1
0
mirror of https://gitee.com/willfree/mlsr.git synced 2026-06-03 15:56:13 +08:00

修改lsdb/lsdb.go,避免合并冲突

This commit is contained in:
free will
2022-07-08 19:36:37 +08:00
16 changed files with 1691 additions and 74 deletions
+5 -1
View File
@@ -30,4 +30,8 @@ require (
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 // indirect golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 // indirect
) )
replace minlib v0.0.0 => ../minlib <<<<<<< HEAD
replace minlib v0.0.0 => ../minlib
=======
replace minlib v0.0.0 => ../minlib
>>>>>>> master
+80
View File
@@ -0,0 +1,80 @@
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/d4l3k/messagediff v1.2.1 h1:ZcAIMYsUg0EAp9X+tt8/enBE/Q8Yd5kzPynLyKptt9U=
github.com/d4l3k/messagediff v1.2.1/go.mod h1:Oozbb1TVXFac9FtSIxHBMnBCq2qeH/2KkEQxENCrlLo=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-co-op/gocron v1.13.0 h1:BjkuNImPy5NuIPEifhWItFG7pYyr27cyjS6BN9w/D4c=
github.com/go-co-op/gocron v1.13.0/go.mod h1:GD5EIEly1YNW+LovFVx5dzbYVcIc8544K99D8UVRpGo=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/liyue201/gostl v1.0.1 h1:VQdvogZ90WpCb5WdG9UxS6r5ulnYEp8VfEMEZXVtpIs=
github.com/liyue201/gostl v1.0.1/go.mod h1:rgK+T1a0sQ1+CsAonfuD1J8C4iuGfOU9VAt9mmR/m10=
github.com/mutecomm/go-sqlcipher/v4 v4.4.2 h1:eM10bFtI4UvibIsKr10/QT7Yfz+NADfjZYh0GKrXUNc=
github.com/mutecomm/go-sqlcipher/v4 v4.4.2/go.mod h1:mF2UmIpBnzFeBdu/ypTDb/LdbS0nk0dfSN1WUsWTjMA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs=
github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg=
github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/tidwall/assert v0.1.0 h1:aWcKyRBUAdLoVebxo95N7+YZVTFF/ASTr7BN4sLP6XI=
github.com/tidwall/assert v0.1.0/go.mod h1:QLYtGyeqse53vuELQheYl9dngGCJQ+mTtlxcktb+Kj8=
github.com/tidwall/btree v1.1.0/go.mod h1:TzIRzen6yHbibdSfK6t8QimqbUnoxUSrZfeW7Uob0q4=
github.com/tidwall/btree v1.2.1 h1:57++q7DAOwfD6R0w0d3wh5yTwwett4gBYJGZD1rmyHQ=
github.com/tidwall/btree v1.2.1/go.mod h1:LGm8L/DZjPLmeWGjv5kFrY8dL4uVhMmzmmLYmsObdKE=
github.com/tidwall/buntdb v1.2.9 h1:XVz684P7X6HCTrdr385yDZWB1zt/n20ZNG3M1iGyFm4=
github.com/tidwall/buntdb v1.2.9/go.mod h1:IwyGSvvDg6hnKSIhtdZ0AqhCZGH8ukdtCAzaP8fI1X4=
github.com/tidwall/gjson v1.12.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/gjson v1.14.0 h1:6aeJ0bzojgWLa82gDQHcx3S0Lr/O51I9bJ5nv6JFx5w=
github.com/tidwall/gjson v1.14.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/grect v0.1.4 h1:dA3oIgNgWdSspFzn1kS4S/RDpZFLrIxAZOdJKjYapOg=
github.com/tidwall/grect v0.1.4/go.mod h1:9FBsaYRaR0Tcy4UwefBX/UDcDcDy9V5jUcxHzv2jd5Q=
github.com/tidwall/lotsa v1.0.2 h1:dNVBH5MErdaQ/xd9s769R31/n2dXavsQ0Yf4TMEHHw8=
github.com/tidwall/lotsa v1.0.2/go.mod h1:X6NiU+4yHA3fE3Puvpnn1XMDrFZrE9JO2/w+UMuqgR8=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tidwall/rtred v0.1.2 h1:exmoQtOLvDoO8ud++6LwVsAMTu0KPzLTUrMln8u1yu8=
github.com/tidwall/rtred v0.1.2/go.mod h1:hd69WNXQ5RP9vHd7dqekAz+RIdtfBogmglkZSRxCHFQ=
github.com/tidwall/tinyqueue v0.1.1 h1:SpNEvEggbpyN5DIReaJ2/1ndroY8iyEGxPYxoSaymYE=
github.com/tidwall/tinyqueue v0.1.1/go.mod h1:O/QNHwrnjqr6IHItYrzoHAKYhBkLI67Q096fQP5zMYw=
github.com/tylertreat/BoomFilters v0.0.0-20210315201527-1a82519a3e43 h1:QEePdg0ty2r0t1+qwfZmQ4OOl/MB2UXIeJSpIZv56lg=
github.com/tylertreat/BoomFilters v0.0.0-20210315201527-1a82519a3e43/go.mod h1:OYRfF6eb5wY9VRFkXJH8FFBi3plw2v+giaIu7P054pM=
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
github.com/zeebo/xxh3 v1.0.1 h1:FMSRIbkrLikb/0hZxmltpg84VkqDAT5M8ufXynuhXsI=
github.com/zeebo/xxh3 v1.0.1/go.mod h1:8VHV24/3AZLn3b6Mlp/KuC33LWH687Wq6EnziEB+rsA=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
+15
View File
@@ -165,6 +165,21 @@ func (a *AdjLsa) GetAdjList() []*AdjLsaAdjacencyInfo {
return a.AdjLsaAdjacenctList.GetAdjList() return a.AdjLsaAdjacenctList.GetAdjList()
} }
//
// GetAdjRouterPrefixList
// @Description: 获取邻接信息中的邻接路由器标识符
// @receiver a
// @return []*component.Identifier
//
func (a *AdjLsa) GetAdjRouterPrefixList() []*component.Identifier {
adjRouterPrefixs := []*component.Identifier{}
adjList := a.AdjLsaAdjacenctList.GetAdjList()
for i := 0; i < len(adjList); i++ {
adjRouterPrefixs = append(adjRouterPrefixs, adjList[i].lsaNeighborRouterIdentifier)
}
return adjRouterPrefixs
}
// //
// AddAdjacencyInfo // AddAdjacencyInfo
// @Description: 增加一条邻接信息 // @Description: 增加一条邻接信息
+439 -50
View File
@@ -10,22 +10,29 @@ package lsdb
import ( import (
"bytes" "bytes"
common2 "minlib/common"
"minlib/component" "minlib/component"
"minlib/logicface"
"minlib/packet" "minlib/packet"
"mlsr/common" "mlsr/common"
"mlsr/communication" "mlsr/communication"
"mlsr/lsa" "mlsr/lsa"
"mlsr/lsdb/LsaContainer" "mlsr/lsdb/LsaContainer"
"mlsr/utils"
"time" "time"
) )
type LsdbUpdate int
// Lsdb更新状态 // Lsdb更新状态
const ( const (
INSTALLED = 0 // 安装 INSTALLED LsdbUpdate = 0 // 安装
UPDATED = 1 // 更新 UPDATED LsdbUpdate = 1 // 更新
REMOVED = -1 // 移除 REMOVED LsdbUpdate = -1 // 移除
) )
const GRACE_PERIOD = 10 * time.Second // 超期宽限期。LSA比设定时间晚几秒钟被删除,以避免信息过早失效。
type Lsdb struct { type Lsdb struct {
// 配置参数 // 配置参数
mlsrConfig *common.MlsrConfig mlsrConfig *common.MlsrConfig
@@ -34,36 +41,97 @@ type Lsdb struct {
sync *communication.SyncLogicHandler sync *communication.SyncLogicHandler
// LSA容器 // LSA容器
lsaContainer *LsaContainer.LsaContainer LsaContainer.LsaContainer
lsaRefreshTime *time.Duration // lsa刷新时间 lsaRefreshTime time.Duration // lsa刷新时间
adjLsaBuildInterval *time.Duration // 邻接LSA构建间隔 adjLsaBuildInterval time.Duration // 邻接LSA构建间隔
thisRouterPrefix *component.Identifier // 当前路由器的标识 thisRouterPrefix *component.Identifier // 当前路由器的标识
// 任务调度器 // 任务调度器
scheduler *Scheduler scheduler *MlsrScheduler
// LogicFace接口
face *logicface.LogicFace
// 将LSA的名称从sync映射到其已知的最高序列号; // 将LSA的名称从sync映射到其已知的最高序列号;
// 用于阻止MLSR尝试获取过时的LSA // 用于阻止MLSR尝试获取过时的LSA
highestSeqNo map[*component.Identifier] uint64 highestSeqNo map[*component.Identifier]uint64
// 不同类型lsa的序列号管理器 // 不同类型lsa的序列号管理器
sequencingManager *SequencingManager sequencingManager *SequencingManager
isBuildAdjLsaScheduled bool // 是否安排构建邻接LSA isBuildAdjLsaScheduled bool // 是否安排构建邻接LSA
adjBuildCount uint64 // 邻接LSA的构建的统计数目 adjBuildCount uint64 // 邻接LSA的构建的统计数目
// 信号:用以通知“Lsdb被修改”这个事件的发生
OnLsdbModified *utils.Signal
}
func (l *Lsdb) Init(mc *common.MlsrConfig, ms *MlsrScheduler,
_face *logicface.LogicFace) {
// 信号初始化
l.OnLsdbModified = utils.NewSignal()
// 配置项
l.mlsrConfig = mc
// 调度器
l.scheduler = ms
// 逻辑face
l.face = _face
// 序列号管理器
l.sequencingManager = GetInstance()
// 存储器
err := l.LsaContainer.Init()
if err != nil {
common2.LogFatal("lsdb.LsaContainer init error, ", err.Error())
}
// todo 构造sync
// lsa刷新时间
l.lsaRefreshTime = l.mlsrConfig.GetLsaRefreshTime()
// 邻接lsa构建间隔
l.adjLsaBuildInterval = l.mlsrConfig.GetAdjLsaBuildInterval()
// 本机路由前缀
l.thisRouterPrefix = l.mlsrConfig.GetRouterPrefix()
// 是否已经安排邻接LSA的构建
l.isBuildAdjLsaScheduled = false
// 邻接LSA构建次数统计
l.adjBuildCount = 0
// 在LSDB初始化之前,对配置文件中的本机路由器进行拉式前缀注册(即监听该前缀)
// todo: 为了在Windows上单独测试,暂时注释掉face注册前缀这一步骤
//lsaPrefix := l.mlsrConfig.GetLsaPrefix()
//err := l.face.RegisterPullIdentifier(lsaPrefix, 2000)
//if err != nil {
// common2.LogFatal("Lsdb Init error, because of face register, ", err.Error())
//}
// 构建并安装自己的名称LSA
l.BuildAndInstallOwnNameLsa()
} }
// //
// DoesLsaExist // DoesLsaExist
// @Description: 返回LSDB是否存在某LSA的查询结果 // @Description: 返回LSDB是否存在某LSA的查询结果
// @receiver l // @receiver l
// @param routerIdentifier // @param routerIdentifier
// @param lsaType // @param lsaType
// @return bool // @return bool
// //
func (l *Lsdb) DoesLsaExist(routerIdentifier *component.Identifier,lsaType int) bool { func (l *Lsdb) DoesLsaNameExist(routerIdentifier *component.Identifier, lsaType lsa.LsaType) bool {
panic("implement me") return l.ExistsRouterNameAndType(routerIdentifier, lsaType)
}
//
// DoesLsaExist
// @Description: 返回LSDB是否存在某个LSA的查询结果
// @receiver l
// @param lsa
// @return bool
//
func (l *Lsdb) DoesLsaExist(lsa lsa.ILsa) bool {
return l.Exists(lsa)
} }
// //
@@ -72,6 +140,20 @@ func (l *Lsdb) DoesLsaExist(routerIdentifier *component.Identifier,lsaType int)
// @receiver l // @receiver l
// //
func (l *Lsdb) BuildAndInstallOwnNameLsa() { func (l *Lsdb) BuildAndInstallOwnNameLsa() {
// 根据配置文件,构造本机的名称LSA
nlsa := new(lsa.NameLsa)
nlsa.SetOriginRouter(l.thisRouterPrefix) // 源路由
nlsa.SetSeqNo(l.sequencingManager.GetNameLsaSeq() + 1) // 序列号
nlsa.SetLsaExpirationTime(l.getLsaExpirationTimePoint()) // 超期时间
nlsa.NameLsaNamePrefixList.InsertNamePrefixList(l.mlsrConfig.GetNamePrefixList()) // 名称前缀列表
// 刷新序列号管理器中的名称LSA序列号
l.sequencingManager.IncreaseNameLsaSeq()
// todo: 使用sync通知路由更新
// m_sync.publishRoutingUpdate(Lsa::Type::NAME, m_sequencingManager.getNameLsaSeq());
// 安装lsa到LSDB
l.InstallLsa(nlsa)
} }
// //
@@ -80,7 +162,7 @@ func (l *Lsdb) BuildAndInstallOwnNameLsa() {
// @receiver l // @receiver l
// //
func (l *Lsdb) BuildAndInstallOwnCoordinateLsa() { func (l *Lsdb) BuildAndInstallOwnCoordinateLsa() {
// todo // todo:坐标计算预留接口
} }
// //
@@ -88,12 +170,29 @@ func (l *Lsdb) BuildAndInstallOwnCoordinateLsa() {
// @Description: 安排LSA的构建 // @Description: 安排LSA的构建
// @receiver l // @receiver l
// //
func (l *Lsdb) ScheduleAdjLsaBuild() { func (l *Lsdb) ScheduleAdjLsaBuild() {
// 计数
l.adjBuildCount++
// 日志记录
if l.isBuildAdjLsaScheduled {
common2.LogInfo("Rescheduling Adjacency LSA build in ", l.adjLsaBuildInterval)
} else {
common2.LogInfo("Scheduling Adjacency LSA build in ", l.adjLsaBuildInterval)
l.isBuildAdjLsaScheduled = true
}
// 安排构造邻接LSA
job, err := l.scheduler.ScheduleTaskAfterDuration(l.adjLsaBuildInterval, 1).Do(l.BuildAdjLsa)
job.LimitRunsTo(1)
l.scheduler.StartAsync()
if err != nil {
common2.LogError("Scheduling Adjacency LSA build error, ", err.Error())
}
} }
// //
// ProcessInterest // ProcessInterest
// @Description: 处理兴趣包。类似NDN的拉式传输 // @Description:收到一个兴趣包,根据兴趣包名称,查找LSA并返回
// 处理兴趣包。类似NDN的拉式传输。
// 在NLSR的设计中,由于对兴趣包进行了进一步的分段,因此有以下两种兴趣包: // 在NLSR的设计中,由于对兴趣包进行了进一步的分段,因此有以下两种兴趣包:
//* 1) 需要从segment fetcher中查找的兴趣包: //* 1) 需要从segment fetcher中查找的兴趣包:
//* /localhop/<network>/nlsr/LSA/<site>/<router>/<lsaType>/<seqNo> //* /localhop/<network>/nlsr/LSA/<site>/<router>/<lsaType>/<seqNo>
@@ -102,10 +201,14 @@ func (l *Lsdb) ScheduleAdjLsaBuild() {
// @receiver l // @receiver l
// @param interest // @param interest
// //
func (l *Lsdb) ProcessInterest(interest *packet.Interest) { func (l *Lsdb) ProcessInterest(interest *packet.Interest) {
} }
func (l *Lsdb) ProcessGPPkt(pkt *packet.GPPkt) { func (l *Lsdb) processInterestForLsa(interest *packet.Interest,
originRouterIdentifier *component.Identifier, lsaType lsa.LsaType, seqNo uint64) {
}
func (l *Lsdb) ProcessGPPkt(pkt *packet.GPPkt) {
} }
// //
@@ -138,12 +241,15 @@ func (l *Lsdb) GetSync() *communication.SyncLogicHandler {
// //
func (l *Lsdb) FindLsa(routerIdentifier *component.Identifier, func (l *Lsdb) FindLsa(routerIdentifier *component.Identifier,
lsaType lsa.LsaType) lsa.ILsa { lsaType lsa.LsaType) lsa.ILsa {
// todo lsaGet, err := l.GetLSAByNameAndType(routerIdentifier, lsaType)
return &lsa.NameLsa{} if err != nil {
lsaGet = nil
}
return lsaGet
} }
// //
// IsLsaNew // isLsaNew
// @Description: 返回来自某个路由器的seq是否表示新的LSA。 // @Description: 返回来自某个路由器的seq是否表示新的LSA。
// @receiver l // @receiver l
// @param routerIdentifier // @param routerIdentifier
@@ -151,23 +257,201 @@ func (l *Lsdb) FindLsa(routerIdentifier *component.Identifier,
// @param seqNo // @param seqNo
// @return bool // @return bool
// //
func (l *Lsdb) IsLsaNew(routerIdentifier *component.Identifier, func (l *Lsdb) isLsaNew(routerIdentifier *component.Identifier,
lsaType lsa.LsaType,seqNo uint64) bool { lsaType lsa.LsaType, seqNo uint64) bool {
lsa := l.FindLsa(routerIdentifier,lsaType) iLsa := l.FindLsa(routerIdentifier, lsaType)
if lsa.GetSeqNo() >= seqNo{ // 没找到,说明是最新的
return false if iLsa == nil {
return true
} }
return true // 找到了,且LSDB中的该lsa序列号小于要查的lsa,说明是最新的
if iLsa.GetSeqNo() < seqNo {
return true
}
return false
} }
func (l *Lsdb) InstallLsa(lsa lsa.ILsa) { //
// IsLsaNew
// @Description: 返回来自某个路由器的seq是否表示新的LSA。
// @receiver l
// @param fLsa
// @return bool
//
func (l *Lsdb) IsLsaNew(fLsa lsa.ILsa) bool {
return l.isLsaNew(fLsa.GetOriginRouter(), fLsa.GetType(), fLsa.GetSeqNo())
} }
func (l* Lsdb) RemoveLsa(routerIdentifier *component.Identifier, //
// InstallLsa
// @Description: 将LSA安装到lsdb中
// @receiver l
// @param lsa
//
func (l *Lsdb) InstallLsa(lsa lsa.ILsa) {
timeToExpire := l.lsaRefreshTime
// 判断不是本机LSA时,调整超期时间
if lsa.GetOriginRouter().ToUri() != l.thisRouterPrefix.ToUri() {
// 如果该其他路由器发来的LSA还没超时,则将超时时间间隔设置为该LSA剩余存活时间
if l.uintToTime(lsa.GetExpirationTime()).After(time.Now()) {
timeToExpire = l.uintToTime(lsa.GetExpirationTime()).Sub(time.Now())
}
}
// 查看数据库中是否已有该LSA源路由器所发出的LSA
lsaInDb := l.FindLsa(lsa.GetOriginRouter(), lsa.GetType())
if lsaInDb == nil {
// 如果没有:
common2.LogDebug("Adding Lsa ", lsa.ToString())
// 1. 就插入该LSA
err := l.Emplace(lsa)
if err != nil {
common2.LogError("Add Lsa error", lsa.ToString())
return
}
// 2. 触发LSDB安装LSA的动作信号 OnLsdbModified(lsa, LsdbUpdate::INSTALLED, {}, {});
if !l.OnLsdbModified.IsEmpty() {
l.OnLsdbModified.Emit(lsa, INSTALLED)
}
// 3. 设置LSA超期时间事件
l.ScheduleLsaExpiration(lsa, timeToExpire)
} else if lsaInDb.GetSeqNo() < lsa.GetSeqNo() {
// 如果查到了,而且传入的这个LSA比数据库中的更新,我们将更新数据库
common2.LogDebug("Updating Lsa ", lsaInDb.ToString())
// 1. 就插入该LSA
err := l.Emplace(lsa)
if err != nil {
common2.LogError("Add Lsa error", lsa.ToString())
return
}
// 2. 触发LSDB更新LSA的动作信号 OnLsdbModified(lsa, LsdbUpdate::UPDATED, namesToAdd, namesToRemove);
updated, namesToAdd, namesToRemove := l.compareTwoLsa(lsaInDb, lsa)
if updated && !l.OnLsdbModified.IsEmpty() {
common2.LogDebug("l.OnLsdbModified.Emit(lsa, UPDATED, namesToAdd, namesToRemove) ")
l.OnLsdbModified.Emit(lsa, UPDATED, namesToAdd, namesToRemove)
}
// 3. 设置LSA超期时间事件
l.ScheduleLsaExpiration(lsa, timeToExpire)
common2.LogDebug("Updated Lsa ", lsa.ToString())
}
}
//
// compareTwoLsa
// @Description: 对比两个lsa,将其不同的部分取出来
// @receiver l
// @param lsaA
// @param lsaB
// @return bool 如果有不同,就返回true
// @return []*component.Identifier
// @return []component.Identifier
//
func (l *Lsdb) compareTwoLsa(lsaA lsa.ILsa, lsaB lsa.ILsa) (bool, []*component.Identifier, []*component.Identifier) {
namesToAdd := []*component.Identifier{}
namesToRemove := []*component.Identifier{}
// 前置判断,确定两个都是名称Lsa时,执行相应操作
if lsaA.GetType() == lsa.LsaNAMEType && lsaB.GetType() == lsa.LsaNAMEType {
// 转换为名称Lsa
lsa1 := lsaA.(*lsa.NameLsa)
lsa2 := lsaB.(*lsa.NameLsa)
lsaPrefixs1 := lsa1.GetNamePrefixes()
lsaPrefixs2 := lsa2.GetNamePrefixes()
// lsa2有而lsa1没的,则为要添加的
for i := 0; i < len(lsaPrefixs2); i++ {
if !existsIdentifier(lsaPrefixs2[i], lsaPrefixs1) {
namesToAdd = append(namesToAdd, lsaPrefixs2[i])
}
}
// lsa1有而lsa2没的,则为要删除的
for i := 0; i < len(lsaPrefixs1); i++ {
if !existsIdentifier(lsaPrefixs1[i], lsaPrefixs2) {
namesToRemove = append(namesToRemove, lsaPrefixs1[i])
}
}
// 有变化,则true;一毛一样,则false
if len(namesToAdd) > 0 || len(namesToRemove) > 0 {
return true, namesToAdd, namesToRemove
} else {
return false, namesToAdd, namesToRemove
}
} else if lsaA.GetType() == lsa.LsaADJACENCYType && lsaB.GetType() == lsa.LsaADJACENCYType {
// 两个都是邻接的情况
// 转换为邻接Lsa
lsa1 := lsaA.(*lsa.AdjLsa)
lsa2 := lsaB.(*lsa.AdjLsa)
lsaPrefixs1 := lsa1.GetAdjRouterPrefixList()
lsaPrefixs2 := lsa2.GetAdjRouterPrefixList()
// lsa2有而lsa1没的,则为要添加的
for i := 0; i < len(lsaPrefixs2); i++ {
if !existsIdentifier(lsaPrefixs2[i], lsaPrefixs1) {
namesToAdd = append(namesToAdd, lsaPrefixs2[i])
}
}
// lsa1有而lsa2没的,则为要删除的
for i := 0; i < len(lsaPrefixs1); i++ {
if !existsIdentifier(lsaPrefixs1[i], lsaPrefixs2) {
namesToRemove = append(namesToRemove, lsaPrefixs1[i])
}
}
// 有变化,则true;一毛一样,则false
if len(namesToAdd) > 0 || len(namesToRemove) > 0 {
return true, namesToAdd, namesToRemove
} else {
return false, namesToAdd, namesToRemove
}
} else {
return false, namesToAdd, namesToRemove
}
}
//
// existsIdentifier
// @Description: 判断是否有某个identifier
// @param target
// @param identifiers
// @return bool
//
func existsIdentifier(target *component.Identifier, identifiers []*component.Identifier) bool {
for i := 0; i < len(identifiers); i++ {
if identifiers[i].ToUri() == target.ToUri() {
return true
}
}
return false
}
//
// RemoveLsa
// @Description: 从LSDB中删除LSA
// @receiver l
// @param lsa
//
func (l *Lsdb) RemoveLsa(lsa lsa.ILsa) {
err := l.LsaContainer.EraseLsa(lsa)
if err != nil {
common2.LogError("")
return
}
l.OnLsdbModified.Emit(lsa, REMOVED)
common2.LogDebug("Removed LSA: ", lsa.ToString())
}
//
// RemoveLsaByNameAndType
// @Description: 删除lsa
// @receiver l
// @param routerIdentifier
// @param lsaType
//
func (l *Lsdb) RemoveLsaByNameAndType(routerIdentifier *component.Identifier,
lsaType lsa.LsaType) { lsaType lsa.LsaType) {
} err := l.LsaContainer.EraseLsaByNameAndType(routerIdentifier, lsaType)
if err != nil {
func (l* Lsdb) RemoveLsaByContainerIndex(index int) { common2.LogError("")
return
}
common2.LogDebug("Removed LSA: ", routerIdentifier.ToUri())
} }
// //
@@ -176,7 +460,43 @@ func (l* Lsdb) RemoveLsaByContainerIndex(index int) {
// 只有当路由器的所有邻居状态是已知的时,才可以构建它的邻接LSA。 // 只有当路由器的所有邻居状态是已知的时,才可以构建它的邻接LSA。
// @receiver l // @receiver l
// //
func (l *Lsdb) BuildAdjLsa() { func (l *Lsdb) BuildAdjLsa() {
common2.LogDebug("buildAdjLsa called")
// 构建邻接lsa的任务启动,那么安排构建就变为false
l.isBuildAdjLsaScheduled = false
// 根据配置文件中邻接表的状态,执行不同的动作
if l.mlsrConfig.GetAdjacencys().IsAdjLsaBuildable(uint32(l.mlsrConfig.GetHelloRetries())) {
// 只有在有计划的情况下才执行adjLsa构建
adjBuildCountCache := l.adjBuildCount
if adjBuildCountCache > 0 {
// 只有有安排时,构建邻接lsa
if l.mlsrConfig.GetAdjacencys().GetNumOfActiveNeighbor() > 0 {
// 有激活状态的邻居,则安装邻接LSA
common2.LogDebug("Building and installing own Adj LSA")
l.BuildAndInstallOwnAdjLsa()
} else {
// 我们没有活跃的邻居,这意味着没有人可以穿过我们。
// 因此,请删除LSDB中的条目。这会阻止此路由器刷新LSA,最终导致其他路由器也将其删除。
common2.LogDebug("Removing own Adj LSA; no ACTIVE neighbors")
l.RemoveLsaByNameAndType(l.thisRouterPrefix, lsa.LsaADJACENCYType)
}
// 如果在构建adj LSA的过程中,FIB必须等待兴趣响应,
// 那么计划的adj LSA构建的数量可能会发生变化,因此我们不应该只将其设置为0。
l.adjBuildCount = l.adjBuildCount - adjBuildCountCache
}
} else {
// 我们仍在等待了解某个邻居的邻接状态,因此请安排稍后的构建(当有望完成时)
l.isBuildAdjLsaScheduled = true
scheTime := l.mlsrConfig.GetHelloTimeout() * time.Duration(l.mlsrConfig.GetHelloRetries())
job, err := l.scheduler.ScheduleTaskAfterDuration(scheTime, 1).Do(l.BuildAdjLsa)
job.LimitRunsTo(1)
l.scheduler.StartAsync()
if err != nil {
common2.LogError("Scheduling BuildAdjLsa error, ", err.Error())
}
}
} }
// //
@@ -184,7 +504,21 @@ func (l *Lsdb) BuildAdjLsa() {
// @Description: 为当前路由器构建并安装一个邻接LSA // @Description: 为当前路由器构建并安装一个邻接LSA
// @receiver l // @receiver l
// //
func (l *Lsdb) BuildAndInstallOwnAdjLsa() { func (l *Lsdb) BuildAndInstallOwnAdjLsa() {
// 根据配置文件,构造本机的名称LSA
adjLsa := new(lsa.AdjLsa)
adjLsa.SetOriginRouter(l.thisRouterPrefix)
adjLsa.SetSeqNo(l.sequencingManager.GetAdjLsaSeq() + 1) // 序列号
adjLsa.SetLsaExpirationTime(l.getLsaExpirationTimePoint()) // 超期时间
adjLsa.AdjLsaAdjacenctList.InsertAdjacenctList(l.mlsrConfig.GetAdjacencyList()) // 名称前缀列表
// 刷新序列号管理器中的名称LSA序列号
l.sequencingManager.IncreaseAdjLsaSeq()
// todo: 使用sync通知路由更新
// m_sync.publishRoutingUpdate(Lsa::Type::ADJACENCY, m_sequencingManager.getAdjLsaSeq());
// 安装lsa到LSDB
l.InstallLsa(adjLsa)
} }
// //
@@ -192,19 +526,69 @@ func (l *Lsdb) BuildAndInstallOwnAdjLsa() {
// @Description: 在调度器中安排一个刷新或过期事件 // @Description: 在调度器中安排一个刷新或过期事件
// @receiver l // @receiver l
// //
func (l *Lsdb) ScheduleLsaExpiration(lsa lsa.ILsa,duration *time.Duration) { func (l *Lsdb) ScheduleLsaExpiration(lsa lsa.ILsa, duration time.Duration) {
// 在指定间隔的几秒后触发刷新或过期事件
duration = duration + GRACE_PERIOD
// 安排LSA在指定时间间隔后进行删除
job, err := l.scheduler.ScheduleTaskAfterDuration(duration, 1).Do(l.ExpireOrRefreshLsa, lsa)
job.LimitRunsTo(1)
l.scheduler.StartAsync()
if err != nil {
common2.LogError("Scheduling Lsa Expiration error, ", err.Error())
}
} }
func (l* Lsdb) ExpireOrRefreshLsa(lsa lsa.ILsa) { //
} // ExpireOrRefreshLsa
// @Description: LSA过期时间触发后,执行该函数
func (l *Lsdb) ProcessInterestForLsa(interest *packet.Interest, // @receiver l
originRouterIdentifier *component.Identifier,lsaType lsa.LsaType,seqNo uint64) { // @param lsa
//
func (l *Lsdb) ExpireOrRefreshLsa(lsa lsa.ILsa) {
common2.LogDebug("ExpireOrRefreshLsa called for ", lsa.ToString())
lsaInDb := l.FindLsa(lsa.GetOriginRouter(), lsa.GetType())
if lsaInDb != nil {
common2.LogDebug("LSA Exists with seq no: ", lsaInDb.GetSeqNo())
// 只有DB中LSA序列号依然是传入调度器的LSA序列号时,才执行删除或更新动作。否则,该LSA已是新的,则不应修改它。
if lsaInDb.GetSeqNo() == lsa.GetSeqNo() {
if lsaInDb.GetOriginRouter().ToUri() == l.thisRouterPrefix.ToUri() {
// 如果是本机LSA,由于它不能被删除,因此我们只继续更新它
// 1. 更新
common2.LogDebug("Own lsa refreshing, ", lsaInDb.ToString())
lsaInDb.SetSeqNo(lsaInDb.GetSeqNo() + 1)
l.sequencingManager.SetLsaSeq(lsaInDb.GetSeqNo()+1, lsaInDb.GetType())
lsaInDb.SetExpirationTime(l.getLsaExpirationTimePoint())
err := l.Emplace(lsaInDb)
if err != nil {
common2.LogError("Own lsa refresh error, ", err.Error())
return
}
common2.LogDebug("Own lsa refreshed, ", lsaInDb.ToString())
// 2. 安排新的超期事件
l.ScheduleLsaExpiration(lsaInDb, l.lsaRefreshTime)
// 3. todo: 将lsa更新通知给sync
// m_sync.publishRoutingUpdate(lsaPtr->getType(), m_sequencingManager.getLsaSeq(lsaPtr->getType()));
} else {
// 如果是其他路由器的LSA,我们将删除它。
// 更新其他路由器的LSA是通过min-sync实现的,而不是超期触发。
common2.LogDebug("Other's LSA, so removing from LSDB, lsa is ", lsa.ToString())
l.RemoveLsa(lsaInDb)
}
}
}
} }
//
// ExpressInterest
// @Description: 发送请求其它路由器LSA的兴趣包
// @receiver l
// @param interestName
// @param timeOut
// @param deadline
//
func (l *Lsdb) ExpressInterest(interestName *component.Identifier, func (l *Lsdb) ExpressInterest(interestName *component.Identifier,
timeOut uint32,deadline *time.Time) { timeOut uint32, deadline *time.Time) {
} }
// //
@@ -219,9 +603,9 @@ func (l *Lsdb) ExpressInterest(interestName *component.Identifier,
// @param lsaName // @param lsaName
// @param seqNo // @param seqNo
// //
func (l *Lsdb) OnFetchLsaError(errorCode uint32,msg string, func (l *Lsdb) onFetchLsaError(errorCode uint32, msg string,
interestName *component.Identifier,retransmitNo uint32, interestName *component.Identifier, retransmitNo uint32,
deadline *time.Time,lsaName *component.Identifier,seqNo uint64) { deadline *time.Time, lsaName *component.Identifier, seqNo uint64) {
} }
// //
@@ -233,11 +617,16 @@ func (l *Lsdb) OnFetchLsaError(errorCode uint32,msg string,
// @param buffer // @param buffer
// @param interestName // @param interestName
// //
func (l *Lsdb) AfterFetchLsa(buffer bytes.Buffer,interestName *component.Identifier) { func (l *Lsdb) afterFetchLsa(buffer bytes.Buffer, interestName *component.Identifier) {
} }
func (l *Lsdb) getLsaExpirationTimePoint() time.Time { func (l *Lsdb) getLsaExpirationTimePoint() uint64 {
// todo timeExpire := time.Now()
return time.Time{} timeExpire = timeExpire.Add(l.mlsrConfig.GetRouterDeadInterval())
return uint64(timeExpire.UnixMilli())
} }
func (l *Lsdb) uintToTime(uintTime uint64) time.Time {
return time.UnixMilli(int64(uintTime))
}
+5 -5
View File
@@ -212,18 +212,18 @@ func TestName_BuildAndInstallAdjLsa(t *testing.T) {
// LogicFace初始化(假设初始化,暂时用不到) // LogicFace初始化(假设初始化,暂时用不到)
face := new(logicface.LogicFace) face := new(logicface.LogicFace)
// LSDB初始化 // LSDB初始化
lsdb := new(Lsdb) mlsdb := new(Lsdb)
lsdb.Init(mlsrConfig, sche, face) mlsdb.Init(mlsrConfig, sche, face)
// 2. 安装本机adjlsa // 2. 安装本机adjlsa
lsdb.BuildAndInstallOwnAdjLsa() mlsdb.BuildAndInstallOwnAdjLsa()
// 3. 打印lsdb中所有本机lsa // 3. 打印lsdb中所有本机lsa
lsas, _ := lsdb.LsaContainer.GetLSAsByType(lsa.LsaADJACENCYType) lsas, _ := mlsdb.LsaContainer.GetLSAsByType(lsa.LsaADJACENCYType)
for i := 0; i < len(lsas); i++ { for i := 0; i < len(lsas); i++ {
common2.LogInfo(lsas[i].ToString()) common2.LogInfo(lsas[i].ToString())
} }
lsas, _ = lsdb.LsaContainer.GetLSAsByType(lsa.LsaNAMEType) lsas, _ = mlsdb.LsaContainer.GetLSAsByType(lsa.LsaNAMEType)
for i := 0; i < len(lsas); i++ { for i := 0; i < len(lsas); i++ {
common2.LogInfo(lsas[i].ToString()) common2.LogInfo(lsas[i].ToString())
} }
+77
View File
@@ -9,10 +9,13 @@
package route package route
import ( import (
"fmt"
common2 "minlib/common" common2 "minlib/common"
"minlib/component" "minlib/component"
"mlsr/lsa" "mlsr/lsa"
"mlsr/lsdb" "mlsr/lsdb"
"mlsr/utils"
"strconv"
) )
// //
@@ -29,9 +32,83 @@ type NamePrefixTable struct {
m_ownRouterName *component.Identifier m_ownRouterName *component.Identifier
// 路由表。包含路由计算器计算出来的每个路由表标识及其对应的下一跳列表 // 路由表。包含路由计算器计算出来的每个路由表标识及其对应的下一跳列表
m_routingTable *RoutingTable m_routingTable *RoutingTable
// 信号接收器
m_afterRoutingChangeConnection *utils.Connection
m_afterLsdbModified *utils.Connection
// todo fib // todo fib
} }
//
// PrintSelf
// @Description: 打印名称前缀表的状态。用于测试。
// @receiver t
//
func (t *NamePrefixTable) PrintSelf() {
fmt.Println("------------------- Name Prefix Table begin: " + t.m_ownRouterName.ToUri() + " -----------------")
fmt.Println("-----------------" + " 1.路由表项池 begin " + "-----------------")
fmt.Println("路由表项池大小:" + strconv.Itoa(len(t.m_rtpool)))
for _, rtpe := range t.m_rtpool {
fmt.Println(rtpe.ToString())
}
fmt.Println("-----------------" + " 1.路由表项池 end " + "-----------------")
fmt.Println("----------------" + " 2.名称前缀列表 start " + "----------------")
fmt.Println("名称前缀列表大小:" + strconv.Itoa(len(t.nptEntryList)))
for i := 0; i < len(t.nptEntryList); i++ {
fmt.Println(t.nptEntryList[i].ToString())
}
fmt.Println("----------------" + " 2.名称前缀列表 end " + "----------------")
t.m_routingTable.PrintSelf()
fmt.Println("------------------- Name Prefix Table end: " + t.m_ownRouterName.ToUri() + " -----------------")
}
//
// Init
// @Description: 名称前缀表初始化
// @receiver t
// @param ownRouterName
// @param routingTable
// @param afterRoutingChangeSignal
// @param afterLsdbModifiedSignal
//
func (t *NamePrefixTable) Init(ownRouterName *component.Identifier,
routingTable *RoutingTable, afterRoutingChangeSignal *utils.Signal,
afterLsdbModifiedSignal *utils.Signal) {
// 初始化数据结构
t.m_rtpool = make(map[string]*RoutingTablePoolEntry)
// 赋值变量
t.m_ownRouterName = ownRouterName
t.m_routingTable = routingTable
// 监听路由表的修改,触发NPT表修改
bindRoutingChangeFunc := func(args ...interface{}) {
common2.LogInfo("NamePrefixTable bindRoutingChangeFunc.")
entrys := args[0].([]*RoutingTableEntry)
t.UpdateWithNewRoute(entrys)
}
t.m_afterRoutingChangeConnection = afterRoutingChangeSignal.Connect(bindRoutingChangeFunc)
// 监听LSDB修改,触发NPT表修改
bindLsdbModifiedFunc := func(args ...interface{}) {
common2.LogInfo("NamePrefixTable bindLsdbModifiedFunc.")
// 获取四个参数
ilsa := args[0].(lsa.ILsa)
updateType := args[1].(lsdb.LsdbUpdate)
common2.LogInfo("NamePrefixTable bindLsdbModifiedFunc lsa: ", ilsa.GetOriginRouter().ToUri())
common2.LogInfo("NamePrefixTable bindLsdbModifiedFunc updateType: ", updateType)
namesToAdd := []*component.Identifier{}
namesToRemove := []*component.Identifier{}
if updateType == lsdb.UPDATED {
namesToAdd = args[2].([]*component.Identifier)
namesToRemove = args[3].([]*component.Identifier)
}
// 执行更新操作
t.UpdateFromLsdb(ilsa, updateType, namesToAdd, namesToRemove)
}
t.m_afterLsdbModified = afterLsdbModifiedSignal.Connect(bindLsdbModifiedFunc)
}
// //
// UpdateFromLsdb // UpdateFromLsdb
// @Description: 根据lsdb的更新,对名称进行增加、更新或移除 // @Description: 根据lsdb的更新,对名称进行增加、更新或移除
+28 -2
View File
@@ -21,7 +21,7 @@ type NamePrefixTableEntry struct {
// 名称前缀 // 名称前缀
m_namePrefix *component.Identifier m_namePrefix *component.Identifier
// 保存路由表池项的切片。切片真好用。 // 保存路由表池项的切片。go语言切片真好用。
// 这是因为,由于支持网内缓存,一个名称前缀可能对应多个路由器标识符。 // 这是因为,由于支持网内缓存,一个名称前缀可能对应多个路由器标识符。
// 名称前缀标项,和路由表项,是多对多的关系。 // 名称前缀标项,和路由表项,是多对多的关系。
m_rteList []*RoutingTablePoolEntry m_rteList []*RoutingTablePoolEntry
@@ -29,6 +29,32 @@ type NamePrefixTableEntry struct {
NextHopList NextHopList
} }
//
// ToString
// @Description: 转string,用于测试
// @receiver e
//
func (e *NamePrefixTableEntry) ToString() string {
str := "-------名称前缀表项 Start:" + e.m_namePrefix.ToUri() + "------------\n"
for i := 0; i < len(e.m_rteList); i++ {
str += e.m_rteList[i].ToString()
}
str += "下一跳列表:\n"
str += e.NextHopList.ToString()
str += "-------名称前缀表项 End :" + e.m_namePrefix.ToUri() + "------------\n"
return str
}
//
// Init
// @Description: 初始化参数
// @receiver e
// @param namePrefix
//
func (e *NamePrefixTableEntry) Init(namePrefix *component.Identifier) {
e.m_namePrefix = namePrefix
}
// //
// GetNamePrefix // GetNamePrefix
// @Description: 获取所表示的名称前缀 // @Description: 获取所表示的名称前缀
@@ -93,7 +119,7 @@ func (e *NamePrefixTableEntry) GenerateNhlfromRteList() {
for i := 0; i < len(e.m_rteList); i++ { for i := 0; i < len(e.m_rteList); i++ {
// 遍历路由表条目的下一跳列表 // 遍历路由表条目的下一跳列表
for j := 0; j < e.m_rteList[i].NextHopList.Size(); j++ { for j := 0; j < e.m_rteList[i].NextHopList.Size(); j++ {
e.NextHopList.AddNextHop(e.m_rteList[i].nextHops[j]) e.NextHopList.AddNextHopBySmallerPriciple(e.m_rteList[i].nextHops[j])
} }
} }
} }
+58
View File
@@ -0,0 +1,58 @@
// Package route
// @Author: Wang Feng
// @Description:
// @Version: 0.1.0
// @Date: 2022/6/24 21:33
// @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
//
package route
import (
"fmt"
"minlib/component"
"testing"
)
//
// TestNamePrefixTable_AddEntry
// @Description: 名称前缀表,增加条目
// @param t
//
func TestNamePrefixTableEntry_AddEntry(t *testing.T) {
// 第一个RTPE
iden, _ := component.CreateIdentifierByString("/RouterC")
rtpe := new(RoutingTablePoolEntry)
rtpe.InitDest(iden, 123)
hop := new(NextHop)
hop.Init("tcp://1.1.1.1", 1)
rtpe.AddNextHop(hop)
// 名称前缀
namePrefix, _ := component.CreateIdentifierByString("/pku/pdf")
npte := new(NamePrefixTableEntry)
npte.Init(namePrefix)
// 打印该名称前缀
fmt.Println("名称前缀: ", npte.GetNamePrefix().ToUri())
// 增加rtpe
npte.AddRoutingTableEntry(rtpe)
fmt.Println(npte.ToString())
// 第二个rtpe
iden2, _ := component.CreateIdentifierByString("/RouterB")
rtpe2 := new(RoutingTablePoolEntry)
rtpe2.InitDest(iden2, 12)
hop2 := new(NextHop)
hop2.Init("tcp://1.1.1.0", 1)
rtpe2.AddNextHop(hop2)
npte.AddRoutingTableEntry(rtpe2)
// 生成下一跳列表
npte.GenerateNhlfromRteList()
fmt.Println(npte.ToString())
// 删除某个rtpe
npte.RemoveRoutingTableEntry(rtpe2)
fmt.Println(npte.ToString())
}
+497
View File
@@ -0,0 +1,497 @@
// Package route
// @Author: Wang Feng
// @Description:
// @Version: 0.1.0
// @Date: 2022/7/1 17:12
// @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
//
package route
import (
"fmt"
common2 "minlib/common"
"minlib/component"
"minlib/logicface"
"mlsr/common"
"mlsr/lsa"
"mlsr/lsdb"
"testing"
"time"
)
//
// TestNamePrefixTable_FinalTest
// @Description: 终极测试
// 先初始化Lsdb、配置项等结构体,再初始化路由表,并将lsdb传入路由表;
// 然后构建五节点邻接拓扑(这块在mlsr完全开发完成之后,将是通过hello和sync来触发更新的),
// 这个时候应触发路由表的路由计算功能。
// 之后再给每个路由器分配一些名称前缀,这个时候应触发名称前缀表的前缀更新下一跳功能。
// 最后,打印输出路由表所有参数,以及名称前缀表所有参数,手动查看是否与预期值相同。
// @param t
//
func TestNamePrefixTable_FinalTest(t *testing.T) {
// 1. 建立前置结构体(lsdb等)
// 配置文件初始化
mlsrConfig, err := common.ParseConfig(testConfigPath)
if err != nil {
common2.LogInfo("配置文件解析错误")
}
// 调度器初始化
sche := new(lsdb.MlsrScheduler)
sche.Init()
// LogicFace初始化(假设初始化,暂时用不到)
face := new(logicface.LogicFace)
// LSDB初始化
mlsdb := new(lsdb.Lsdb)
mlsdb.Init(mlsrConfig, sche, face)
// 2. 打印lsdb中所有本机lsa
lsas, _ := mlsdb.LsaContainer.GetLSAsByType(lsa.LsaADJACENCYType)
for i := 0; i < len(lsas); i++ {
common2.LogInfo(lsas[i].ToString())
}
lsas, _ = mlsdb.LsaContainer.GetLSAsByType(lsa.LsaNAMEType)
for i := 0; i < len(lsas); i++ {
common2.LogInfo(lsas[i].ToString())
}
fmt.Println("lsdb是否正在忙于构建lsdb: ", mlsdb.GetIsBuildAdjLsaScheduled())
// 3. 路由表初始化
rt := new(RoutingTable)
rt.Init(mlsrConfig, sche, mlsdb)
// 4. 名称前缀表初始化
npt := new(NamePrefixTable)
npt.Init(mlsrConfig.GetRouterPrefix(), rt, rt.AfterRoutingChange, mlsdb.OnLsdbModified)
// 5. 安装本机adjlsa => 将触发两个事件:A. 安排15s后做路由表计算;B.触发名称前缀表更新(本机lsa不做更新)
mlsdb.BuildAndInstallOwnAdjLsa()
fmt.Println("路由表是否已经知道lsdb成功构建了邻接Lsa: ", rt.m_ownAdjLsaExist)
// 6. 安装其它路由器的邻接lsa => A. 安排15s后做路由表计算;B.触发名称前缀表更新(邻接lsa只单单加入一个条目)
// 传入一些其它虚拟lsa,这些lsa与本机lsa共同形成一个小型路由拓扑
// 路由器B
adjLsaB := testCreateAdjLsa("/routerB")
adjInfoBA := testCreateAdjInfo(10, "/min/pkusz/routerA")
adjInfoBE := testCreateAdjInfo(50, "/routerE")
adjLsaB.Insert(adjInfoBA)
adjLsaB.Insert(adjInfoBE)
// 路由器C
adjLsaC := testCreateAdjLsa("/routerC")
adjInfoCA := testCreateAdjInfo(100, "/min/pkusz/routerA")
adjInfoCE := testCreateAdjInfo(10, "/routerE")
adjInfoCD := testCreateAdjInfo(60, "/routerD")
adjLsaC.Insert(adjInfoCA)
adjLsaC.Insert(adjInfoCD)
adjLsaC.Insert(adjInfoCE)
// 路由器E
adjLsaE := testCreateAdjLsa("/routerE")
adjInfoEB := testCreateAdjInfo(50, "/routerB")
adjInfoEC := testCreateAdjInfo(10, "/routerC")
adjInfoED := testCreateAdjInfo(20, "/routerD")
adjLsaE.Insert(adjInfoEB)
adjLsaE.Insert(adjInfoEC)
adjLsaE.Insert(adjInfoED)
// 路由器D
adjLsaD := testCreateAdjLsa("/routerD")
adjInfoDA := testCreateAdjInfo(30, "/min/pkusz/routerA")
adjInfoDC := testCreateAdjInfo(60, "/routerC")
adjInfoDE := testCreateAdjInfo(20, "/routerE")
adjLsaD.Insert(adjInfoDA)
adjLsaD.Insert(adjInfoDC)
adjLsaD.Insert(adjInfoDE)
mlsdb.InstallLsa(adjLsaB)
mlsdb.InstallLsa(adjLsaC)
mlsdb.InstallLsa(adjLsaD)
mlsdb.InstallLsa(adjLsaE)
// 7. 只是等待。并打印路由表
for i := 0; i < 30; i++ {
time.Sleep(time.Second)
fmt.Println(i+1, " seconds later...")
rt.PrintSelf()
}
}
//
// TestNamePrefixTable_AddEntry
// @Description: 测试增加一个条目
// @param t
//
func TestNamePrefixTable_AddEntryAndRemoveEntry(t *testing.T) {
// 1. 建立前置结构体(lsdb等)
// 配置文件初始化
mlsrConfig, err := common.ParseConfig(testConfigPath)
if err != nil {
common2.LogInfo("配置文件解析错误")
}
// 调度器初始化
sche := new(lsdb.MlsrScheduler)
sche.Init()
// LogicFace初始化(假设初始化,暂时用不到)
face := new(logicface.LogicFace)
// LSDB初始化
mlsdb := new(lsdb.Lsdb)
mlsdb.Init(mlsrConfig, sche, face)
// 2. 打印lsdb中所有本机lsa
lsas, _ := mlsdb.LsaContainer.GetLSAsByType(lsa.LsaADJACENCYType)
for i := 0; i < len(lsas); i++ {
common2.LogInfo(lsas[i].ToString())
}
lsas, _ = mlsdb.LsaContainer.GetLSAsByType(lsa.LsaNAMEType)
for i := 0; i < len(lsas); i++ {
common2.LogInfo(lsas[i].ToString())
}
fmt.Println("lsdb是否正在忙于构建lsdb: ", mlsdb.GetIsBuildAdjLsaScheduled())
// 3. 路由表初始化
rt := new(RoutingTable)
rt.Init(mlsrConfig, sche, mlsdb)
// 4. 名称前缀表初始化
npt := new(NamePrefixTable)
npt.Init(mlsrConfig.GetRouterPrefix(), rt, rt.AfterRoutingChange, mlsdb.OnLsdbModified)
// 5. 安装本机adjlsa => 将触发两个事件:A. 安排15s后做路由表计算;B.触发名称前缀表更新(本机lsa不做更新)
mlsdb.BuildAndInstallOwnAdjLsa()
// 看看npt
fmt.Println("光秃秃啥也没有:")
npt.PrintSelf()
// 6. 插入一个条目:目的路由器没有在路由表中
name, _ := component.CreateIdentifierByString("/someSourceNames")
route, _ := component.CreateIdentifierByString("/routeAAA")
npt.AddEntry(name, route)
fmt.Println("加了一个虚空资源")
npt.PrintSelf()
// 7. 加入五星拓扑
// 安装其它路由器的邻接lsa => A. 安排15s后做路由表计算;B.触发名称前缀表更新(邻接lsa只单单加入一个条目)
// 传入一些其它虚拟lsa,这些lsa与本机lsa共同形成一个小型路由拓扑
// 路由器B
adjLsaB := testCreateAdjLsa("/routerB")
adjInfoBA := testCreateAdjInfo(10, "/min/pkusz/routerA")
adjInfoBE := testCreateAdjInfo(50, "/routerE")
adjLsaB.Insert(adjInfoBA)
adjLsaB.Insert(adjInfoBE)
// 路由器C
adjLsaC := testCreateAdjLsa("/routerC")
adjInfoCA := testCreateAdjInfo(100, "/min/pkusz/routerA")
adjInfoCE := testCreateAdjInfo(10, "/routerE")
adjInfoCD := testCreateAdjInfo(60, "/routerD")
adjLsaC.Insert(adjInfoCA)
adjLsaC.Insert(adjInfoCD)
adjLsaC.Insert(adjInfoCE)
// 路由器E
adjLsaE := testCreateAdjLsa("/routerE")
adjInfoEB := testCreateAdjInfo(50, "/routerB")
adjInfoEC := testCreateAdjInfo(10, "/routerC")
adjInfoED := testCreateAdjInfo(20, "/routerD")
adjLsaE.Insert(adjInfoEB)
adjLsaE.Insert(adjInfoEC)
adjLsaE.Insert(adjInfoED)
// 路由器D
adjLsaD := testCreateAdjLsa("/routerD")
adjInfoDA := testCreateAdjInfo(30, "/min/pkusz/routerA")
adjInfoDC := testCreateAdjInfo(60, "/routerC")
adjInfoDE := testCreateAdjInfo(20, "/routerE")
adjLsaD.Insert(adjInfoDA)
adjLsaD.Insert(adjInfoDC)
adjLsaD.Insert(adjInfoDE)
mlsdb.InstallLsa(adjLsaB)
mlsdb.InstallLsa(adjLsaC)
mlsdb.InstallLsa(adjLsaD)
mlsdb.InstallLsa(adjLsaE)
for i := 0; i < 15; i++ {
time.Sleep(time.Second)
fmt.Println(i+1, " seconds later...")
}
fmt.Println("五星拓扑构建完成.")
// 8. 加入一个拓扑之上的资源
nameC, _ := component.CreateIdentifierByString("/realSourcesInRouterC")
routeC, _ := component.CreateIdentifierByString("/routerC")
npt.AddEntry(nameC, routeC)
fmt.Println("加了一个真实资源在路由器C上")
npt.PrintSelf()
// 9. 加入一个拓扑之上的资源,该资源被允许存在在两个路由器之上
routeB, _ := component.CreateIdentifierByString("/routerB")
npt.AddEntry(nameC, routeB)
fmt.Println("将路由C之上的真实资源同时加在路由器B上")
npt.PrintSelf()
// 10.1 删除一个虚空资源
npt.RemoveEntry(name, route)
fmt.Println("---------- 删除一个虚空资源 -----------")
npt.PrintSelf()
// 10.2 删除一个在两个路由器上的资源标识,只删除某个路由器上的该资源
npt.RemoveEntry(nameC, routeB)
fmt.Println("--------------- 删除一个在两个路由器上的资源标识 ------------------")
npt.PrintSelf()
// 10.3 删除一个路由器标识
routeE, _ := component.CreateIdentifierByString("/routerE")
npt.RemoveEntry(routeE, routeE)
fmt.Println("---------- 删除一个路由器标识: routerE -----------")
npt.PrintSelf()
}
//
// TestNamePrefixTable_UpdateFromLsdb
// @Description: 测试根据Lsdb的变化而更新名称前缀表
// @param t
//
func TestNamePrefixTable_UpdateFromLsdb(t *testing.T) {
// 1. 建立前置结构体(lsdb等)
// 配置文件初始化
mlsrConfig, err := common.ParseConfig(testConfigPath)
if err != nil {
common2.LogInfo("配置文件解析错误")
}
// 调度器初始化
sche := new(lsdb.MlsrScheduler)
sche.Init()
// LogicFace初始化(假设初始化,暂时用不到)
face := new(logicface.LogicFace)
// LSDB初始化
mlsdb := new(lsdb.Lsdb)
mlsdb.Init(mlsrConfig, sche, face)
// 2. 打印lsdb中所有本机lsa
lsas, _ := mlsdb.LsaContainer.GetLSAsByType(lsa.LsaADJACENCYType)
for i := 0; i < len(lsas); i++ {
common2.LogInfo(lsas[i].ToString())
}
lsas, _ = mlsdb.LsaContainer.GetLSAsByType(lsa.LsaNAMEType)
for i := 0; i < len(lsas); i++ {
common2.LogInfo(lsas[i].ToString())
}
fmt.Println("lsdb是否正在忙于构建lsdb: ", mlsdb.GetIsBuildAdjLsaScheduled())
// 3. 路由表初始化
rt := new(RoutingTable)
rt.Init(mlsrConfig, sche, mlsdb)
// 4. 名称前缀表初始化
npt := new(NamePrefixTable)
npt.Init(mlsrConfig.GetRouterPrefix(), rt, rt.AfterRoutingChange, mlsdb.OnLsdbModified)
// 5. 安装本机adjlsa => 将触发两个事件:A. 安排15s后做路由表计算;B.触发名称前缀表更新(本机lsa不做更新)
mlsdb.BuildAndInstallOwnAdjLsa()
// 看看npt
fmt.Println("光秃秃啥也没有:")
npt.PrintSelf()
// 6. 插入一个条目:目的路由器没有在路由表中
name, _ := component.CreateIdentifierByString("/someSourceNames")
route, _ := component.CreateIdentifierByString("/routeAAA")
npt.AddEntry(name, route)
fmt.Println("加了一个虚空资源")
npt.PrintSelf()
// 7. 加入五星拓扑
// 安装其它路由器的邻接lsa => A. 安排15s后做路由表计算;B.触发名称前缀表更新(邻接lsa只单单加入一个条目)
// 传入一些其它虚拟lsa,这些lsa与本机lsa共同形成一个小型路由拓扑
// 路由器B
adjLsaB := testCreateAdjLsa("/routerB")
adjInfoBA := testCreateAdjInfo(10, "/min/pkusz/routerA")
adjInfoBE := testCreateAdjInfo(50, "/routerE")
adjLsaB.Insert(adjInfoBA)
adjLsaB.Insert(adjInfoBE)
// 路由器C
adjLsaC := testCreateAdjLsa("/routerC")
adjInfoCA := testCreateAdjInfo(100, "/min/pkusz/routerA")
adjInfoCE := testCreateAdjInfo(10, "/routerE")
adjInfoCD := testCreateAdjInfo(60, "/routerD")
adjLsaC.Insert(adjInfoCA)
adjLsaC.Insert(adjInfoCD)
adjLsaC.Insert(adjInfoCE)
// 路由器E
adjLsaE := testCreateAdjLsa("/routerE")
adjInfoEB := testCreateAdjInfo(50, "/routerB")
adjInfoEC := testCreateAdjInfo(10, "/routerC")
adjInfoED := testCreateAdjInfo(20, "/routerD")
adjLsaE.Insert(adjInfoEB)
adjLsaE.Insert(adjInfoEC)
adjLsaE.Insert(adjInfoED)
// 路由器D
adjLsaD := testCreateAdjLsa("/routerD")
adjInfoDA := testCreateAdjInfo(30, "/min/pkusz/routerA")
adjInfoDC := testCreateAdjInfo(60, "/routerC")
adjInfoDE := testCreateAdjInfo(20, "/routerE")
adjLsaD.Insert(adjInfoDA)
adjLsaD.Insert(adjInfoDC)
adjLsaD.Insert(adjInfoDE)
mlsdb.InstallLsa(adjLsaB)
mlsdb.InstallLsa(adjLsaC)
mlsdb.InstallLsa(adjLsaD)
mlsdb.InstallLsa(adjLsaE)
for i := 0; i < 15; i++ {
time.Sleep(time.Second)
fmt.Println(i+1, " seconds later...")
}
fmt.Println("五星拓扑构建完成.")
// 8. 加入一个拓扑之上的资源
nameC, _ := component.CreateIdentifierByString("/realSourcesInRouterC")
routeC, _ := component.CreateIdentifierByString("/routerC")
npt.AddEntry(nameC, routeC)
fmt.Println("加了一个真实资源在路由器C上")
npt.PrintSelf()
// 9. 加入一个拓扑之上的资源,该资源被允许存在在两个路由器之上
routeB, _ := component.CreateIdentifierByString("/routerB")
npt.AddEntry(nameC, routeB)
fmt.Println("将路由C之上的真实资源同时加在路由器B上")
npt.PrintSelf()
// 10. 将五拓扑中的 D->E 这条链路给切断:以重新install LSA的形式。
// 路由器E
adjNewLsaE := testCreateAdjLsa("/routerE")
adjNewLsaE.SetSeqNo(22222)
adjNewLsaE.Insert(adjInfoEB)
adjNewLsaE.Insert(adjInfoEC)
// 路由器D
adjNewLsaD := testCreateAdjLsa("/routerD")
adjNewLsaD.SetSeqNo(22222)
adjNewLsaD.Insert(adjInfoDA)
adjNewLsaD.Insert(adjInfoDC)
// 将两者重新安装
mlsdb.InstallLsa(adjNewLsaE)
mlsdb.InstallLsa(adjNewLsaD)
// 静候下一个路由计算间隔
for i := 0; i < 15; i++ {
time.Sleep(time.Second)
fmt.Println(i+1, " seconds later...")
}
// 观察触发的双表变化
npt.PrintSelf()
}
//
// TestNamePrefixTable_UpdateWithNewRoute
// @Description: 测试根据路由变化而更新名称前缀表.
// 当路由表更新时,名称前缀表应随之更新。如,路由表被清空,则名称前缀表对应前缀的下一跳也应随之清空。
// @param t
//
func TestNamePrefixTable_UpdateWithNewRoute(t *testing.T) {
// 1. 建立前置结构体(lsdb等)
// 配置文件初始化
mlsrConfig, err := common.ParseConfig(testConfigPath)
if err != nil {
common2.LogInfo("配置文件解析错误")
}
// 调度器初始化
sche := new(lsdb.MlsrScheduler)
sche.Init()
// LogicFace初始化(假设初始化,暂时用不到)
face := new(logicface.LogicFace)
// LSDB初始化
mlsdb := new(lsdb.Lsdb)
mlsdb.Init(mlsrConfig, sche, face)
// 2. 打印lsdb中所有本机lsa
lsas, _ := mlsdb.LsaContainer.GetLSAsByType(lsa.LsaADJACENCYType)
for i := 0; i < len(lsas); i++ {
common2.LogInfo(lsas[i].ToString())
}
lsas, _ = mlsdb.LsaContainer.GetLSAsByType(lsa.LsaNAMEType)
for i := 0; i < len(lsas); i++ {
common2.LogInfo(lsas[i].ToString())
}
fmt.Println("lsdb是否正在忙于构建lsdb: ", mlsdb.GetIsBuildAdjLsaScheduled())
// 3. 路由表初始化
rt := new(RoutingTable)
rt.Init(mlsrConfig, sche, mlsdb)
// 4. 名称前缀表初始化
npt := new(NamePrefixTable)
npt.Init(mlsrConfig.GetRouterPrefix(), rt, rt.AfterRoutingChange, mlsdb.OnLsdbModified)
// 5. 安装本机adjlsa => 将触发两个事件:A. 安排15s后做路由表计算;B.触发名称前缀表更新(本机lsa不做更新)
mlsdb.BuildAndInstallOwnAdjLsa()
// 看看npt
fmt.Println("光秃秃啥也没有:")
npt.PrintSelf()
// 6. 插入一个条目:目的路由器没有在路由表中
name, _ := component.CreateIdentifierByString("/someSourceNames")
route, _ := component.CreateIdentifierByString("/routeAAA")
npt.AddEntry(name, route)
fmt.Println("加了一个虚空资源")
npt.PrintSelf()
// 7. 加入五星拓扑
// 安装其它路由器的邻接lsa => A. 安排15s后做路由表计算;B.触发名称前缀表更新(邻接lsa只单单加入一个条目)
// 传入一些其它虚拟lsa,这些lsa与本机lsa共同形成一个小型路由拓扑
// 路由器B
adjLsaB := testCreateAdjLsa("/routerB")
adjInfoBA := testCreateAdjInfo(10, "/min/pkusz/routerA")
adjInfoBE := testCreateAdjInfo(50, "/routerE")
adjLsaB.Insert(adjInfoBA)
adjLsaB.Insert(adjInfoBE)
// 路由器C
adjLsaC := testCreateAdjLsa("/routerC")
adjInfoCA := testCreateAdjInfo(100, "/min/pkusz/routerA")
adjInfoCE := testCreateAdjInfo(10, "/routerE")
adjInfoCD := testCreateAdjInfo(60, "/routerD")
adjLsaC.Insert(adjInfoCA)
adjLsaC.Insert(adjInfoCD)
adjLsaC.Insert(adjInfoCE)
// 路由器E
adjLsaE := testCreateAdjLsa("/routerE")
adjInfoEB := testCreateAdjInfo(50, "/routerB")
adjInfoEC := testCreateAdjInfo(10, "/routerC")
adjInfoED := testCreateAdjInfo(20, "/routerD")
adjLsaE.Insert(adjInfoEB)
adjLsaE.Insert(adjInfoEC)
adjLsaE.Insert(adjInfoED)
// 路由器D
adjLsaD := testCreateAdjLsa("/routerD")
adjInfoDA := testCreateAdjInfo(30, "/min/pkusz/routerA")
adjInfoDC := testCreateAdjInfo(60, "/routerC")
adjInfoDE := testCreateAdjInfo(20, "/routerE")
adjLsaD.Insert(adjInfoDA)
adjLsaD.Insert(adjInfoDC)
adjLsaD.Insert(adjInfoDE)
mlsdb.InstallLsa(adjLsaB)
mlsdb.InstallLsa(adjLsaC)
mlsdb.InstallLsa(adjLsaD)
mlsdb.InstallLsa(adjLsaE)
for i := 0; i < 15; i++ {
time.Sleep(time.Second)
fmt.Println(i+1, " seconds later...")
}
fmt.Println("五星拓扑构建完成.")
// 8. 加入一个拓扑之上的资源
nameC, _ := component.CreateIdentifierByString("/realSourcesInRouterC")
routeC, _ := component.CreateIdentifierByString("/routerC")
npt.AddEntry(nameC, routeC)
fmt.Println("加了一个真实资源在路由器C上")
npt.PrintSelf()
// 9. 加入一个拓扑之上的资源,该资源被允许存在在两个路由器之上
routeB, _ := component.CreateIdentifierByString("/routerB")
npt.AddEntry(nameC, routeB)
fmt.Println("将路由C之上的真实资源同时加在路由器B上")
npt.PrintSelf()
// 根据配置文件,构造本机的名称LSA
adjLsa := new(lsa.AdjLsa)
adjLsa.SetOriginRouter(mlsrConfig.GetRouterPrefix())
adjLsa.SetSeqNo(11022) // 序列号
adjLsa.SetLsaExpirationTime(1283719) // 超期时间
adjLsa.AdjLsaAdjacenctList.InsertAdjacenctList(mlsrConfig.GetAdjacencyList()) // 名称前缀列表
// 10. 从Lsdb中删除该lsa,以观察触发路由更改,由此触发路由表清零,从而触发所有与之相关的名称前缀列表的更新
mlsdb.RemoveLsa(adjLsa)
npt.PrintSelf()
}
+10
View File
@@ -41,6 +41,16 @@ func NewNextHop(uri string, cost uint64) (*NextHop, error) {
return nextHop, nil return nextHop, nil
} }
//
// Init
// @Description: 参数初始化
// @receiver l
//
func (l *NextHop) Init(faceUri string, cost uint64) {
l.SetLogicFaceUri(faceUri)
l.SetRouteCost(cost)
}
// //
// WireEncode // WireEncode
// @Description: 线速编码 // @Description: 线速编码
+21 -2
View File
@@ -88,7 +88,7 @@ func (l *NextHopList) findSameNextHop(hop *NextHop) int {
// //
// AddNextHop // AddNextHop
// @Description: 增加一个下一跳表项。1. 如果不存在同uri,则插入;2. 如果存在,但cost不同,则更新它 // @Description: 增加一个下一跳表项。1. 如果不存在同uri,则插入;2. 如果存在,但cost不同,则按照新的下一跳来更新它
// @receiver l // @receiver l
// @param hop // @param hop
// //
@@ -97,7 +97,26 @@ func (l *NextHopList) AddNextHop(hop *NextHop) {
if index < 0 { if index < 0 {
l.nextHops = append(l.nextHops, hop) l.nextHops = append(l.nextHops, hop)
} else if l.nextHops[index].RouteCost.RouteCost() != hop.RouteCost.RouteCost() { } else if l.nextHops[index].RouteCost.RouteCost() != hop.RouteCost.RouteCost() {
l.nextHops[index].RouteCost.SetRouteCost(hop.RouteCost.RouteCost()) // 注意,这里必须先删掉旧的,再加入新的;如果直接修改旧的nextHop,则可能导致该nextHop所属的另一个NextHopList属性被改变
l.RemoveNextHop(l.nextHops[index])
l.nextHops = append(l.nextHops, hop)
}
}
//
// AddNextHopBySmallerPriciple
// @Description: 在加入重合下一跳时,按照取较小开销的下一跳原则,进行更新
// @receiver l
// @param hop
//
func (l *NextHopList) AddNextHopBySmallerPriciple(hop *NextHop) {
index := l.findSameUriNextHop(hop)
if index < 0 {
l.nextHops = append(l.nextHops, hop)
} else if l.nextHops[index].RouteCost.RouteCost() > hop.RouteCost.RouteCost() {
// 注意,这里必须先删掉旧的,再加入新的;如果直接修改旧的nextHop,则可能导致该nextHop所属的另一个NextHopList属性被改变
l.RemoveNextHop(l.nextHops[index])
l.nextHops = append(l.nextHops, hop)
} }
} }
+89 -12
View File
@@ -10,6 +10,7 @@ package route
import ( import (
"errors" "errors"
"fmt"
common2 "minlib/common" common2 "minlib/common"
"minlib/component" "minlib/component"
"minlib/encoding" "minlib/encoding"
@@ -17,6 +18,8 @@ import (
"mlsr/extensions" "mlsr/extensions"
"mlsr/lsa" "mlsr/lsa"
"mlsr/lsdb" "mlsr/lsdb"
"mlsr/utils"
"strconv"
"time" "time"
) )
@@ -39,10 +42,33 @@ type RoutingTable struct {
// 当前路由器的邻接LSA是否存在 // 当前路由器的邻接LSA是否存在
m_ownAdjLsaExist bool m_ownAdjLsaExist bool
// 通知路由表更改的信号
AfterRoutingChange *utils.Signal
// 监听Lsdb被修改的信号接收器
m_afterLsdbModified *utils.Connection
// 双曲坐标状态 => 暂时用不到 // 双曲坐标状态 => 暂时用不到
m_hyperbolicState uint32 m_hyperbolicState uint32
} }
//
// PrintSelf
// @Description: 打印状态,用于测试
// @receiver t
//
func (t *RoutingTable) PrintSelf() {
fmt.Println("----------- Routing Table begin ---------")
fmt.Println("len: " + strconv.Itoa(len(t.rTable)))
for i := 0; i < len(t.rTable); i++ {
fmt.Println(t.rTable[i].ToString())
}
fmt.Println("路由计算间隔: " + t.m_routingCalcInterval.String())
fmt.Println("是否正在计算: " + strconv.FormatBool(t.m_isRoutingTableCalculating))
fmt.Println("是否安排计算: " + strconv.FormatBool(t.m_isRouteCalculationScheduled))
fmt.Println("本机路由器邻接lsa存在状态: ", t.m_ownAdjLsaExist)
fmt.Println("----------- Routing Table end ---------")
}
// //
// Init // Init
// @Description: 初始化 // @Description: 初始化
@@ -66,16 +92,67 @@ func (t *RoutingTable) Init(mc *common.MlsrConfig,
t.m_isRoutingTableCalculating = false t.m_isRoutingTableCalculating = false
t.m_isRouteCalculationScheduled = false t.m_isRouteCalculationScheduled = false
// todo 事件监听:如果监听到了传来的删除本地邻接LSA操作 // 初始化信号
t.AfterRoutingChange = utils.NewSignal()
// todo 事件监听:如果监听到了传来的安装本地邻接LSA操作 bindFunc := func(args ...interface{}) {
t.m_ownAdjLsaExist = true // 获取四个参数
ilsa := args[0].(lsa.ILsa)
updateType := args[1].(lsdb.LsdbUpdate)
common2.LogInfo("RoutingTable.bindFunc: ",
ilsa.GetOriginRouter().ToUri(), " ", updateType)
//var namesToAdd []*component.Identifier
//var namesToRemove []*component.Identifier
//if updateType == lsdb.REMOVED {
// namesToAdd = args[2].([]*component.Identifier)
// namesToRemove = args[3].([]*component.Identifier)
//}
// todo 事件监听:如果监听到了传来的安装或更新本地邻接LSA操作 // 根据四个参数做进一步的信息获取
//err := t.ScheduleRoutingTableCalculation() lsaType := ilsa.GetType()
//if err != nil { updateForOwnAdjacencyLsa := false
// common2.LogError("RoutingTable.Init ScheduleRoutingTableCalculation error.") if ilsa.GetOriginRouter().ToUri() == t.mlsrConfig.GetRouterPrefix().ToUri() &&
//} lsaType == lsa.LsaADJACENCYType {
updateForOwnAdjacencyLsa = true
}
// 事件监听:如果监听到了传来的删除本地邻接LSA操作
if updateType == lsdb.REMOVED && updateForOwnAdjacencyLsa {
// 如果删除了自己的邻接LSA,那么我们就没有活动邻居。
//(永远不会删除自身坐标LSA。但路由表计算在HelloProtocol中安排。HR的路由表计算器会考虑链路的非活动状态)
common2.LogDebug("No Adj LSA of router itself, routing table can not be calculated :(")
t.clearRoutingTable()
common2.LogDebug("Calling Update NPT With new Route")
// todo 触发改变 AfterRoutingChange(m_rTable);
t.AfterRoutingChange.Emit(t.rTable)
t.m_ownAdjLsaExist = false
}
// 事件监听:如果监听到了传来的安装本地邻接LSA操作
if updateType == lsdb.INSTALLED && updateForOwnAdjacencyLsa {
t.m_ownAdjLsaExist = true
}
scheduleCalculation := false
// 事件监听:如果监听到了传来的安装或更新本地邻接LSA操作
// 不要在移除时做任何事情,等待Hello协议去确认,然后做出响应
if updateType == lsdb.INSTALLED || updateType == lsdb.UPDATED {
if lsaType == lsa.LsaADJACENCYType {
scheduleCalculation = true
}
}
if scheduleCalculation {
common2.LogInfo("Is Schedule RoutingTable Calculation...")
err := t.ScheduleRoutingTableCalculation()
if err != nil {
common2.LogError("RoutingTable.Init ScheduleRoutingTableCalculation error.")
}
}
}
t.m_afterLsdbModified = t.lsdb.OnLsdbModified.Connect(bindFunc)
} }
// //
@@ -91,7 +168,7 @@ func (t *RoutingTable) Calculate() {
// 做邻接路由计算 // 做邻接路由计算
t.calculateLsRoutingTable() t.calculateLsRoutingTable()
// 恢复计算状态 // 恢复到可以被安排做路由计算状态
t.m_isRouteCalculationScheduled = false t.m_isRouteCalculationScheduled = false
t.m_isRoutingTableCalculating = false t.m_isRoutingTableCalculating = false
} else { } else {
@@ -118,11 +195,11 @@ func (t *RoutingTable) AddNextHop(destRouter *component.Identifier, hop *NextHop
// 如果没有这条表项,则构建并加入 // 如果没有这条表项,则构建并加入
if rte == nil { if rte == nil {
rte = new(RoutingTableEntry) rte = new(RoutingTableEntry)
rte.SetDestination(destRouter)
rte.AddNextHop(hop) rte.AddNextHop(hop)
t.rTable = append(t.rTable, rte) t.rTable = append(t.rTable, rte)
} else { } else {
// 如果有,则直接编辑该条目,增加一个下一跳. // 如果有,则直接编辑该条目,增加一个下一跳.
// todo: 这块需要测试,是否在go中可以直接根据引用进行表项的修改
rte.AddNextHop(hop) rte.AddNextHop(hop)
} }
} }
@@ -208,9 +285,9 @@ func (t *RoutingTable) calculateLsRoutingTable() {
t.AddNextHop(routers[i], nexthops[i]) t.AddNextHop(routers[i], nexthops[i])
} }
// todo: 开始根据新计算的路由去更新NPT表 // 开始根据新计算的路由去更新NPT表
common2.LogInfo("Calling Update NPT With new Route") common2.LogInfo("Calling Update NPT With new Route")
//todo t.AfterRoutingChange.Emit(t.rTable)
} }
// //
+27
View File
@@ -10,6 +10,7 @@ package route
import ( import (
"minlib/component" "minlib/component"
"strconv"
) )
// //
@@ -23,6 +24,26 @@ type RoutingTablePoolEntry struct {
m_useCount uint64 // 记录本条目被多少条名称前缀所使用 m_useCount uint64 // 记录本条目被多少条名称前缀所使用
} }
//
// ToString
// @Description: 转string,用于测试
// @receiver pe
// @return string
//
func (pe *RoutingTablePoolEntry) ToString() string {
str := "-------RoutingTablePoolEntry Start--------\n"
str += "use Count: " + strconv.FormatUint(pe.m_useCount, 10) + "\n"
str += pe.RoutingTableEntry.ToString()
str += "entries len: " + strconv.Itoa(len(pe.NamePrefixTableEntries)) + "\n"
str += "NamePrefixTableEntries: "
for prefix, _ := range pe.NamePrefixTableEntries {
str += prefix + " "
}
str += "\n"
str += "-------RoutingTablePoolEntry End --------\n"
return str
}
// //
// Init // Init
// @Description: 初始化目的路由器 // @Description: 初始化目的路由器
@@ -32,6 +53,8 @@ type RoutingTablePoolEntry struct {
func (pe *RoutingTablePoolEntry) Init(dest *component.Identifier) { func (pe *RoutingTablePoolEntry) Init(dest *component.Identifier) {
pe.m_destination = dest pe.m_destination = dest
pe.m_useCount = 1 pe.m_useCount = 1
// map 初始化
pe.NamePrefixTableEntries = make(map[string]*NamePrefixTableEntry)
} }
// //
@@ -45,6 +68,8 @@ func (pe *RoutingTablePoolEntry) InitRTE(rte *RoutingTableEntry, useCount uint64
pe.m_destination = rte.m_destination pe.m_destination = rte.m_destination
pe.nextHops = rte.GetNextHops() pe.nextHops = rte.GetNextHops()
pe.m_useCount = useCount pe.m_useCount = useCount
// map 初始化
pe.NamePrefixTableEntries = make(map[string]*NamePrefixTableEntry)
} }
// //
@@ -57,6 +82,8 @@ func (pe *RoutingTablePoolEntry) InitRTE(rte *RoutingTableEntry, useCount uint64
func (pe *RoutingTablePoolEntry) InitDest(dest *component.Identifier, useCount uint64) { func (pe *RoutingTablePoolEntry) InitDest(dest *component.Identifier, useCount uint64) {
pe.m_destination = dest pe.m_destination = dest
pe.m_useCount = useCount pe.m_useCount = useCount
// map 初始化
pe.NamePrefixTableEntries = make(map[string]*NamePrefixTableEntry)
} }
// //
+69
View File
@@ -0,0 +1,69 @@
// Package route
// @Author: Wang Feng
// @Description:
// @Version: 0.1.0
// @Date: 2022/6/24 21:44
// @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
//
package route
import (
"fmt"
"minlib/component"
"testing"
)
//
// TestRoutingTablePoolEntry_Init
// @Description: 测试初始化
// @param t
//
func TestRoutingTablePoolEntry_Init(t *testing.T) {
iden, _ := component.CreateIdentifierByString("/ifIhaveAnotherChance")
rtpe := new(RoutingTablePoolEntry)
rtpe.Init(iden)
// 打印
fmt.Println(rtpe.m_useCount)
fmt.Println(rtpe.m_destination.ToUri())
}
//
// TestRoutingTablePoolEntry_InitDest
// @Description: 测试初始化
// @param t
//
func TestRoutingTablePoolEntry_InitDest(t *testing.T) {
iden, _ := component.CreateIdentifierByString("/ifIhaveAnotherChance")
rtpe := new(RoutingTablePoolEntry)
rtpe.InitDest(iden, 123)
// 打印
fmt.Println(rtpe.m_useCount)
fmt.Println(rtpe.m_destination.ToUri())
}
//
// TestRoutingTablePoolEntry_IsEqual
// @Description: 测试两个rtpe是否相等
// @param t
//
func TestRoutingTablePoolEntry_IsEqual(t *testing.T) {
// 第一个
iden, _ := component.CreateIdentifierByString("/ifIhaveAnotherChance")
rtpe := new(RoutingTablePoolEntry)
rtpe.InitDest(iden, 123)
hop := new(NextHop)
hop.Init("/f", 1)
rtpe.AddNextHop(hop)
iden2, _ := component.CreateIdentifierByString("/ifIhaveAnotherChance")
rtpe2 := new(RoutingTablePoolEntry)
rtpe2.InitDest(iden2, 123)
hop2 := new(NextHop)
hop2.Init("/f", 2)
rtpe2.AddNextHop(hop2)
fmt.Println("是否相等: ", rtpe.IsEqual(rtpe2))
}
+208 -2
View File
@@ -9,11 +9,15 @@
package route package route
import ( import (
"fmt"
common2 "minlib/common" common2 "minlib/common"
"minlib/component"
"minlib/logicface" "minlib/logicface"
"mlsr/common" "mlsr/common"
"mlsr/lsa"
"mlsr/lsdb" "mlsr/lsdb"
"testing" "testing"
"time"
) )
// //
@@ -48,22 +52,224 @@ func TestRoutingTable_Init(t *testing.T) {
// @param t // @param t
// //
func TestRoutingTable_AddNextHop(t *testing.T) { func TestRoutingTable_AddNextHop(t *testing.T) {
// 1. 组件初始化
// 配置文件初始化
mlsrConfig, err := common.ParseConfig(testConfigPath)
if err != nil {
common2.LogInfo("配置文件解析错误")
}
// 调度器初始化
sche := new(lsdb.MlsrScheduler)
sche.Init()
// LogicFace初始化(假设初始化,暂时用不到)
face := new(logicface.LogicFace)
// LSDB初始化
mlsdb := new(lsdb.Lsdb)
mlsdb.Init(mlsrConfig, sche, face)
// 安装本机adjlsa
mlsdb.BuildAndInstallOwnAdjLsa()
// 2. 打印lsdb中所有本机lsa
lsas, _ := mlsdb.LsaContainer.GetLSAsByType(lsa.LsaADJACENCYType)
for i := 0; i < len(lsas); i++ {
common2.LogInfo(lsas[i].ToString())
}
lsas, _ = mlsdb.LsaContainer.GetLSAsByType(lsa.LsaNAMEType)
for i := 0; i < len(lsas); i++ {
common2.LogInfo(lsas[i].ToString())
}
// 3. 路由表初始化
rt := new(RoutingTable)
rt.Init(mlsrConfig, sche, mlsdb)
// 加入一个新的条目
iden, _ := component.CreateIdentifierByString("/pkuiswhat")
hop := new(NextHop)
hop.Init("tcp://1.1.1.1", 77)
rt.AddNextHop(iden, hop)
// 打印
rt.PrintSelf()
// 加入一个旧条目
hopOld := new(NextHop)
hopOld.Init("udp://1.1.1.12", 88)
rt.AddNextHop(iden, hopOld)
// 打印
rt.PrintSelf()
// 再加一遍
rt.AddNextHop(iden, hopOld)
// 打印
rt.PrintSelf()
} }
// //
// TestRoutingTable_Calculate // TestRoutingTable_calculateLsRoutingTable
// @Description: 测试计算 // @Description: 测试计算
// @param t // @param t
// //
func TestRoutingTable_Calculate(t *testing.T) { func TestRoutingTable_calculateLsRoutingTable(t *testing.T) {
// 1. 组件初始化
// 配置文件初始化
mlsrConfig, err := common.ParseConfig(testConfigPath)
if err != nil {
common2.LogInfo("配置文件解析错误")
}
// 调度器初始化
sche := new(lsdb.MlsrScheduler)
sche.Init()
// LogicFace初始化(假设初始化,暂时用不到)
face := new(logicface.LogicFace)
// LSDB初始化
mlsdb := new(lsdb.Lsdb)
mlsdb.Init(mlsrConfig, sche, face)
// 2. 打印lsdb中所有本机lsa
lsas, _ := mlsdb.LsaContainer.GetLSAsByType(lsa.LsaADJACENCYType)
for i := 0; i < len(lsas); i++ {
common2.LogInfo(lsas[i].ToString())
}
lsas, _ = mlsdb.LsaContainer.GetLSAsByType(lsa.LsaNAMEType)
for i := 0; i < len(lsas); i++ {
common2.LogInfo(lsas[i].ToString())
}
fmt.Println("lsdb是否正在忙于构建lsdb: ", mlsdb.GetIsBuildAdjLsaScheduled())
// 3. 路由表初始化
rt := new(RoutingTable)
rt.Init(mlsrConfig, sche, mlsdb)
// 安装本机adjlsa
mlsdb.BuildAndInstallOwnAdjLsa()
fmt.Println("路由表是否已经知道lsdb成功构建了邻接Lsa: ", rt.m_ownAdjLsaExist)
// 4. 安装其它路由器的邻接lsa
// 传入一些其它虚拟lsa,这些lsa与本机lsa共同形成一个小型路由拓扑
// 路由器B
adjLsaB := testCreateAdjLsa("/routerB")
adjInfoBA := testCreateAdjInfo(10, "/min/pkusz/routerA")
adjInfoBE := testCreateAdjInfo(50, "/routerE")
adjLsaB.Insert(adjInfoBA)
adjLsaB.Insert(adjInfoBE)
// 路由器C
adjLsaC := testCreateAdjLsa("/routerC")
adjInfoCA := testCreateAdjInfo(100, "/min/pkusz/routerA")
adjInfoCE := testCreateAdjInfo(10, "/routerE")
adjInfoCD := testCreateAdjInfo(60, "/routerD")
adjLsaC.Insert(adjInfoCA)
adjLsaC.Insert(adjInfoCD)
adjLsaC.Insert(adjInfoCE)
// 路由器E
adjLsaE := testCreateAdjLsa("/routerE")
adjInfoEB := testCreateAdjInfo(50, "/routerB")
adjInfoEC := testCreateAdjInfo(10, "/routerC")
adjInfoED := testCreateAdjInfo(20, "/routerD")
adjLsaE.Insert(adjInfoEB)
adjLsaE.Insert(adjInfoEC)
adjLsaE.Insert(adjInfoED)
// 路由器D
adjLsaD := testCreateAdjLsa("/routerD")
adjInfoDA := testCreateAdjInfo(30, "/min/pkusz/routerA")
adjInfoDC := testCreateAdjInfo(60, "/routerC")
adjInfoDE := testCreateAdjInfo(20, "/routerE")
adjLsaD.Insert(adjInfoDA)
adjLsaD.Insert(adjInfoDC)
adjLsaD.Insert(adjInfoDE)
mlsdb.InstallLsa(adjLsaB)
mlsdb.InstallLsa(adjLsaC)
mlsdb.InstallLsa(adjLsaD)
mlsdb.InstallLsa(adjLsaE)
// 5. 调用计算路由函数,并打印路由表
rt.calculateLsRoutingTable()
rt.PrintSelf()
} }
// //
// TestRoutingTable_ScheduleRoutingTableCalculation // TestRoutingTable_ScheduleRoutingTableCalculation
// @Description: 测试安排路由计算 // @Description: 测试安排路由计算
// 由于RT会在监听到邻接lsa改变时被直接安排做计算,因此,这里只需要等待其触发就好。触发间隔为15s。
// @param t // @param t
// //
func TestRoutingTable_ScheduleRoutingTableCalculation(t *testing.T) { func TestRoutingTable_ScheduleRoutingTableCalculation(t *testing.T) {
// 1. 组件初始化
// 配置文件初始化
mlsrConfig, err := common.ParseConfig(testConfigPath)
if err != nil {
common2.LogInfo("配置文件解析错误")
}
// 调度器初始化
sche := new(lsdb.MlsrScheduler)
sche.Init()
// LogicFace初始化(假设初始化,暂时用不到)
face := new(logicface.LogicFace)
// LSDB初始化
mlsdb := new(lsdb.Lsdb)
mlsdb.Init(mlsrConfig, sche, face)
// 2. 打印lsdb中所有本机lsa
lsas, _ := mlsdb.LsaContainer.GetLSAsByType(lsa.LsaADJACENCYType)
for i := 0; i < len(lsas); i++ {
common2.LogInfo(lsas[i].ToString())
}
lsas, _ = mlsdb.LsaContainer.GetLSAsByType(lsa.LsaNAMEType)
for i := 0; i < len(lsas); i++ {
common2.LogInfo(lsas[i].ToString())
}
fmt.Println("lsdb是否正在忙于构建lsdb: ", mlsdb.GetIsBuildAdjLsaScheduled())
// 3. 路由表初始化
rt := new(RoutingTable)
rt.Init(mlsrConfig, sche, mlsdb)
// 安装本机adjlsa
mlsdb.BuildAndInstallOwnAdjLsa()
fmt.Println("路由表是否已经知道lsdb成功构建了邻接Lsa: ", rt.m_ownAdjLsaExist)
// 4. 安装其它路由器的邻接lsa
// 传入一些其它虚拟lsa,这些lsa与本机lsa共同形成一个小型路由拓扑
// 路由器B
adjLsaB := testCreateAdjLsa("/routerB")
adjInfoBA := testCreateAdjInfo(10, "/min/pkusz/routerA")
adjInfoBE := testCreateAdjInfo(50, "/routerE")
adjLsaB.Insert(adjInfoBA)
adjLsaB.Insert(adjInfoBE)
// 路由器C
adjLsaC := testCreateAdjLsa("/routerC")
adjInfoCA := testCreateAdjInfo(100, "/min/pkusz/routerA")
adjInfoCE := testCreateAdjInfo(10, "/routerE")
adjInfoCD := testCreateAdjInfo(60, "/routerD")
adjLsaC.Insert(adjInfoCA)
adjLsaC.Insert(adjInfoCD)
adjLsaC.Insert(adjInfoCE)
// 路由器E
adjLsaE := testCreateAdjLsa("/routerE")
adjInfoEB := testCreateAdjInfo(50, "/routerB")
adjInfoEC := testCreateAdjInfo(10, "/routerC")
adjInfoED := testCreateAdjInfo(20, "/routerD")
adjLsaE.Insert(adjInfoEB)
adjLsaE.Insert(adjInfoEC)
adjLsaE.Insert(adjInfoED)
// 路由器D
adjLsaD := testCreateAdjLsa("/routerD")
adjInfoDA := testCreateAdjInfo(30, "/min/pkusz/routerA")
adjInfoDC := testCreateAdjInfo(60, "/routerC")
adjInfoDE := testCreateAdjInfo(20, "/routerE")
adjLsaD.Insert(adjInfoDA)
adjLsaD.Insert(adjInfoDC)
adjLsaD.Insert(adjInfoDE)
mlsdb.InstallLsa(adjLsaB)
mlsdb.InstallLsa(adjLsaC)
mlsdb.InstallLsa(adjLsaD)
mlsdb.InstallLsa(adjLsaE)
// 5. 只是等待。并打印路由表
for i := 0; i < 60; i++ {
time.Sleep(time.Second)
fmt.Println(i+1, " seconds later...")
rt.PrintSelf()
}
} }
+63
View File
@@ -0,0 +1,63 @@
// Package utils
// @Author: Wang Feng
// @Description:
// @Version: 0.1.0
// @Date: 2022/6/24 12:05
// @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
//
package utils
import "testing"
//
// TestSignalUsage
// @Description: 测试如何使用Signal
// @param t
//
func TestSignalUsage(t *testing.T) {
s := NewSignal()
hit1 := 0
// 等待通知,被通知后,执行此函数
func1 := func(args ...interface{}) {
hit1 += 1
num := args[0].(int)
if num != 8106 {
panic("Test two arguments failed.")
}
num1 := args[1].(int)
if num1 != 8107 {
panic("Test two arguments failed.")
}
}
// 建立执行函数与信号的联系
conn := s.Connect(func1)
// 信号发出,即通知出去
s.Emit(8106, 8107)
if hit1 != 1 {
t.Fatalf("ManualDisconnect failed.")
}
if !conn.IsConnected() {
t.Fatalf("ManualDisconnect failed.")
}
// 关闭与信号的联系
conn.Disconnect()
if conn.IsConnected() {
t.Fatalf("ManualDisconnect failed.")
}
s.Emit()
if hit1 != 1 {
t.Fatalf("ManualDisconnect failed.")
}
conn.Disconnect()
}