1
0
mirror of https://gitee.com/willfree/mlsr.git synced 2026-06-09 16:29:34 +08:00
Files
mlsr/hello/HelloProtocol.go
T
2022-05-05 11:59:21 +08:00

275 lines
10 KiB
Go

//package hello
//@Author: Pei Xinyuan
//@Description:
//@Version: 0.1.0
//@Date: 2022/4/27 10:57:00
//@Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
package hello
import (
"github.com/sirupsen/logrus"
"minlib/component"
"minlib/encoding"
"minlib/logicface"
"minlib/packet"
"minlib/security"
"mlsr/common"
"mlsr/lsa"
"mlsr/lsdb"
"time"
)
//INIT_LOGGER(HelloProtocol)
const INFO_COMPONENT = "INFO"
const MLSR_COMPONENT = "MLSR"
type HelloProtocol struct {
encoding.SelfEncodingBase
mlsrConfig *common.MlsrConfig
face *logicface.LogicFace
keychain *security.KeyChain
//RoutingTable
lsdb.Lsdb
scheduler *lsdb.Scheduler
//SignatureInfo *component.SignatureInfo
}
//声明一个邻接列表
var adjacentList *lsa.AdjLsaAdjacenctList
//
// expressInterest
// @Description:发送一个Hello兴趣包
// @receiver h
// @param interestNamePrefix
// @param seconds
//
func (h *HelloProtocol) expressInterest(interestName *component.Identifier, seconds uint32) {
logrus.Debug("Expressing Interest:%v", interestName)
var interest *packet.Interest
interest.SetName(interestName) //设置兴趣包的名字
interest.SetInterestLifeTime(uint64(seconds)) //设置兴趣包的生命周期
interest.SetMustBeRefresh(true)
interest.SetCanBePrefix(true)
h.face.SendInterest(interest)
}
//
// sendHelloInterest
// @Description:发送Hello兴趣包给所有的邻居
// @receiver h
// @param neighbor
//
func (h *HelloProtocol) sendHelloInterest(neighbor *component.Identifier) {
//声明一个邻居“对象”,输入其名称前缀获取它的邻接信息,adjacent的类型为*AdjLsaAdjacencyInfo
adjacent, _ := adjacentList.GetAdjacency(neighbor)
//判定邻接列表是否为空,若为空则返回
if adjacentList.GetAdjList() == nil {
return
}
if adjacent.LogicFaceId() != 0 {
var interestName *component.Identifier
//获取邻居路由器的名称前缀
interestName = adjacent.GetNeighborRouterIdentifier()
//假设本机是A,邻居是B
//interestName格式:/<B路由器前缀>/MLSR/INFO/<A路由器的前缀>
mlsr, _ := component.CreateIdentifierByString(MLSR_COMPONENT) //mlsr的类型是*component.Identifier
info, _ := component.CreateIdentifierByString(INFO_COMPONENT)
mlsr1, _ := mlsr.Get(0) //mlsr1的类型是*component.IdentifierComponent
info1, _ := info.Get(0)
thisRouterPrefix, _ := h.ThisRouterPrefix.Get(0)
interestName.Append(mlsr1) //在兴趣包名字后面添加“MLSR”
interestName.Append(info1) //在兴趣包名字后面添加“INFO”
interestName.Append(thisRouterPrefix) //在兴趣包名字后面添加本路由器的前缀
h.expressInterest(interestName, h.mlsrConfig.HelloTimeout) //将兴趣包传出去
logrus.Debug("Sending Hello Interest:%v", interestName) //日志记录
}
//使用调度器循环调度上面事件,调度器里传入两个参数:一个是间隔时间,一个是event,意思是每隔HelloInterval时间就调用一次event事件
//h.scheduler.scheduler(h.mlsrConfig.HelloInterval,{h.sendHelloInterest(this.neighbor)})
}
//
// processInterest
// @Description: 处理来自邻居的Hello兴趣包
// @receiver h
// @param name
// @param interest
//
func (h *HelloProtocol) processInterest(name *component.Identifier, interest *packet.Interest) {
var interestName *component.Identifier
//假设本机是A,邻居是B
//收到的interest name: /<A路由器前缀>/MLSR/INFO/<B路由器前缀>
interestName = interest.GetName()
logrus.Debug("Interest Recieved for name:v%", interestName)
//判断收到的包是否符合格式
is_info, _ := interestName.Get(-2)
if is_info.ToUri() != INFO_COMPONENT {
logrus.Debug("INFO_COMPONENT not found or interestName: v% "+
"does not match expression", interestName)
return
}
var neighbor *component.Identifier //B路由器名称前缀
neighborPrefix, _ := interestName.Get(-1) //neighborPrefix是IdentifierComponent,与neighbor不同
neighbor.WireDecode(neighborPrefix.Raw())
logrus.Debug("Neighbor: v%", neighbor)
if adjacentList.IsNeighbor(neighbor) {
var data *packet.Data
dataName := interest.GetName()
dataName.AppendVersionNumber(1)
data.SetName(dataName)
data.SetFreshnessPeriod(uint64(time.Second * 10)) //10 sec
data.Payload.SetValue([]byte(INFO_COMPONENT))
h.keychain.SignData(data)
logrus.Debug("Sending out data for name:v%", interestName)
h.face.SendData(data)
//为了优化响应链路恢复的时间,如果邻居当前是非活动状态,那么Hello协议将立即向邻居发送Hello Interest
adjacent, _ := adjacentList.GetAdjacency(neighbor)
if adjacent.Status == 0 { //邻居路由器的状态:未知-1、未激活0、激活1
if adjacent.LogicFaceId() != 0 { //邻居有face我们才能做
var interestName *component.Identifier
//获取邻居路由器的名称前缀
interestName = adjacent.GetNeighborRouterIdentifier()
//假设本机是A,邻居是B
//interestName格式:/<B路由器前缀>/MLSR/INFO/<A路由器的前缀>
mlsr, _ := component.CreateIdentifierByString(MLSR_COMPONENT) //mlsr的类型是*component.Identifier
info, _ := component.CreateIdentifierByString(INFO_COMPONENT)
mlsr1, _ := mlsr.Get(0) //mlsr1的类型是*component.IdentifierComponent
info1, _ := info.Get(0)
thisRouterPrefix, _ := h.ThisRouterPrefix.Get(0)
interestName.Append(mlsr1) //在兴趣包名字后面添加“MLSR”
interestName.Append(info1) //在兴趣包名字后面添加“INFO”
interestName.Append(thisRouterPrefix) //在兴趣包名字后面添加本路由器的前缀
h.expressInterest(interestName, h.mlsrConfig.HelloTimeout) //将兴趣包传出去
}
}
}
}
//
// processInterestTimeOut
// @Description: 尝试通过hello协议重新联系邻居
// @receiver h
// @param interest
//
func (h *HelloProtocol) processInterestTimeOut(interest *packet.Interest) {
var interestName *component.Identifier
interestName = interest.GetName()
logrus.Debug("Interest timed out for Name:v%", interestName)
//判断包格式
is_info, _ := interestName.Get(-2)
if is_info.ToUri() != INFO_COMPONENT {
logrus.Debug("INFO_COMPONENT not found or interestName: v% "+
"does not match expression", interestName)
return
}
var neighbor *component.Identifier //B路由器名称前缀
neighborPrefix, _ := interestName.Get(-1) //neighborPrefix是IdentifierComponent,与neighbor不同
neighbor.WireDecode(neighborPrefix.Raw())
logrus.Debug("Neighbor: v%", neighbor)
adjacentList.IncrementTimedOutInterestCount(neighbor)
status, _ := adjacentList.GetStatusOfNeighbor(neighbor) //邻居路由器的状态:未知-1、未激活0、激活1
infoIntTimedOutCount, _ := adjacentList.GetTimedOutInterestCount(neighbor)
logrus.Debug("Status:v%", status)
logrus.Debug("Info Interest Timed out:v%", infoIntTimedOutCount)
if infoIntTimedOutCount < uint32(h.mlsrConfig.HelloRetries) {
var interestName *component.Identifier
adjacent, _ := adjacentList.GetAdjacency(neighbor)
//获取邻居路由器的名称前缀
interestName = adjacent.GetNeighborRouterIdentifier()
//假设本机是A,邻居是B
//interestName格式:/<B路由器前缀>/MLSR/INFO/<A路由器的前缀>
mlsr, _ := component.CreateIdentifierByString(MLSR_COMPONENT) //mlsr的类型是*component.Identifier
info, _ := component.CreateIdentifierByString(INFO_COMPONENT)
mlsr1, _ := mlsr.Get(0) //mlsr1的类型是*component.IdentifierComponent
info1, _ := info.Get(0)
thisRouterPrefix, _ := h.ThisRouterPrefix.Get(0)
interestName.Append(mlsr1) //在兴趣包名字后面添加“MLSR”
interestName.Append(info1) //在兴趣包名字后面添加“INFO”
interestName.Append(thisRouterPrefix) //在兴趣包名字后面添加本路由器的前缀
logrus.Debug("Resending interest:v%", interestName)
h.expressInterest(interestName, h.mlsrConfig.HelloTimeout) //将兴趣包传出去
} else {
if status == 1 {
adjacentList.SetStatusOfNeighbor(neighbor, 0) //邻居被置为未激活
adjacentList.SetTimedOutInterestCount(neighbor, uint32(h.mlsrConfig.HelloRetries)) //邻居的超时计数被设置为hello-retries
logrus.Debug("Neighbor:v% status changed to INACTIVE", neighbor)
h.ScheduleAdjLsaBuild() //安排Adjacency LSA的构建
}
}
}
//
// onContent
// @Description:对hello数据包进行签名验签和数据校验
// @receiver h
// @param interest
// @param data
//
func (h *HelloProtocol) onContent(interest *packet.Interest, data *packet.Data) {
logrus.Debug("Received data for name:v%", data.GetName())
Sig, _ := data.GetSignature(0) //获取指定位置的签名
kl := Sig.SigInfo.GetKeyLocator()
//签名的格式如何验证????????????extensions选的是TlvMlsrLsaNamePrefix吗?
if kl != nil {
//if encoding.ExpectType(kl.Raw().GetType(), extensions.TlvMlsrLsaNamePrefix) != nil {
if h.keychain.VerifyData(data) != nil {
logrus.Debug("Data signed with:v%", kl.GetIdentifier())
}
//}
}
//数据如何校验?????????????
}
//
// onContentValidated
// @Description: 改变一个邻居的状态
// @receiver h
// @param data
//
func (h *HelloProtocol) onContentValidated(data *packet.Data) {
// data name: /<neighbor>/NLSR/INFO/<router>/<version>
dataName := data.GetName()
logrus.Debug("Data validation successful for name:v%", dataName)
info, _ := dataName.Get(-3)
if info.ToUri() == INFO_COMPONENT {
neighborPrefix, _ := dataName.Get(0) //*identifierComponent
var neighbor *component.Identifier
//neighbor.WireDecode(neighborPrefix.Raw())
neighbor.BuildIdentifierByString(neighborPrefix.ToString())
oldStatus, _ := adjacentList.GetStatusOfNeighbor(neighbor) //*identifier
adjacentList.SetStatusOfNeighbor(neighbor, 1) //邻居路由器的状态:未知-1、未激活0、激活1
adjacentList.SetTimedOutInterestCount(neighbor, 0)
newStatus, _ := adjacentList.GetStatusOfNeighbor(neighbor)
logrus.Debug("Neighbor:v%", neighbor)
logrus.Debug("Old status:v%,New status:V%", oldStatus, newStatus)
// change in Adjacency list
if oldStatus != newStatus {
h.ScheduleAdjLsaBuild()
}
}
}
//
// onContentValidationFailed
// @Description:
// @param data
// @return {}
//
func onContentValidationFailed(data *packet.Data) {}