//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格式://MLSR/INFO/ 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: //MLSR/INFO/ 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格式://MLSR/INFO/ 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格式://MLSR/INFO/ 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: //NLSR/INFO// 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() } } } }