mirror of
https://gitee.com/willfree/mlsr.git
synced 2026-06-15 20:04:48 +08:00
295 lines
11 KiB
Go
295 lines
11 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 (
|
|
"fmt"
|
|
"github.com/sirupsen/logrus"
|
|
"minlib/component"
|
|
"minlib/logicface"
|
|
"minlib/packet"
|
|
"minlib/security"
|
|
"mlsr/common"
|
|
"mlsr/lsa"
|
|
"mlsr/lsdb"
|
|
"mlsr/route"
|
|
"time"
|
|
)
|
|
|
|
//INIT_LOGGER(HelloProtocol)
|
|
|
|
const INFO_COMPONENT = "INFO"
|
|
const MLSR_COMPONENT = "MLSR"
|
|
|
|
type HelloProtocol struct {
|
|
m_face *logicface.LogicFace
|
|
m_scheduler *lsdb.MlsrScheduler
|
|
m_keychain *security.KeyChain
|
|
mlsrConfig *common.MlsrConfig
|
|
m_routingTable *route.RoutingTable
|
|
m_lsdb *lsdb.Lsdb
|
|
m_adjacencyList *lsa.AdjLsaAdjacenctList
|
|
}
|
|
|
|
//
|
|
// Init
|
|
// @Description: Hello协议-初始化
|
|
// @receiver hp
|
|
// @param face
|
|
// @param scheduler
|
|
// @param keychain
|
|
// @param mlsrConfig
|
|
// @param routingTable
|
|
// @param mlsdb
|
|
//
|
|
func (hp *HelloProtocol) Init(face *logicface.LogicFace,
|
|
scheduler *lsdb.MlsrScheduler,
|
|
keychain *security.KeyChain, mlsrConfig *common.MlsrConfig,
|
|
routingTable *route.RoutingTable, mlsdb *lsdb.Lsdb) {
|
|
hp.m_face = face
|
|
hp.m_scheduler = scheduler
|
|
hp.m_keychain = keychain
|
|
hp.mlsrConfig = mlsrConfig
|
|
hp.m_routingTable = routingTable
|
|
hp.m_lsdb = mlsdb
|
|
hp.m_adjacencyList = mlsrConfig.GetAdjacencys()
|
|
}
|
|
|
|
// ExpressInterest
|
|
// @Description:发送一个Hello兴趣包
|
|
// @receiver h
|
|
// @param interestNamePrefix
|
|
// @param seconds
|
|
//
|
|
func (hp *HelloProtocol) ExpressInterest(interestName *component.Identifier, seconds uint32) error {
|
|
logrus.Debug("Expressing Interest: ", interestName)
|
|
var interest *packet.Interest
|
|
interest.SetName(interestName) //设置兴趣包的名字
|
|
interest.SetInterestLifeTime(uint64(seconds)) //设置兴趣包的生命周期
|
|
interest.SetMustBeRefresh(true)
|
|
interest.SetCanBePrefix(true)
|
|
hp.m_face.SendInterest(interest)
|
|
err := hp.m_face.SendInterest(interest)
|
|
if err == nil {
|
|
fmt.Println("Express successfully!")
|
|
} else {
|
|
fmt.Println("Express unseccessfully!")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// SendHelloInterest
|
|
// @Description:发送Hello兴趣包给所有的邻居
|
|
// @receiver h
|
|
// @param neighbor
|
|
//
|
|
func (hp *HelloProtocol) SendHelloInterest(neighbor *component.Identifier) {
|
|
//声明一个邻居“对象”,输入其名称前缀获取它的邻接信息,adjacent的类型为*AdjLsaAdjacencyInfo
|
|
adjacent, _ := hp.m_adjacencyList.GetAdjacency(neighbor)
|
|
//判定邻接列表是否为空,若为空则返回
|
|
if hp.m_adjacencyList.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)
|
|
interestName.Append(mlsr1) //在兴趣包名字后面添加“MLSR”
|
|
interestName.Append(info1) //在兴趣包名字后面添加“INFO”
|
|
interestName.Append(hp.mlsrConfig.GetRouterPrefix().ToUri()) //在兴趣包名字后面添加本路由器的前缀
|
|
hp.ExpressInterest(interestName, hp.mlsrConfig.HelloTimeout) //将兴趣包传出去
|
|
logrus.Debug("Sending Hello Interest:", interestName) //日志记录
|
|
}
|
|
//使用调度器循环调度上面事件,调度器里传入两个参数:一个是间隔时间,一个是event,意思是每隔HelloInterval时间就调用一次event事件
|
|
//h.scheduler.scheduler(h.mlsrConfig.HelloInterval,{h.SendHelloInterest(this.neighbor)})
|
|
}
|
|
|
|
// ProcessInterest
|
|
// @Description: 处理来自邻居的Hello兴趣包
|
|
// @receiver h
|
|
// @param name
|
|
// @param interest
|
|
//
|
|
func (hp *HelloProtocol) ProcessInterest(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 hp.m_adjacencyList.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))
|
|
|
|
hp.m_keychain.SignData(data)
|
|
|
|
logrus.Debug("Sending out data for name:v%", interestName)
|
|
|
|
hp.m_face.SendData(data)
|
|
err := hp.m_face.SendData(data)
|
|
if err == nil {
|
|
fmt.Println("Process successfully!")
|
|
} else {
|
|
fmt.Println("Process unsuccessfully!")
|
|
}
|
|
//为了优化响应链路恢复的时间,如果邻居当前是非活动状态,那么Hello协议将立即向邻居发送Hello Interest
|
|
adjacent, _ := hp.m_adjacencyList.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) //在兴趣包名字后面添加本路由器的前缀
|
|
hp.ExpressInterest(interestName, hp.mlsrConfig.HelloTimeout) //将兴趣包传出去
|
|
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
// ProcessInterestTimeOut
|
|
// @Description: 尝试通过hello协议重新联系邻居
|
|
// @receiver h
|
|
// @param interest
|
|
//
|
|
func (hp *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())
|
|
neighbor.BuildIdentifierByString(neighborPrefix.ToString())
|
|
logrus.Debug("Neighbor: v%", neighbor)
|
|
hp.m_adjacencyList.IncrementTimedOutInterestCount(neighbor)
|
|
status, _ := hp.m_adjacencyList.GetStatusOfNeighbor(neighbor) //邻居路由器的状态:未知-1、未激活0、激活1
|
|
infoIntTimedOutCount, _ := hp.m_adjacencyList.GetTimedOutInterestCount(neighbor)
|
|
logrus.Debug("Status:v%", status)
|
|
logrus.Debug("Info Interest Timed out:v%", infoIntTimedOutCount)
|
|
if infoIntTimedOutCount < uint32(hp.mlsrConfig.HelloRetries) {
|
|
var interestName *component.Identifier
|
|
adjacent, _ := hp.m_adjacencyList.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)
|
|
hp.ExpressInterest(interestName, hp.mlsrConfig.HelloTimeout) //将兴趣包传出去
|
|
|
|
} else {
|
|
if status == 1 {
|
|
hp.m_adjacencyList.SetStatusOfNeighbor(neighbor, 0) //邻居被置为未激活
|
|
hp.m_adjacencyList.SetTimedOutInterestCount(neighbor, uint32(hp.mlsrConfig.HelloRetries)) //邻居的超时计数被设置为hello-retries
|
|
logrus.Debug("Neighbor:v% status changed to INACTIVE", neighbor)
|
|
hp.ScheduleAdjLsaBuild() //安排Adjacency LSA的构建
|
|
}
|
|
}
|
|
}
|
|
|
|
// OnContent
|
|
// @Description:对hello数据包进行签名验签和数据校验
|
|
// @receiver h
|
|
// @param interest
|
|
// @param data
|
|
//
|
|
func (hp *HelloProtocol) OnContent(data *packet.Data) {
|
|
logrus.Debug("Received data for name:v%", data.GetName())
|
|
Sig, _ := data.GetSignature(0) //获取指定位置的签名
|
|
if Sig != nil {
|
|
kl := Sig.SigInfo.GetKeyLocator()
|
|
if kl != nil {
|
|
if hp.m_keychain.VerifyData(data) != nil {
|
|
fmt.Println("Data signed with:v%", kl.GetIdentifier())
|
|
logrus.Debug("Data signed with:v%", kl.GetIdentifier())
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
// OnContentValidated
|
|
// @Description: 改变一个邻居的状态
|
|
// @receiver h
|
|
// @param data
|
|
//
|
|
func (hp *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())
|
|
if neighbor != nil {
|
|
neighbor.BuildIdentifierByString(neighborPrefix.ToString())
|
|
|
|
oldStatus, _ := hp.m_adjacencyList.GetStatusOfNeighbor(neighbor) //*identifier
|
|
hp.m_adjacencyList.SetStatusOfNeighbor(neighbor, 1) //邻居路由器的状态:未知-1、未激活0、激活1
|
|
hp.m_adjacencyList.SetTimedOutInterestCount(neighbor, 0)
|
|
newStatus, _ := hp.m_adjacencyList.GetStatusOfNeighbor(neighbor)
|
|
fmt.Println("Neighbor:v%", neighbor)
|
|
fmt.Println("Old status:v%,New status:v%", oldStatus, newStatus)
|
|
logrus.Debug("Neighbor:v%", neighbor)
|
|
logrus.Debug("Old status:v%,New status:v%", oldStatus, newStatus)
|
|
// change in Adjacency list
|
|
if oldStatus != newStatus {
|
|
hp.ScheduleAdjLsaBuild()
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|