From 82434236e0ce0d159cd2a3932e2d1cc132852a9e Mon Sep 17 00:00:00 2001 From: zhengqi Date: Wed, 24 Aug 2022 05:10:52 -0700 Subject: [PATCH 1/9] add: new branch local --- go.mod | 2 -- lsdb/Lsdb.go | 7 ++++++- mlsrcmd/mlsr.go | 6 +++++- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 2259bbe..2e67236 100644 --- a/go.mod +++ b/go.mod @@ -4,8 +4,6 @@ go 1.17 require ( MINSync v0.0.0 - //github.com/rakanalh/scheduler v0.1 - github.com/deckarep/golang-set v1.8.0 github.com/go-co-op/gocron v1.13.0 github.com/liyue201/gostl v1.0.1 github.com/olekukonko/tablewriter v0.0.5 diff --git a/lsdb/Lsdb.go b/lsdb/Lsdb.go index c8b0883..d27e0f5 100644 --- a/lsdb/Lsdb.go +++ b/lsdb/Lsdb.go @@ -95,7 +95,12 @@ func (l *Lsdb) Init(mc *common.MlsrConfig, ms *MlsrScheduler, common2.LogFatal("lsdb.LsaContainer init error, ", err.Error()) } - // todo 构造sync + // 构造sync + // dummyClientLogicFace := + // l.sync = communication.NewSyncLogicHandler(nil, + // func(identifier *component.Identifier, lsaType lsa.LsaType, seq, incomingLogicFaceId uint64) bool { + + // },&l.mlsrConfig.MlsrConfigParameters) // lsa刷新时间 l.lsaRefreshTime = l.mlsrConfig.GetLsaRefreshTime() diff --git a/mlsrcmd/mlsr.go b/mlsrcmd/mlsr.go index 9449c83..bcc36d6 100644 --- a/mlsrcmd/mlsr.go +++ b/mlsrcmd/mlsr.go @@ -13,6 +13,7 @@ import ( "minlib/component" "minlib/logicface" "minlib/security" + utils2 "minlib/utils" "mlsr/common" "mlsr/hello" "mlsr/lsa" @@ -37,7 +38,7 @@ type Mlsr struct { m_helloProtocol *hello.HelloProtocol // 用于异步事件触发的信号量接收器 - m_onNewLsaConnection *utils.SignalConnection + m_onNewLsaConnection *utils2.Connection m_onPrefixRegistrationSuccess *utils.SignalConnection m_onInitialHelloDataValidated *utils.SignalConnection } @@ -90,6 +91,9 @@ func (m *Mlsr) Init(face *logicface.LogicFaceICN, scheduler *lsdb.MlsrScheduler, m.m_helloProtocol = new(hello.HelloProtocol) m.m_helloProtocol.Init(m.m_face, m.m_scheduler, chain, m.m_confParam, m.m_routingTable, m.m_lsdb) + // NewLSAConnection + // sync := m.m_lsdb.GetSync() + // m.m_onNewLsaConnection = m.m_lsdb. // 三个信号量接收器的触发 todo 还没实现的两个,一个与sync有关,一个与fib有关 // hello信号量接收器 bindHelloFunc := func(args ...interface{}) { From 881f3c8654b589928c7e84507aecadf81fec1f54 Mon Sep 17 00:00:00 2001 From: zhengqi Date: Thu, 25 Aug 2022 06:54:06 -0700 Subject: [PATCH 2/9] add: lsdb supplement --- hello/HelloProtocol.go | 4 +- hello/HelloProtocol_test.go | 4 +- lsa/ILsa.go | 5 +- lsdb/Lsdb.go | 138 +++++++++++++++--- lsdb/Lsdb_test.go | 12 +- mlsrcmd/mlsr.go | 6 +- route/LinkStateRoutingTableCalculator_test.go | 4 +- route/NamePrefixTable_test.go | 8 +- route/RouterMap_test.go | 2 +- route/RoutingTableCalculator_test.go | 2 +- route/RoutingTable_test.go | 8 +- 11 files changed, 146 insertions(+), 47 deletions(-) diff --git a/hello/HelloProtocol.go b/hello/HelloProtocol.go index 6c835b1..522bfc7 100644 --- a/hello/HelloProtocol.go +++ b/hello/HelloProtocol.go @@ -27,7 +27,7 @@ const INFO_COMPONENT = "INFO" const MLSR_COMPONENT = "mlsr" type HelloProtocol struct { - m_face *logicface.LogicFaceICN + m_face *logicface.DummyClientLogicFace m_scheduler *lsdb.MlsrScheduler m_keychain *security.KeyChain mlsrConfig *common.MlsrConfig @@ -53,7 +53,7 @@ type HelloProtocol struct { // @param routingTable // @param mlsdb // -func (hp *HelloProtocol) Init(face *logicface.LogicFaceICN, +func (hp *HelloProtocol) Init(face *logicface.DummyClientLogicFace, scheduler *lsdb.MlsrScheduler, keychain *security.KeyChain, mlsrConfig *common.MlsrConfig, routingTable *route.RoutingTable, mlsdb *lsdb.Lsdb) { diff --git a/hello/HelloProtocol_test.go b/hello/HelloProtocol_test.go index 5a33bfb..92a0109 100644 --- a/hello/HelloProtocol_test.go +++ b/hello/HelloProtocol_test.go @@ -37,7 +37,7 @@ func TestHelloProtocol_Init(t *testing.T) { sche := new(lsdb.MlsrScheduler) sche.Init() // LogicFace初始化(假设初始化,暂时用不到) - face := new(logicface.LogicFaceICN) + face := new(logicface.DummyClientLogicFace) keychain := new(security.KeyChain) // LSDB初始化 mlsdb := new(lsdb.Lsdb) @@ -69,7 +69,7 @@ func TestHelloProtocol_SendHelloInterest(t *testing.T) { sche := new(lsdb.MlsrScheduler) sche.Init() // LogicFace初始化(假设初始化,暂时用不到) - face := new(logicface.LogicFaceICN) + face := new(logicface.DummyClientLogicFace) keychain := new(security.KeyChain) // LSDB初始化 mlsdb := new(lsdb.Lsdb) diff --git a/lsa/ILsa.go b/lsa/ILsa.go index 1c0ba23..eb4eb55 100644 --- a/lsa/ILsa.go +++ b/lsa/ILsa.go @@ -25,14 +25,13 @@ type ILsa interface { GetType() LsaType - WireEncode(encoder *encoding.Encoder) (int,error) + WireEncode(encoder *encoding.Encoder) (int, error) WireDecode(block *encoding.Block) error // 转string ToString() string // JsonString <=> Lsa - GetJsonString() ([]byte,error) + GetJsonString() ([]byte, error) LoadFromJsonString(jsonBytes []byte) error - } diff --git a/lsdb/Lsdb.go b/lsdb/Lsdb.go index d27e0f5..a34842c 100644 --- a/lsdb/Lsdb.go +++ b/lsdb/Lsdb.go @@ -14,14 +14,18 @@ import ( "bytes" common2 "minlib/common" "minlib/component" + mencoding "minlib/encoding" "minlib/logicface" "minlib/packet" + mutil "minlib/utils" "mlsr/common" "mlsr/communication" "mlsr/lsa" "mlsr/lsdb/LsaContainer" "mlsr/utils" "time" + + "github.com/liyue201/gostl/ds/set" ) type LsdbUpdate int @@ -33,6 +37,12 @@ const ( REMOVED LsdbUpdate = -1 // 移除 ) +const ( + LSA_REFRESH_TIME_MIN = 240 + LSA_REFRESH_TIME_DEFAULT = 1800 + LSA_REFRESH_TIME_MAX = 7200 +) + const GRACE_PERIOD = 10 * time.Second // 超期宽限期。LSA比设定时间晚几秒钟被删除,以避免信息过早失效。 type Lsdb struct { @@ -52,7 +62,7 @@ type Lsdb struct { // 任务调度器 scheduler *MlsrScheduler // LogicFace接口 - face *logicface.LogicFaceICN + face *logicface.DummyClientLogicFace // 将LSA的名称从sync映射到其已知的最高序列号; // 用于阻止MLSR尝试获取过时的LSA @@ -60,14 +70,15 @@ type Lsdb struct { // 不同类型lsa的序列号管理器 sequencingManager *SequencingManager - // todo 信号接收器: - m_onNewLsaConnection *utils.SignalConnection + // 信号接收器 + m_onNewLsaConnection *mutil.Connection - // todo 分片获取器、分片发送器 - m_fetchers *MINSync.FragmentFetcher + // 分片获取器、分片发送器 + m_fetchers *set.MultiSet m_segmentPublisher *MINSync.FragmentPublisher - // todo InMemoryStoragePersistent + // InMemoryStoragePersistent -> MINSync.InMemoryStorage + m_lsaStorage *MINSync.InMemoryStorage isBuildAdjLsaScheduled bool // 是否安排构建邻接LSA adjBuildCount uint64 // 邻接LSA的构建的统计数目 @@ -77,7 +88,7 @@ type Lsdb struct { } func (l *Lsdb) Init(mc *common.MlsrConfig, ms *MlsrScheduler, - _face *logicface.LogicFaceICN) { + _face *logicface.DummyClientLogicFace) { // 信号初始化 l.OnLsdbModified = utils.NewSignal() @@ -95,13 +106,87 @@ func (l *Lsdb) Init(mc *common.MlsrConfig, ms *MlsrScheduler, common2.LogFatal("lsdb.LsaContainer init error, ", err.Error()) } + // highestSeqNo + l.highestSeqNo = make(map[*component.Identifier]uint64) + // 构造sync - // dummyClientLogicFace := - // l.sync = communication.NewSyncLogicHandler(nil, - // func(identifier *component.Identifier, lsaType lsa.LsaType, seq, incomingLogicFaceId uint64) bool { + dummyClientLogicFace := logicface.NewDummyClientLogicFaceByOptions("dummy://face0", "", + logicface.NewDummyClientOptionsByParams(true, true)) - // },&l.mlsrConfig.MlsrConfigParameters) + if mc == nil { + common2.LogFatal("lsdb.SyncLogicHandler init error, config ptr is nil") + } + l.sync, err = communication.NewSyncLogicHandler(dummyClientLogicFace, func(routerName *component.Identifier, lsaType lsa.LsaType, seq, incomingLogicFaceId uint64) bool { + return l.isLsaNew(routerName, lsaType, seq) + }, &mc.MlsrConfigParameters) + if err != nil { + common2.LogFatal("lsdb.SyncLogicHandler init error, ", err.Error()) + } + // m_onNewLsaConnection + l.m_onNewLsaConnection = l.sync.OnNewLsa.Connect(func(args ...interface{}) { + var updateName, originRouter *component.Identifier + var seq, incomingLogicFaceId uint64 + var ok bool + + if args[0] != nil { + updateName, ok = args[0].(*component.Identifier) + if !ok { + common2.LogError("updateName conversion failed.") + return + } + } + + if args[1] != nil { + seq, ok = args[1].(uint64) + if !ok { + common2.LogError("seq conversion failed.") + return + } + } + + if args[2] != nil { + originRouter, ok = args[2].(*component.Identifier) + if !ok { + common2.LogError("originRouter conversion failed.") + return + } + common2.LogDebug("originRouter: ", originRouter.ToUri()) + } + + if args[3] != nil { + incomingLogicFaceId, ok = args[3].(uint64) + if !ok { + common2.LogError("incomingLogicFaceId conversion failed.") + return + } + } + + updateNameBlockForCopy, err := updateName.SelfWireEncode(updateName) + if err != nil { + common2.LogError("self encoding error: ", err.Error()) + return + } + + lsaInterestName, err := component.NewIdentifierByBlock(updateNameBlockForCopy) + if err != nil { + common2.LogError("create identifier error: ", err.Error()) + return + } + + lsaInterestName.Append(component.CreateIdentifierComponentByNonNegativeInteger(seq)) + // deadline + l.ExpressInterest(lsaInterestName, 0, uint32(incomingLogicFaceId), time.Now()) + + }) + + // lsaStorage + l.m_lsaStorage = MINSync.NewInMemoryStorage(100) + + // 分片获取器set + l.m_fetchers = set.NewMultiSet(set.WithGoroutineSafe()) + // 分片发送器 + l.m_segmentPublisher = MINSync.NewFragmentPublisher(l.face, 100) // lsa刷新时间 l.lsaRefreshTime = l.mlsrConfig.GetLsaRefreshTime() // 邻接lsa构建间隔 @@ -170,8 +255,9 @@ func (l *Lsdb) BuildAndInstallOwnNameLsa() { // 刷新序列号管理器中的名称LSA序列号 l.sequencingManager.IncreaseNameLsaSeq() - // todo: 使用sync通知路由更新 + // 使用sync通知路由更新 // m_sync.publishRoutingUpdate(Lsa::Type::NAME, m_sequencingManager.getNameLsaSeq()); + l.sync.PublishRoutingUpdate(lsa.LsaNAMEType, l.sequencingManager.nameLsaSeq) // 安装lsa到LSDB l.InstallLsa(nlsa) @@ -258,8 +344,9 @@ func (l *Lsdb) ProcessInterest(interest *packet.Interest) { // 处理该lsa请求 l.processInterestForLsa(interest, originRouter, lsa.LsaType(lsatype), seq) - } else { - // todo 查找m_lsaStorage.find(interest),看是否有该兴趣包对应的Data包 + } else if data := l.m_lsaStorage.FindByInterest(interest); data != nil { + // 查找m_lsaStorage.find(interest),看是否有该兴趣包对应的Data包 + l.face.PutData(data) } } @@ -281,8 +368,16 @@ func (l *Lsdb) processInterestForLsa(interest *packet.Interest, if glsa != nil { common2.LogDebug("Lsdb processInterestForLsa ", interest.ToUri(), " ", lsaType, " success.") if seqNo == glsa.GetSeqNo() { - // todo 使用段发布器将该lsa发布给该interest的发送者 + // encode glsa + glsaBlock, err := mencoding.EasyEncoder(glsa) + if err != nil { + common2.LogError("glsa encoding error: ", err.Error()) + return false + } + // 使用段发布器将该lsa发布给该interest的发送者 // m_segmentPublisher.publish(interest.getName(), interest.getName(), lsaPtr->wireEncode(), + l.m_segmentPublisher.PublishBlock(interest.GetName(), interest.GetName(), + glsaBlock, l.lsaRefreshTime) return true } } else { @@ -598,9 +693,9 @@ func (l *Lsdb) BuildAndInstallOwnAdjLsa() { // 刷新序列号管理器中的名称LSA序列号 l.sequencingManager.IncreaseAdjLsaSeq() - // todo: 使用sync通知路由更新 + // 使用sync通知路由更新 // m_sync.publishRoutingUpdate(Lsa::Type::ADJACENCY, m_sequencingManager.getAdjLsaSeq()); - + l.sync.PublishRoutingUpdate(lsa.LsaADJACENCYType, l.sequencingManager.adjLsaSeq) // 安装lsa到LSDB l.InstallLsa(adjLsa) } @@ -651,8 +746,9 @@ func (l *Lsdb) ExpireOrRefreshLsa(lsa lsa.ILsa) { common2.LogDebug("Own lsa refreshed, ", lsaInDb.ToString()) // 2. 安排新的超期事件 l.ScheduleLsaExpiration(lsaInDb, l.lsaRefreshTime) - // 3. todo: 将lsa更新通知给sync + // 3. 将lsa更新通知给sync // m_sync.publishRoutingUpdate(lsaPtr->getType(), m_sequencingManager.getLsaSeq(lsaPtr->getType())); + l.sync.PublishRoutingUpdate(lsaInDb.GetType(), lsaInDb.GetSeqNo()) } else { // 如果是其他路由器的LSA,我们将删除它。 // 更新其他路由器的LSA是通过min-sync实现的,而不是超期触发。 @@ -669,10 +765,14 @@ func (l *Lsdb) ExpireOrRefreshLsa(lsa lsa.ILsa) { // @receiver l // @param interestName // @param timeOut +// @param incomingFaceId // @param deadline // func (l *Lsdb) ExpressInterest(interestName *component.Identifier, - timeOut uint32, deadline *time.Time) { + timeOut, incomingFaceId uint32, deadline time.Time) { + deadline = deadline.Add(LSA_REFRESH_TIME_MAX * time.Second) + + lsaName := } // diff --git a/lsdb/Lsdb_test.go b/lsdb/Lsdb_test.go index 1246ab9..3b9dc6d 100644 --- a/lsdb/Lsdb_test.go +++ b/lsdb/Lsdb_test.go @@ -38,7 +38,7 @@ func TestLsdb_Init(t *testing.T) { sche := new(MlsrScheduler) sche.Init() // LogicFace初始化(假设初始化,暂时用不到) - face := new(logicface.LogicFaceICN) + face := new(logicface.DummyClientLogicFace) // LSDB初始化 lsdb := new(Lsdb) lsdb.Init(mlsrConfig, sche, face) @@ -59,7 +59,7 @@ func TestUnixTime(t *testing.T) { sche := new(MlsrScheduler) sche.Init() // LogicFace初始化(假设初始化,暂时用不到) - face := new(logicface.LogicFaceICN) + face := new(logicface.DummyClientLogicFace) // LSDB初始化 lsdb := new(Lsdb) lsdb.Init(mlsrConfig, sche, face) @@ -87,7 +87,7 @@ func TestLsdb_ScheduleLsaExpiration(t *testing.T) { sche := new(MlsrScheduler) sche.Init() // LogicFace初始化(假设初始化,暂时用不到) - face := new(logicface.LogicFaceICN) + face := new(logicface.DummyClientLogicFace) // LSDB初始化 lsdb := new(Lsdb) lsdb.Init(mlsrConfig, sche, face) @@ -151,7 +151,7 @@ func TestLsab_InstallLsa(t *testing.T) { sche := new(MlsrScheduler) sche.Init() // LogicFace初始化(假设初始化,暂时用不到) - face := new(logicface.LogicFaceICN) + face := new(logicface.DummyClientLogicFace) // LSDB初始化 lsdb := new(Lsdb) lsdb.Init(mlsrConfig, sche, face) @@ -210,7 +210,7 @@ func TestName_BuildAndInstallAdjLsa(t *testing.T) { sche := new(MlsrScheduler) sche.Init() // LogicFace初始化(假设初始化,暂时用不到) - face := new(logicface.LogicFaceICN) + face := new(logicface.DummyClientLogicFace) // LSDB初始化 mlsdb := new(Lsdb) mlsdb.Init(mlsrConfig, sche, face) @@ -245,7 +245,7 @@ func TestLsdb_InstallLsa_ScheduleAdjLsaBuild(t *testing.T) { sche := new(MlsrScheduler) sche.Init() // LogicFace初始化(假设初始化,暂时用不到) - face := new(logicface.LogicFaceICN) + face := new(logicface.DummyClientLogicFace) // LSDB初始化 lsdb := new(Lsdb) lsdb.Init(mlsrConfig, sche, face) diff --git a/mlsrcmd/mlsr.go b/mlsrcmd/mlsr.go index bcc36d6..3697503 100644 --- a/mlsrcmd/mlsr.go +++ b/mlsrcmd/mlsr.go @@ -25,7 +25,7 @@ import ( type Mlsr struct { LOCALHOST_PREFIX *component.Identifier - m_face *logicface.LogicFaceICN + m_face *logicface.DummyClientLogicFace m_scheduler *lsdb.MlsrScheduler m_confParam *common.MlsrConfig m_adjacencyList *lsa.AdjLsaAdjacenctList @@ -53,7 +53,7 @@ type Mlsr struct { // @param chain // @param confParam // -func (m *Mlsr) Init(face *logicface.LogicFaceICN, scheduler *lsdb.MlsrScheduler, +func (m *Mlsr) Init(face *logicface.DummyClientLogicFace, scheduler *lsdb.MlsrScheduler, passwd string, chain *security.KeyChain, confParam *common.MlsrConfig) { common2.LogDebug("Initializing Mlsr") @@ -103,7 +103,7 @@ func (m *Mlsr) Init(face *logicface.LogicFaceICN, scheduler *lsdb.MlsrScheduler, // 查看本机是否已知道此路由器 adjInfo := m.m_adjacencyList.FindAdjacencyByRouterIdentifier(neighbor) if adjInfo != nil { - // 在fib中注册该前缀 + // todo: 在fib中注册该前缀 // m_fib.registerPrefix(m_confParam.getSyncPrefix(), it->getFaceUri(), it->getLinkCost(), // ndn::time::milliseconds::max(), ndn::nfd::ROUTE_FLAG_CAPTURE, 0); } diff --git a/route/LinkStateRoutingTableCalculator_test.go b/route/LinkStateRoutingTableCalculator_test.go index efe66ef..fdc816e 100644 --- a/route/LinkStateRoutingTableCalculator_test.go +++ b/route/LinkStateRoutingTableCalculator_test.go @@ -75,7 +75,7 @@ func TestLinkStateRoutingTableCalculator_CalculateOnePath(t *testing.T) { sche := new(lsdb.MlsrScheduler) sche.Init() // LogicFace初始化(假设初始化,暂时用不到) - face := new(logicface.LogicFaceICN) + face := new(logicface.DummyClientLogicFace) // LSDB初始化 mlsdb := new(lsdb.Lsdb) mlsdb.Init(mlsrConfig, sche, face) @@ -185,7 +185,7 @@ func TestLinkStateRoutingTableCalculator_CalculateMutilPath(t *testing.T) { sche := new(lsdb.MlsrScheduler) sche.Init() // LogicFace初始化(假设初始化,暂时用不到) - face := new(logicface.LogicFaceICN) + face := new(logicface.DummyClientLogicFace) // LSDB初始化 mlsdb := new(lsdb.Lsdb) mlsdb.Init(mlsrConfig, sche, face) diff --git a/route/NamePrefixTable_test.go b/route/NamePrefixTable_test.go index 60c8d6a..3ce7f12 100644 --- a/route/NamePrefixTable_test.go +++ b/route/NamePrefixTable_test.go @@ -41,7 +41,7 @@ func TestNamePrefixTable_FinalTest(t *testing.T) { sche := new(lsdb.MlsrScheduler) sche.Init() // LogicFace初始化(假设初始化,暂时用不到) - face := new(logicface.LogicFaceICN) + face := new(logicface.DummyClientLogicFace) // LSDB初始化 mlsdb := new(lsdb.Lsdb) mlsdb.Init(mlsrConfig, sche, face) @@ -131,7 +131,7 @@ func TestNamePrefixTable_AddEntryAndRemoveEntry(t *testing.T) { sche := new(lsdb.MlsrScheduler) sche.Init() // LogicFace初始化(假设初始化,暂时用不到) - face := new(logicface.LogicFaceICN) + face := new(logicface.DummyClientLogicFace) // LSDB初始化 mlsdb := new(lsdb.Lsdb) mlsdb.Init(mlsrConfig, sche, face) @@ -257,7 +257,7 @@ func TestNamePrefixTable_UpdateFromLsdb(t *testing.T) { sche := new(lsdb.MlsrScheduler) sche.Init() // LogicFace初始化(假设初始化,暂时用不到) - face := new(logicface.LogicFaceICN) + face := new(logicface.DummyClientLogicFace) // LSDB初始化 mlsdb := new(lsdb.Lsdb) mlsdb.Init(mlsrConfig, sche, face) @@ -392,7 +392,7 @@ func TestNamePrefixTable_UpdateWithNewRoute(t *testing.T) { sche := new(lsdb.MlsrScheduler) sche.Init() // LogicFace初始化(假设初始化,暂时用不到) - face := new(logicface.LogicFaceICN) + face := new(logicface.DummyClientLogicFace) // LSDB初始化 mlsdb := new(lsdb.Lsdb) mlsdb.Init(mlsrConfig, sche, face) diff --git a/route/RouterMap_test.go b/route/RouterMap_test.go index 9fce9d9..2940128 100644 --- a/route/RouterMap_test.go +++ b/route/RouterMap_test.go @@ -32,7 +32,7 @@ func TestRouterMap_CreateFromAdjLsdb(t *testing.T) { sche := new(lsdb.MlsrScheduler) sche.Init() // LogicFace初始化(假设初始化,暂时用不到) - face := new(logicface.LogicFaceICN) + face := new(logicface.DummyClientLogicFace) // LSDB初始化 lsdb := new(lsdb.Lsdb) lsdb.Init(mlsrConfig, sche, face) diff --git a/route/RoutingTableCalculator_test.go b/route/RoutingTableCalculator_test.go index cd7fe09..0af76dc 100644 --- a/route/RoutingTableCalculator_test.go +++ b/route/RoutingTableCalculator_test.go @@ -33,7 +33,7 @@ func TestRoutingTableCalculator_Init(t *testing.T) { sche := new(lsdb.MlsrScheduler) sche.Init() // LogicFace初始化(假设初始化,暂时用不到) - face := new(logicface.LogicFaceICN) + face := new(logicface.DummyClientLogicFace) // LSDB初始化 mlsdb := new(lsdb.Lsdb) mlsdb.Init(mlsrConfig, sche, face) diff --git a/route/RoutingTable_test.go b/route/RoutingTable_test.go index d30ad45..b22dad7 100644 --- a/route/RoutingTable_test.go +++ b/route/RoutingTable_test.go @@ -36,7 +36,7 @@ func TestRoutingTable_Init(t *testing.T) { sche := new(lsdb.MlsrScheduler) sche.Init() // LogicFace初始化(假设初始化,暂时用不到) - face := new(logicface.LogicFaceICN) + face := new(logicface.DummyClientLogicFace) // LSDB初始化 mlsdb := new(lsdb.Lsdb) mlsdb.Init(mlsrConfig, sche, face) @@ -62,7 +62,7 @@ func TestRoutingTable_AddNextHop(t *testing.T) { sche := new(lsdb.MlsrScheduler) sche.Init() // LogicFace初始化(假设初始化,暂时用不到) - face := new(logicface.LogicFaceICN) + face := new(logicface.DummyClientLogicFace) // LSDB初始化 mlsdb := new(lsdb.Lsdb) mlsdb.Init(mlsrConfig, sche, face) @@ -120,7 +120,7 @@ func TestRoutingTable_calculateLsRoutingTable(t *testing.T) { sche := new(lsdb.MlsrScheduler) sche.Init() // LogicFace初始化(假设初始化,暂时用不到) - face := new(logicface.LogicFaceICN) + face := new(logicface.DummyClientLogicFace) // LSDB初始化 mlsdb := new(lsdb.Lsdb) mlsdb.Init(mlsrConfig, sche, face) @@ -204,7 +204,7 @@ func TestRoutingTable_ScheduleRoutingTableCalculation(t *testing.T) { sche := new(lsdb.MlsrScheduler) sche.Init() // LogicFace初始化(假设初始化,暂时用不到) - face := new(logicface.LogicFaceICN) + face := new(logicface.DummyClientLogicFace) // LSDB初始化 mlsdb := new(lsdb.Lsdb) mlsdb.Init(mlsrConfig, sche, face) From 582436943b1578c1d098d84dbcb8ba4a9251e11a Mon Sep 17 00:00:00 2001 From: zhengqi Date: Thu, 25 Aug 2022 07:12:38 -0700 Subject: [PATCH 3/9] add: lsdb supplement --- lsdb/Lsdb.go | 54 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/lsdb/Lsdb.go b/lsdb/Lsdb.go index a34842c..18fa8f4 100644 --- a/lsdb/Lsdb.go +++ b/lsdb/Lsdb.go @@ -66,7 +66,7 @@ type Lsdb struct { // 将LSA的名称从sync映射到其已知的最高序列号; // 用于阻止MLSR尝试获取过时的LSA - highestSeqNo map[*component.Identifier]uint64 + highestSeqNo map[string]uint64 // 不同类型lsa的序列号管理器 sequencingManager *SequencingManager @@ -107,7 +107,7 @@ func (l *Lsdb) Init(mc *common.MlsrConfig, ms *MlsrScheduler, } // highestSeqNo - l.highestSeqNo = make(map[*component.Identifier]uint64) + l.highestSeqNo = make(map[string]uint64) // 构造sync dummyClientLogicFace := logicface.NewDummyClientLogicFaceByOptions("dummy://face0", "", @@ -772,7 +772,55 @@ func (l *Lsdb) ExpressInterest(interestName *component.Identifier, timeOut, incomingFaceId uint32, deadline time.Time) { deadline = deadline.Add(LSA_REFRESH_TIME_MAX * time.Second) - lsaName := + lsaName, err := interestName.GetSubIdentifier(0, interestName.Size()-1) + if err != nil { + common2.LogError("lsaName error: ", err.Error()) + return + } + + seqNoComponent, err := interestName.Get(-1) + if err != nil { + common2.LogError("seqNo error: ", err.Error()) + return + } + + seqNo := seqNoComponent.GetNonNegativeInteger() + + lsaNameUri := lsaName.ToUri() + if v, ok := l.highestSeqNo[lsaNameUri]; !ok { + l.highestSeqNo[lsaNameUri] = seqNo + } else if seqNo > v { + l.highestSeqNo[lsaNameUri] = seqNo + } else { + // Otherwise, its an old/invalid LSA + common2.LogWarn("old/invalid LSA ", lsaNameUri, " seq: ", seqNo) + return + } + + interest := packet.NewInterestByName(interestName) + + options := MINSync.NewFetcherOptions() + options.InterestLifetime = l.mlsrConfig.GetLsaInterestLifetime() + options.MaxTimeout = l.mlsrConfig.GetLsaInterestLifetime() + + fetcher := MINSync.Start(l.face, interest, options) + if fetcher == nil { + common2.LogError("cannot fetch lsa, quit.") + return + } + + l.m_fetchers.Insert(fetcher) + fetcher.AfterFragmentValidated.Connect(func(i ...interface{}) { + + }) + + fetcher.OnComplete.Connect(func(i ...interface{}) { + + }) + + fetcher.OnError.Connect(func(i ...interface{}) { + + }) } // From 62f63d4bf0bb48e942804fcabde76fbf46fbabfc Mon Sep 17 00:00:00 2001 From: zhengqi <709030194@qq.com> Date: Fri, 26 Aug 2022 17:10:57 +0800 Subject: [PATCH 4/9] add: lsdb supplement --- lsa/CoordinateLsa.go | 10 +- lsdb/Lsdb.go | 261 ++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 251 insertions(+), 20 deletions(-) diff --git a/lsa/CoordinateLsa.go b/lsa/CoordinateLsa.go index 2fb5738..6e984be 100644 --- a/lsa/CoordinateLsa.go +++ b/lsa/CoordinateLsa.go @@ -10,8 +10,8 @@ package lsa import "minlib/encoding" -type HyperbolicRadius float64 // 双曲半径 -type HyperbolicAngles []float64 // 双曲角度 +type HyperbolicRadius float64 // 双曲半径 +type HyperbolicAngles []float64 // 双曲角度 // // CoordinateLsa @@ -37,12 +37,12 @@ func (c *CoordinateLsa) ToString() string { return "" } -func (c *CoordinateLsa) WireEncode(encoder *encoding.Encoder) (int,error) { +func (c *CoordinateLsa) WireEncode(encoder *encoding.Encoder) (int, error) { // todo - return 0,nil + return 0, nil } func (c *CoordinateLsa) WireDecode(block *encoding.Block) error { // todo return nil -} \ No newline at end of file +} diff --git a/lsdb/Lsdb.go b/lsdb/Lsdb.go index 18fa8f4..f6663ad 100644 --- a/lsdb/Lsdb.go +++ b/lsdb/Lsdb.go @@ -1,5 +1,5 @@ // Package lsdb -// @Author: Wang Feng +// @Author: Wang Feng/zhengqi Wu // @Description: // Set的用法:https://www.jianshu.com/p/fee89fbb5f27 // @Version: 0.1.0 @@ -11,7 +11,6 @@ package lsdb import ( "MINSync" - "bytes" common2 "minlib/common" "minlib/component" mencoding "minlib/encoding" @@ -23,6 +22,8 @@ import ( "mlsr/lsa" "mlsr/lsdb/LsaContainer" "mlsr/utils" + "strconv" + "sync" "time" "github.com/liyue201/gostl/ds/set" @@ -66,7 +67,7 @@ type Lsdb struct { // 将LSA的名称从sync映射到其已知的最高序列号; // 用于阻止MLSR尝试获取过时的LSA - highestSeqNo map[string]uint64 + highestSeqNo sync.Map // 不同类型lsa的序列号管理器 sequencingManager *SequencingManager @@ -107,7 +108,7 @@ func (l *Lsdb) Init(mc *common.MlsrConfig, ms *MlsrScheduler, } // highestSeqNo - l.highestSeqNo = make(map[string]uint64) + // l.highestSeqNo = make(map[string]uint64) // 构造sync dummyClientLogicFace := logicface.NewDummyClientLogicFaceByOptions("dummy://face0", "", @@ -125,6 +126,11 @@ func (l *Lsdb) Init(mc *common.MlsrConfig, ms *MlsrScheduler, // m_onNewLsaConnection l.m_onNewLsaConnection = l.sync.OnNewLsa.Connect(func(args ...interface{}) { + if args == nil || len(args) < 4 { + common2.LogError("invalid arg list") + return + } + var updateName, originRouter *component.Identifier var seq, incomingLogicFaceId uint64 var ok bool @@ -769,7 +775,7 @@ func (l *Lsdb) ExpireOrRefreshLsa(lsa lsa.ILsa) { // @param deadline // func (l *Lsdb) ExpressInterest(interestName *component.Identifier, - timeOut, incomingFaceId uint32, deadline time.Time) { + timeOutCount, incomingFaceId uint32, deadline time.Time) { deadline = deadline.Add(LSA_REFRESH_TIME_MAX * time.Second) lsaName, err := interestName.GetSubIdentifier(0, interestName.Size()-1) @@ -787,10 +793,10 @@ func (l *Lsdb) ExpressInterest(interestName *component.Identifier, seqNo := seqNoComponent.GetNonNegativeInteger() lsaNameUri := lsaName.ToUri() - if v, ok := l.highestSeqNo[lsaNameUri]; !ok { - l.highestSeqNo[lsaNameUri] = seqNo - } else if seqNo > v { - l.highestSeqNo[lsaNameUri] = seqNo + if v, ok := l.highestSeqNo.Load(lsaNameUri); !ok { + l.highestSeqNo.Store(lsaNameUri, seqNo) + } else if seqNo > v.(uint64) { + l.highestSeqNo.Store(lsaNameUri, seqNo) } else { // Otherwise, its an old/invalid LSA common2.LogWarn("old/invalid LSA ", lsaNameUri, " seq: ", seqNo) @@ -810,16 +816,106 @@ func (l *Lsdb) ExpressInterest(interestName *component.Identifier, } l.m_fetchers.Insert(fetcher) - fetcher.AfterFragmentValidated.Connect(func(i ...interface{}) { + fetcher.AfterFragmentValidated.Connect(func(args ...interface{}) { + if args == nil || len(args) != 1 { + common2.LogError("invalid arg list") + return + } + // 解析data参数 + var data *packet.Data + var ok bool + if args[0] != nil { + data, ok = args[0].(*packet.Data) + if !ok { + common2.LogError("data conversion failed.") + return + } + } + // 插入内存数据库 + l.m_lsaStorage.Insert(data, MINSync.INFINITEWINDOW) + // 计划删除该分片 + fragmentName := data.GetName() + job, err := l.scheduler.ScheduleTaskAfterDuration(LSA_REFRESH_TIME_DEFAULT*time.Second, 1).Do(func(fragmentName *component.Identifier) { + l.m_lsaStorage.Erase(fragmentName, false) + }, fragmentName) + if err != nil { + common2.LogError("deletion scheduling error: ", err.Error()) + return + } + job.LimitRunsTo(1) + // 开始调度 + l.scheduler.StartAsync() }) - fetcher.OnComplete.Connect(func(i ...interface{}) { + fetcher.OnComplete.Connect(func(args ...interface{}) { + if args == nil || len(args) != 1 { + common2.LogError("invalid arg list") + return + } + // 解析buffer参数 + var buffer []byte + var ok bool + if args[0] != nil { + buffer, ok = args[0].([]byte) + if !ok { + common2.LogError("buffer conversion failed.") + return + } + } + // 从内存数据库中移除该lsa + lsaNameBlockForCopy, err := lsaName.SelfWireEncode(lsaName) + if err != nil { + common2.LogError("lsaName encode failed: ", err.Error()) + return + } + lsaNameCopy, err := component.NewIdentifierByBlock(lsaNameBlockForCopy) + if err != nil { + common2.LogError("new identifier failed: ", err.Error()) + return + } + lsaNameCopy.Append(component.CreateIdentifierComponentByNonNegativeInteger(seqNo - 1)) + l.m_lsaStorage.Erase(lsaNameCopy, false) + + // 从fetchers中移除该fetcher + l.m_fetchers.Erase(fetcher) + + // 将收到的数据传递给afterFetchLsa + l.afterFetchLsa(buffer, interestName) }) - fetcher.OnError.Connect(func(i ...interface{}) { + fetcher.OnError.Connect(func(args ...interface{}) { + if args == nil || len(args) != 2 { + common2.LogError("invalid arg list") + return + } + // 解析参数 + var errCode MINSync.ErrorCode + var msg string + var ok bool + + if args[0] != nil { + errCode, ok = args[0].(MINSync.ErrorCode) + if !ok { + common2.LogError("ErrorCode conversion failed.") + return + } + } + + if args[1] != nil { + msg, ok = args[1].(string) + if !ok { + common2.LogError("msg conversion failed.") + return + } + } + + // 调用onFetchLsaError + l.onFetchLsaError(errCode, msg, interestName, timeOutCount, deadline, lsaName, seqNo) + // 从fetchers中移除该fetcher + l.m_fetchers.Erase(fetcher) }) } @@ -835,9 +931,26 @@ func (l *Lsdb) ExpressInterest(interestName *component.Identifier, // @param lsaName // @param seqNo // -func (l *Lsdb) onFetchLsaError(errorCode uint32, msg string, +func (l *Lsdb) onFetchLsaError(errorCode MINSync.ErrorCode, msg string, interestName *component.Identifier, retransmitNo uint32, - deadline *time.Time, lsaName *component.Identifier, seqNo uint64) { + deadline time.Time, lsaName *component.Identifier, seqNo uint64) { + common2.LogDebug("Failed to fetch LSA: ", lsaName, ", Error Code: ", errorCode, ", Message: ", msg) + + if time.Now().Before(deadline) { + delay := l.mlsrConfig.GetLsaInterestLifetime() + if errorCode == MINSync.INTEREST_TIMEOUT { + delay = 0 * time.Second + } + // 调度LSA兴趣包重传任务 + job, err := l.scheduler.ScheduleTaskAfterDuration(delay, 1).Do(l.ExpressInterest, interestName, retransmitNo+1, 0, deadline) + if err != nil { + common2.LogError("retransimission scheduling error: ", err.Error()) + return + } + job.LimitRunsTo(1) + // 开始调度 + l.scheduler.StartAsync() + } } // @@ -849,7 +962,125 @@ func (l *Lsdb) onFetchLsaError(errorCode uint32, msg string, // @param buffer // @param interestName // -func (l *Lsdb) afterFetchLsa(buffer bytes.Buffer, interestName *component.Identifier) { +func (l *Lsdb) afterFetchLsa(buffer []byte, interestName *component.Identifier) { + common2.LogDebug("Received data for LSA interest: ", interestName.ToUri()) + + // 解析lsaName + lsaName, err := interestName.GetSubIdentifier(0, interestName.Size()-1) + if err != nil { + common2.LogError("lsaName error: ", err.Error()) + return + } + + // 解析seqNo + seqNoComponent, err := interestName.Get(-1) + if err != nil { + common2.LogError("seqNo error: ", err.Error()) + return + } + seqNo := seqNoComponent.GetNonNegativeInteger() + + // 更新highestSeqNo + lsaNameUri := lsaName.ToUri() + if v, ok := l.highestSeqNo.Load(lsaNameUri); !ok { + l.highestSeqNo.Store(lsaNameUri, seqNo) + } else if seqNo > v.(uint64) { + l.highestSeqNo.Store(lsaNameUri, seqNo) + } else { + // Otherwise, its an old/invalid LSA + common2.LogWarn("old/invalid LSA ", lsaNameUri, " seq: ", seqNo) + return + } + + chkString := "LSA" + lsaPosition := utils.GetNameComponentPosition(interestName, chkString) + + // 提取LSA类型并Install + if lsaPosition >= 0 { + // 复制originRouter + originRouter := l.mlsrConfig.GetNetwork() + originRouterBlockForCopy, err := originRouter.SelfWireEncode(originRouter) + if err != nil { + common2.LogError("originRouter encoding failed.") + return + } + originRouterCopy, err := component.NewIdentifierByBlock(originRouterBlockForCopy) + if err != nil { + common2.LogError("new identifier failed: ", err.Error()) + return + } + + // 复制subInterestName + interestNameBlockForCopy, err := interestName.SelfWireEncode(interestName) + if err != nil { + common2.LogError("interestName encoding failed: ", err.Error()) + return + } + interestNameCopy, err := component.NewIdentifierByBlock(interestNameBlockForCopy) + subInterestName, err := interestNameCopy.GetSubIdentifier(lsaPosition+1, interestNameCopy.Size()-lsaPosition-3) + if err != nil { + common2.LogError("get sub identifier failed: ", err.Error()) + return + } + + // 将subInterestName 附加到 originRouter + for _, comp := range subInterestName.GetComponents() { + originRouterCopy.Append(comp) + } + + // 获取LsaType组件 + lsTypeComponent, err := interestName.Get(-2) + if err != nil { + common2.LogError("get lsa type component failed: ", err.Error()) + return + } + + // 解析LsaType + interestLsTypeInInt, err := strconv.Atoi(lsTypeComponent.ToUri()) + if err != nil { + common2.LogError("Atoi failed: ", err.Error()) + return + } + + interestLsType := lsa.LsaType(interestLsTypeInInt) + + if interestLsType == lsa.LsaBaseType { + common2.LogError("Received Unsupported LSA Type: ", interestLsType) + return + } + + block, err := mencoding.CreateBlockByBuffer(buffer, true) + if err != nil { + common2.LogError("Create Block failed: ", err.Error()) + return + } + + if interestLsType == lsa.LsaNAMEType { + if l.isLsaNew(originRouterCopy, interestLsType, seqNo) { + nameLsa := new(lsa.NameLsa) + err = nameLsa.WireDecode(block) + if err != nil { + common2.LogError("name lsa decode failed: ", err.Error()) + return + } + l.InstallLsa(nameLsa) + } + } else if interestLsType == lsa.LsaADJACENCYType { + if l.isLsaNew(originRouterCopy, interestLsType, seqNo) { + adjLsa := new(lsa.AdjLsa) + err = adjLsa.WireDecode(block) + if err != nil { + common2.LogError("adj lsa decode failed: ", err.Error()) + return + } + l.InstallLsa(adjLsa) + } + } else if interestLsType == lsa.LsaCOORDINATEType { + if l.isLsaNew(originRouterCopy, interestLsType, seqNo) { + panic("implement me") + } + } + } } func (l *Lsdb) getLsaExpirationTimePoint() uint64 { From 34a4796ebe0402c1a70e2b1a3587081a185683a4 Mon Sep 17 00:00:00 2001 From: zhengqi <709030194@qq.com> Date: Fri, 26 Aug 2022 17:50:15 +0800 Subject: [PATCH 5/9] add: fib supplement --- mir/FibCodeCaller.go | 51 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/mir/FibCodeCaller.go b/mir/FibCodeCaller.go index dfde75e..b1276c5 100644 --- a/mir/FibCodeCaller.go +++ b/mir/FibCodeCaller.go @@ -19,6 +19,7 @@ import ( "minlib/logicface" "minlib/mgmt" "minlib/security" + "mlsr/route" ) // 一些关于MIR的默认信息。todo 后期应完善到配置文件中,从配置文件中进行读取。 @@ -69,6 +70,48 @@ type FibCodeCaller struct { keyChain *security.KeyChain } +////////////////// MLSR FIB 交互接口 /////////////////////// + +func (c *FibCodeCaller) Remove(name *component.Identifier) { + +} + +func (c *FibCodeCaller) Update(name *component.Identifier, allHops route.NextHopList) { + +} + +func (c *FibCodeCaller) Clean() { + +} + +func (c *FibCodeCaller) SetEntryRefreshTime(fert int32) { + +} + +func (c *FibCodeCaller) RegisterPrefix() { + +} + +func (c *FibCodeCaller) SetStrategy(name, strategy *component.Identifier, count uint32) { + +} + +func (c *FibCodeCaller) IsNotNeighbor(name *component.Identifier) { + +} + +func (c *FibCodeCaller) AddNextHopsTpFIBEntryAndMIR() { + +} + +func (c *FibCodeCaller) GetNumberOfFacesForName() { + +} + +func (c *FibCodeCaller) UnRegisterPrefix() { + +} + // // NewDefaultKeychain // @Description: 传入mir身份密码,获取路由器的KeyChain @@ -234,7 +277,7 @@ func (c *FibCodeCaller) newFibListCommandExecutor(parameters *component.ControlP } // -// AddFib +// addFib // @Description: 增加某个fib表项 // @receiver c // @param prefix @@ -242,7 +285,7 @@ func (c *FibCodeCaller) newFibListCommandExecutor(parameters *component.ControlP // @param cost // @return error // -func (c *FibCodeCaller) AddFib(prefix string, nexthop string, cost uint64) error { +func (c *FibCodeCaller) addFib(prefix string, nexthop string, cost uint64) error { /* Create Control Parameters */ parameters, err := c.newModifyControlParameters(prefix, nexthop, cost) if err != nil { @@ -275,7 +318,7 @@ func (c *FibCodeCaller) AddFib(prefix string, nexthop string, cost uint64) error // @param cost // @return error // -func (c *FibCodeCaller) DelFib(prefix string, nexthop string, cost uint64) error { +func (c *FibCodeCaller) delFib(prefix string, nexthop string, cost uint64) error { /* Create Control Parameters */ parameters, err := c.newModifyControlParameters(prefix, nexthop, cost) if err != nil { @@ -305,7 +348,7 @@ func (c *FibCodeCaller) DelFib(prefix string, nexthop string, cost uint64) error // @receiver c // @return string // -func (c *FibCodeCaller) ListFib() (string, error) { +func (c *FibCodeCaller) listFib() (string, error) { /* Create Control Parameters */ parameters, err := NewReadControlParameters() if err != nil { From 35c9be1763b47c14b5ae3a8f81278abaa171c67a Mon Sep 17 00:00:00 2001 From: zhengqi Date: Fri, 26 Aug 2022 06:09:21 -0700 Subject: [PATCH 6/9] add:f ib supplement --- mir/FibCodeCaller.go | 89 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 79 insertions(+), 10 deletions(-) diff --git a/mir/FibCodeCaller.go b/mir/FibCodeCaller.go index b1276c5..a9c11da 100644 --- a/mir/FibCodeCaller.go +++ b/mir/FibCodeCaller.go @@ -19,7 +19,12 @@ import ( "minlib/logicface" "minlib/mgmt" "minlib/security" + "mlsr/common" + "mlsr/lsa" + "mlsr/lsdb" "mlsr/route" + "mlsr/utils" + "sync" ) // 一些关于MIR的默认信息。todo 后期应完善到配置文件中,从配置文件中进行读取。 @@ -71,44 +76,108 @@ type FibCodeCaller struct { } ////////////////// MLSR FIB 交互接口 /////////////////////// +type FibEntry struct { + name *component.Identifier + seqNo int32 + nexthopSet *route.NextHopList +} -func (c *FibCodeCaller) Remove(name *component.Identifier) { +// NewFibEntry +// +// @param name *component.Identifier +// +// @return *FibEntry +// +func NewFibEntry(name *component.Identifier) (*FibEntry, error) { + if name == nil { + return nil, errors.New("Invalid name: nil") + } + + fibEntry := new(FibEntry) + // name + fibEntry.name = name + // seqNo + fibEntry.seqNo = 1 + // nexthopSet + fibEntry.nexthopSet = new(route.NextHopList) + return fibEntry, nil +} + +// AfterRefreshCallback +// +type AfterRefreshCallback = func(entry *FibEntry) + +type Fib struct { + ////////////////// const //////////////// + // MULTICAST_STRATEGY + MULTICAST_STRATEGY *component.Identifier + // BEST_ROUTE_STRATEGY + BEST_ROUTE_STRATEGY *component.Identifier + // GRACE_PERIOD + GRACE_PERIOD uint64 + ///////////////////////////////////////// + // OnPrefixRegistrationSuccess + OnPrefixRegistrationSuccess *utils.Signal + // scheduler + scheduler *lsdb.MlsrScheduler + // refreshTime + refreshTime int32 + // controller + controller *mgmt.MIRController + // table map[string]*FibEntry + table sync.Map + // adjacencyList + adjacencyList *lsa.AdjLsaAdjacenctList + // confParameter + confParameter *common.MlsrConfigParameters +} + +func NewFib() (*Fib, error) { } -func (c *FibCodeCaller) Update(name *component.Identifier, allHops route.NextHopList) { +// +// Remove +// +// @param name +// +func (f *Fib) Remove(name *component.Identifier) error { } -func (c *FibCodeCaller) Clean() { +func (f *Fib) Update(name *component.Identifier, allHops route.NextHopList) { } -func (c *FibCodeCaller) SetEntryRefreshTime(fert int32) { +func (f *Fib) Clean() { } -func (c *FibCodeCaller) RegisterPrefix() { +func (f *Fib) SetEntryRefreshTime(fert int32) { } -func (c *FibCodeCaller) SetStrategy(name, strategy *component.Identifier, count uint32) { +func (f *Fib) RegisterPrefix() { } -func (c *FibCodeCaller) IsNotNeighbor(name *component.Identifier) { +func (f *Fib) SetStrategy(name, strategy *component.Identifier, count uint32) { } -func (c *FibCodeCaller) AddNextHopsTpFIBEntryAndMIR() { +func (f *Fib) IsNotNeighbor(name *component.Identifier) { } -func (c *FibCodeCaller) GetNumberOfFacesForName() { +func (f *Fib) AddNextHopsTpFIBEntryAndMIR() { } -func (c *FibCodeCaller) UnRegisterPrefix() { +func (f *Fib) GetNumberOfFacesForName() { + +} + +func (f *Fib) UnRegisterPrefix() { } From 16adbae591fbab8fe18ee933090b3905df19c6a0 Mon Sep 17 00:00:00 2001 From: zhengqi <709030194@qq.com> Date: Sun, 11 Sep 2022 19:31:03 +0800 Subject: [PATCH 7/9] =?UTF-8?q?add:=20MLSR=20=E8=A1=A5=E5=85=A8=E6=96=B9?= =?UTF-8?q?=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hello/HelloProtocol_test.go | 6 +- lsa/AdjLsaAdjacencyList.go | 19 ++- lsa/AdjLsaAdjacencyList_test.go | 4 +- mir/FibCodeCaller.go | 124 +----------------- mlsrcmd/mlsr.go | 99 ++++++++++++-- route/Fib_test.go | 1 + route/LinkStateRoutingTableCalculator_test.go | 4 +- route/NamePrefixTable.go | 45 +++++-- route/NextHopList.go | 8 +- route/NextHop_test.go | 4 +- route/RouteCost.go | 6 +- route/RouteCost_test.go | 6 +- route/RoutingTablePoolEntry.go | 2 +- 13 files changed, 161 insertions(+), 167 deletions(-) create mode 100644 route/Fib_test.go diff --git a/hello/HelloProtocol_test.go b/hello/HelloProtocol_test.go index 92a0109..698946f 100644 --- a/hello/HelloProtocol_test.go +++ b/hello/HelloProtocol_test.go @@ -46,7 +46,8 @@ func TestHelloProtocol_Init(t *testing.T) { rt.Init(mlsrConfig, sche, mlsdb) // 名称前缀表初始化 npt := new(route.NamePrefixTable) - npt.Init(mlsrConfig.GetRouterPrefix(), rt, rt.AfterRoutingChange, mlsdb.OnLsdbModified) + // todo: fib 初始化 + npt.Init(mlsrConfig.GetRouterPrefix(), rt, rt.AfterRoutingChange, mlsdb.OnLsdbModified, nil) // 2. 初始化hello协议 hp := new(HelloProtocol) @@ -78,7 +79,8 @@ func TestHelloProtocol_SendHelloInterest(t *testing.T) { rt.Init(mlsrConfig, sche, mlsdb) // 名称前缀表初始化 npt := new(route.NamePrefixTable) - npt.Init(mlsrConfig.GetRouterPrefix(), rt, rt.AfterRoutingChange, mlsdb.OnLsdbModified) + // todo: fib 初始化 + npt.Init(mlsrConfig.GetRouterPrefix(), rt, rt.AfterRoutingChange, mlsdb.OnLsdbModified, nil) // 2. 初始化hello协议 hp := new(HelloProtocol) diff --git a/lsa/AdjLsaAdjacencyList.go b/lsa/AdjLsaAdjacencyList.go index 8d9010e..6451c94 100644 --- a/lsa/AdjLsaAdjacencyList.go +++ b/lsa/AdjLsaAdjacencyList.go @@ -344,10 +344,10 @@ func (l *AdjLsaAdjacenctList) FindAdjacencyByRouterIdentifier(routerIdentifier * // @param id // @return []*AdjLsaAdjacencyInfo // -func (l *AdjLsaAdjacenctList) FindAdjacencyByLogicFaceId(id *AdjLsaLogicFaceId) []*AdjLsaAdjacencyInfo { +func (l *AdjLsaAdjacenctList) FindAdjacencyByLogicFaceId(id uint64) []*AdjLsaAdjacencyInfo { var infos []*AdjLsaAdjacencyInfo for i := 0; i < len(l.lsaAdjacencys); i++ { - if l.lsaAdjacencys[i].LogicFaceId() == id.Value() { + if l.lsaAdjacencys[i].LogicFaceId() == id { infos = append(infos, l.lsaAdjacencys[i]) } } @@ -361,19 +361,26 @@ func (l *AdjLsaAdjacenctList) FindAdjacencyByLogicFaceId(id *AdjLsaLogicFaceId) // @param uri // @return []*AdjLsaAdjacencyInfo // -func (l *AdjLsaAdjacenctList) FindAdjacencyByLogicFaceUri(uri *AdjLsaLogicFaceUri) []*AdjLsaAdjacencyInfo { +func (l *AdjLsaAdjacenctList) FindAdjacencyByLogicFaceUri(uri string) []*AdjLsaAdjacencyInfo { var infos []*AdjLsaAdjacencyInfo for i := 0; i < len(l.lsaAdjacencys); i++ { - if l.lsaAdjacencys[i].AdjLsaLogicFaceUri.Value() == uri.Value() { + if l.lsaAdjacencys[i].AdjLsaLogicFaceUri.Value() == uri { infos = append(infos, l.lsaAdjacencys[i]) } } return infos } -func (l *AdjLsaAdjacenctList) getLogicFaceId(uri *AdjLsaLogicFaceUri) (uint64, error) { +// +// FindLogicFaceId +// @Description: 获取指定logicfaceuri的logicFaceId。 +// @receiver l +// @param uri +// @return uint64 +// +func (l *AdjLsaAdjacenctList) FindLogicFaceId(uri string) (uint64, error) { for i := 0; i < len(l.lsaAdjacencys); i++ { - if l.lsaAdjacencys[i].AdjLsaLogicFaceUri.Value() == uri.Value() { + if l.lsaAdjacencys[i].AdjLsaLogicFaceUri.Value() == uri { return l.lsaAdjacencys[i].AdjLsaLogicFaceId.Value(), nil } } diff --git a/lsa/AdjLsaAdjacencyList_test.go b/lsa/AdjLsaAdjacencyList_test.go index debe648..e425432 100644 --- a/lsa/AdjLsaAdjacencyList_test.go +++ b/lsa/AdjLsaAdjacencyList_test.go @@ -145,8 +145,8 @@ func TestAdjLsaAdjacenctList_FindAdjacencyByRouterIdentifier(t *testing.T) { // 获取 fmt.Println(adjInfoList.FindAdjacencysByRouterIdentifier(iden)[0].ToString()) //fmt.Println(adjInfoList.FindAdjacencyByRouterIdentifier(iden)[1].ToString()) - fmt.Println(adjInfoList.FindAdjacencyByLogicFaceId(&faceId)[0].ToString()) - fmt.Println(adjInfoList.FindAdjacencyByLogicFaceUri(&faceUri)[0].ToString()) + fmt.Println(adjInfoList.FindAdjacencyByLogicFaceId(faceId.Value())[0].ToString()) + fmt.Println(adjInfoList.FindAdjacencyByLogicFaceUri(faceUri.Value())[0].ToString()) } // diff --git a/mir/FibCodeCaller.go b/mir/FibCodeCaller.go index a9c11da..2fe5ee3 100644 --- a/mir/FibCodeCaller.go +++ b/mir/FibCodeCaller.go @@ -19,12 +19,6 @@ import ( "minlib/logicface" "minlib/mgmt" "minlib/security" - "mlsr/common" - "mlsr/lsa" - "mlsr/lsdb" - "mlsr/route" - "mlsr/utils" - "sync" ) // 一些关于MIR的默认信息。todo 后期应完善到配置文件中,从配置文件中进行读取。 @@ -36,8 +30,7 @@ const ( MirTopPrefix = "/min-mir/mgmt/localhost" ) -// -// MirNextHopInfo +// MirNextHopInfo // @Description: 下一跳信息【可用于ListFib函数返回值的反序列化】 // type MirNextHopInfo struct { @@ -45,8 +38,7 @@ type MirNextHopInfo struct { Cost uint64 } -// -// MirFibInfo +// MirFibInfo // @Description: 每个FIB条目中,一个前缀可对应多个下一跳【可用于ListFib函数返回值的反序列化】 // type MirFibInfo struct { @@ -54,8 +46,7 @@ type MirFibInfo struct { NextHopsInfo []MirNextHopInfo } -// -// MirFaceInfo +// MirFaceInfo // @Description: 用于从MIR获取所有face信息时的反序列化 // type MirFaceInfo struct { @@ -66,8 +57,7 @@ type MirFaceInfo struct { RateLimit int64 } -// -// FibCodeCaller +// FibCodeCaller // @Description: 实现MIR中fib表项信息更改的结构体 // type FibCodeCaller struct { @@ -75,112 +65,6 @@ type FibCodeCaller struct { keyChain *security.KeyChain } -////////////////// MLSR FIB 交互接口 /////////////////////// -type FibEntry struct { - name *component.Identifier - seqNo int32 - nexthopSet *route.NextHopList -} - -// NewFibEntry -// -// @param name *component.Identifier -// -// @return *FibEntry -// -func NewFibEntry(name *component.Identifier) (*FibEntry, error) { - if name == nil { - return nil, errors.New("Invalid name: nil") - } - - fibEntry := new(FibEntry) - // name - fibEntry.name = name - // seqNo - fibEntry.seqNo = 1 - // nexthopSet - fibEntry.nexthopSet = new(route.NextHopList) - return fibEntry, nil -} - -// AfterRefreshCallback -// -type AfterRefreshCallback = func(entry *FibEntry) - -type Fib struct { - ////////////////// const //////////////// - // MULTICAST_STRATEGY - MULTICAST_STRATEGY *component.Identifier - // BEST_ROUTE_STRATEGY - BEST_ROUTE_STRATEGY *component.Identifier - // GRACE_PERIOD - GRACE_PERIOD uint64 - ///////////////////////////////////////// - // OnPrefixRegistrationSuccess - OnPrefixRegistrationSuccess *utils.Signal - // scheduler - scheduler *lsdb.MlsrScheduler - // refreshTime - refreshTime int32 - // controller - controller *mgmt.MIRController - // table map[string]*FibEntry - table sync.Map - // adjacencyList - adjacencyList *lsa.AdjLsaAdjacenctList - // confParameter - confParameter *common.MlsrConfigParameters -} - -func NewFib() (*Fib, error) { - -} - -// -// Remove -// -// @param name -// -func (f *Fib) Remove(name *component.Identifier) error { - -} - -func (f *Fib) Update(name *component.Identifier, allHops route.NextHopList) { - -} - -func (f *Fib) Clean() { - -} - -func (f *Fib) SetEntryRefreshTime(fert int32) { - -} - -func (f *Fib) RegisterPrefix() { - -} - -func (f *Fib) SetStrategy(name, strategy *component.Identifier, count uint32) { - -} - -func (f *Fib) IsNotNeighbor(name *component.Identifier) { - -} - -func (f *Fib) AddNextHopsTpFIBEntryAndMIR() { - -} - -func (f *Fib) GetNumberOfFacesForName() { - -} - -func (f *Fib) UnRegisterPrefix() { - -} - // // NewDefaultKeychain // @Description: 传入mir身份密码,获取路由器的KeyChain diff --git a/mlsrcmd/mlsr.go b/mlsrcmd/mlsr.go index 3697503..8de54fb 100644 --- a/mlsrcmd/mlsr.go +++ b/mlsrcmd/mlsr.go @@ -12,17 +12,19 @@ import ( common2 "minlib/common" "minlib/component" "minlib/logicface" + "minlib/mgmt" "minlib/security" utils2 "minlib/utils" "mlsr/common" "mlsr/hello" "mlsr/lsa" "mlsr/lsdb" - "mlsr/mir" "mlsr/route" "mlsr/utils" ) +const unixPath = "/tmp/mir.sock" + type Mlsr struct { LOCALHOST_PREFIX *component.Identifier m_face *logicface.DummyClientLogicFace @@ -31,7 +33,7 @@ type Mlsr struct { m_adjacencyList *lsa.AdjLsaAdjacenctList m_namePrefixList *lsa.NameLsaNamePrefixList //std::vector m_strategySetOnRouters; todo 不同前缀使用不同转发策略 - m_fibCaller *mir.FibCodeCaller + m_fib *route.Fib m_lsdb *lsdb.Lsdb m_routingTable *route.RoutingTable m_namePrefixTable *route.NamePrefixTable @@ -62,6 +64,27 @@ func (m *Mlsr) Init(face *logicface.DummyClientLogicFace, scheduler *lsdb.MlsrSc if err != nil { common2.LogFatal("mlsr identifier \"/localhost/nlsr\" create error, ", err) } + + // mir controller 初始化 + controller := mgmt.CreateMIRController(func() (mgmt.IMgmtLogicFace, error) { + face := new(logicface.LogicFace) + // 建立unix连接 + if err := face.InitWithUnixSocket(unixPath); err != nil { + return nil, err + } + return face, nil + }, true, chain) + + // conf parameters 初始化 + conf := new(common.MlsrConfigParameters) + conf.Init(confParam) + + // fib 初始化 + fib, err := route.NewFib(scheduler, controller, confParam.GetAdjacencys(), conf) + if err != nil { + common2.LogFatal("Fib Init Failed.") + } + m.LOCALHOST_PREFIX = nameIdentifier m.m_face = face @@ -69,10 +92,7 @@ func (m *Mlsr) Init(face *logicface.DummyClientLogicFace, scheduler *lsdb.MlsrSc m.m_confParam = confParam m.m_adjacencyList = confParam.GetAdjacencys() m.m_namePrefixList = confParam.GetNamePrefixs() - - // fib修改器 - m.m_fibCaller = new(mir.FibCodeCaller) - m.m_fibCaller.Init2(passwd, chain) + m.m_fib = fib // lsdb m.m_lsdb = new(lsdb.Lsdb) @@ -85,16 +105,13 @@ func (m *Mlsr) Init(face *logicface.DummyClientLogicFace, scheduler *lsdb.MlsrSc // 名称前缀表 m.m_namePrefixTable = new(route.NamePrefixTable) m.m_namePrefixTable.Init(m.m_confParam.GetRouterPrefix(), m.m_routingTable, - m.m_routingTable.AfterRoutingChange, m.m_lsdb.OnLsdbModified) + m.m_routingTable.AfterRoutingChange, m.m_lsdb.OnLsdbModified, fib) // hello协议 m.m_helloProtocol = new(hello.HelloProtocol) m.m_helloProtocol.Init(m.m_face, m.m_scheduler, chain, m.m_confParam, m.m_routingTable, m.m_lsdb) - // NewLSAConnection - // sync := m.m_lsdb.GetSync() - // m.m_onNewLsaConnection = m.m_lsdb. - // 三个信号量接收器的触发 todo 还没实现的两个,一个与sync有关,一个与fib有关 + // 三个信号量接收器的触发 // hello信号量接收器 bindHelloFunc := func(args ...interface{}) { common2.LogInfo("Mlsr.bindHelloFunc") @@ -103,12 +120,67 @@ func (m *Mlsr) Init(face *logicface.DummyClientLogicFace, scheduler *lsdb.MlsrSc // 查看本机是否已知道此路由器 adjInfo := m.m_adjacencyList.FindAdjacencyByRouterIdentifier(neighbor) if adjInfo != nil { - // todo: 在fib中注册该前缀 + // 在fib中注册该前缀 // m_fib.registerPrefix(m_confParam.getSyncPrefix(), it->getFaceUri(), it->getLinkCost(), // ndn::time::milliseconds::max(), ndn::nfd::ROUTE_FLAG_CAPTURE, 0); + if err := fib.RegisterPrefix(confParam.GetSyncPrefix(), adjInfo.LogicFaceUri(), adjInfo.LinkCost()); err != nil { + common2.LogError(err.Error()) + } } } m.m_onInitialHelloDataValidated = m.m_helloProtocol.OnInitialHelloDataValidated.Connect(bindHelloFunc) + + // NewLSAConnection 信号量接收器 + sync := m.m_lsdb.GetSync() + m.m_onNewLsaConnection = sync.OnNewLsa.Connect(func(i ...interface{}) { + if i == nil || len(i) < 4 { + common2.LogError("invalid arg list") + return + } + + var originRouter *component.Identifier + var ok bool + if i[2] != nil { + originRouter, ok = i[2].(*component.Identifier) + if !ok { + common2.LogError("originRouter conversion failed.") + return + } + common2.LogDebug("originRouter: ", originRouter.ToUri()) + } + + m.RegisterStrategyForCerts(originRouter) + }) + + // onPrefixRegistrationSuccess 信号量接收器 + m.m_onPrefixRegistrationSuccess = m.m_fib.OnPrefixRegistrationSuccess.Connect(func(i ...interface{}) { + if i == nil || len(i) < 1 { + common2.LogError("invalid arg list") + return + } + + var name *component.Identifier + var ok bool + + if i[0] != nil { + name, ok = i[0].(*component.Identifier) + if !ok { + common2.LogError("originRouter conversion failed.") + return + } + common2.LogDebug("originRouter: ", name.ToUri()) + } + m.m_helloProtocol.SendHelloInterest(name) + }) + + // 设置组播策略 + if err = m.m_fib.SetStrategy(confParam.GetLsaPrefix(), fib.MULTICAST_STRATEGY, 0); err != nil { + common2.LogFatal("设置组播策略失败:", err) + } + if err = m.m_fib.SetStrategy(confParam.GetSyncPrefix(), fib.MULTICAST_STRATEGY, 0); err != nil { + common2.LogFatal("设置组播策略失败:", err) + } + } // @@ -118,7 +190,8 @@ func (m *Mlsr) Init(face *logicface.DummyClientLogicFace, scheduler *lsdb.MlsrSc // @param originRouter // func (m *Mlsr) RegisterStrategyForCerts(originRouter *component.Identifier) { - + // NLSR中为命名空间routerKey 和 instanceKey 都设置了BEST_ROUTE策略 + // 然而MIR中默认策略即为BEST_ROUTE策略,所以该函数不用实现 } // diff --git a/route/Fib_test.go b/route/Fib_test.go new file mode 100644 index 0000000..7b24afe --- /dev/null +++ b/route/Fib_test.go @@ -0,0 +1 @@ +package route diff --git a/route/LinkStateRoutingTableCalculator_test.go b/route/LinkStateRoutingTableCalculator_test.go index fdc816e..0daf229 100644 --- a/route/LinkStateRoutingTableCalculator_test.go +++ b/route/LinkStateRoutingTableCalculator_test.go @@ -162,7 +162,7 @@ func TestLinkStateRoutingTableCalculator_CalculateOnePath(t *testing.T) { fmt.Println("") for i := 0; i < len(nexthops); i++ { fmt.Println(nexthops[i].LogicFaceUri() + "-" + - strconv.FormatUint(nexthops[i].RouteCost.RouteCost(), 10) + " ") + strconv.FormatUint(nexthops[i].RouteCost.Cost(), 10) + " ") } } @@ -288,6 +288,6 @@ func TestLinkStateRoutingTableCalculator_CalculateMutilPath(t *testing.T) { fmt.Println("") for i := 0; i < len(nexthops); i++ { fmt.Println(nexthops[i].LogicFaceUri() + "-" + - strconv.FormatUint(nexthops[i].RouteCost.RouteCost(), 10) + " ") + strconv.FormatUint(nexthops[i].RouteCost.Cost(), 10) + " ") } } diff --git a/route/NamePrefixTable.go b/route/NamePrefixTable.go index e5b4e70..b84cd9d 100644 --- a/route/NamePrefixTable.go +++ b/route/NamePrefixTable.go @@ -37,7 +37,8 @@ type NamePrefixTable struct { m_afterRoutingChangeConnection *utils.SignalConnection m_afterLsdbModified *utils.SignalConnection - // todo fib + // FIB FIB表交互结构体 + m_fib *Fib } // @@ -74,12 +75,13 @@ func (t *NamePrefixTable) PrintSelf() { // func (t *NamePrefixTable) Init(ownRouterName *component.Identifier, routingTable *RoutingTable, afterRoutingChangeSignal *utils.Signal, - afterLsdbModifiedSignal *utils.Signal) { + afterLsdbModifiedSignal *utils.Signal, fib *Fib) { // 初始化数据结构 t.m_rtpool = make(map[string]*RoutingTablePoolEntry) // 赋值变量 t.m_ownRouterName = ownRouterName t.m_routingTable = routingTable + t.m_fib = fib // 监听路由表的修改,触发NPT表修改 bindRoutingChangeFunc := func(args ...interface{}) { @@ -261,14 +263,23 @@ func (t *NamePrefixTable) AddEntry(name *component.Identifier, destRouter *compo // 如果这个条目有下一跳,我们需要通知FIB if len(npte.GetNextHops()) > 0 { common2.LogDebug("Updating FIB with next hops for ", npte.GetNamePrefix().ToUri()) - // todo 更新fib m_fib.update(name, npte->getNexthopList()); + // 更新fib + // m_fib.update(name, npte->getNexthopList()); + err := t.m_fib.Update(name, npte.GetNexthopList()) + if err != nil { + common2.LogError(err.Error()) + } } else { // 如果没有下一跳 // 路由表可以重新计算并添加一个没有下一跳的路由表条目,以替换现有的路由表条目。 // 在这种情况下,通过下一个跃点无法再访问名称前缀,应将其从FIB中删除。 // 但是,前缀应该保留在名称前缀表中,因为未来的路由表计算可能会添加下一跳。 common2.LogDebug(npte.GetNamePrefix().ToUri() + " has no next hops; removing from FIB") - // todo 更新fib m_fib.remove(name); + // 更新fib + // m_fib.remove(name); + if err := t.m_fib.Remove(name); err != nil { + common2.LogError(err.Error()) + } } } else { // 如果NPT有这个name @@ -282,11 +293,19 @@ func (t *NamePrefixTable) AddEntry(name *component.Identifier, destRouter *compo if len(t.nptEntryList[nameIndex].GetNextHops()) > 0 { common2.LogDebug("Updating FIB with next hops for ", t.nptEntryList[nameIndex].GetNamePrefix().ToUri()) - // todo 更新fib m_fib.update(name, npte->getNexthopList()); + // 更新fib + //m_fib.update(name, npte->getNexthopList()); + if err := t.m_fib.Update(name, t.nptEntryList[nameIndex].GetNexthopList()); err != nil { + common2.LogError(err.Error()) + } } else { common2.LogDebug(t.nptEntryList[nameIndex].GetNamePrefix().ToUri() + " has no next hops; removing from FIB") - // todo 更新fib m_fib.remove(name); + // 更新fib + //m_fib.remove(name); + if err := t.m_fib.Remove(name); err != nil { + common2.LogError(err.Error()) + } } } @@ -338,12 +357,20 @@ func (t *NamePrefixTable) RemoveEntry(name *component.Identifier, destRouter *co common2.LogDebug(name.ToUri() + " has no routing table entries;" + " removing from table and FIB") t.deleteNamePrefix(nameIndex) - // todo 删除fib中的该name m_fib.remove(name); + // 删除fib中的该name + //m_fib.remove(name); + if err := t.m_fib.Remove(name); err != nil { + common2.LogError(err.Error()) + } } else { common2.LogDebug(name.ToUri() + " has other routing table entries;" + " updating FIB with next hops") t.nptEntryList[nameIndex].GenerateNhlfromRteList() - // todo 更新fib m_fib.update(name, (*nameItr)->getNexthopList()); + // 更新fib + //m_fib.update(name, (*nameItr)->getNexthopList()); + if err := t.m_fib.Update(name, t.nptEntryList[nameIndex].GetNexthopList()); err != nil { + common2.LogError(err.Error()) + } } } else { common2.LogDebug("Attempted to remove origin: " + rtpe.GetDestination().ToUri() + @@ -366,7 +393,7 @@ func isNextHopsEqual(hops1 []*NextHop, hops2 []*NextHop) bool { // 遍历,如果有一个不相等,则false for i := 0; i < len(hops1); i++ { if hops1[i].LogicFaceUri() != hops2[i].LogicFaceUri() || - hops1[i].RouteCost.RouteCost() != hops2[i].RouteCost.RouteCost() { + hops1[i].RouteCost.Cost() != hops2[i].RouteCost.Cost() { return false } } diff --git a/route/NextHopList.go b/route/NextHopList.go index 364fc88..a12228f 100644 --- a/route/NextHopList.go +++ b/route/NextHopList.go @@ -36,7 +36,7 @@ func (l *NextHopList) ToString() string { res := "----------------\n" for i := 0; i < len(l.nextHops); i++ { res += l.nextHops[i].LogicFaceUri() + " " - res += strconv.FormatUint(l.nextHops[i].RouteCost.RouteCost(), 10) + " " + res += strconv.FormatUint(l.nextHops[i].RouteCost.Cost(), 10) + " " res += strconv.FormatBool(l.nextHops[i].IsHyperbolic) + " \n" } res += "----------------\n" @@ -79,7 +79,7 @@ func (l *NextHopList) findSameUriNextHop(hop *NextHop) int { func (l *NextHopList) findSameNextHop(hop *NextHop) int { for i := 0; i < len(l.nextHops); i++ { if (l.nextHops[i].LogicFaceUri() == hop.LogicFaceUri()) && - (l.nextHops[i].RouteCost.RouteCost() == hop.RouteCost.RouteCost()) { + (l.nextHops[i].RouteCost.Cost() == hop.RouteCost.Cost()) { return i } } @@ -96,7 +96,7 @@ func (l *NextHopList) AddNextHop(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() { + } else if l.nextHops[index].RouteCost.Cost() != hop.RouteCost.Cost() { // 注意,这里必须先删掉旧的,再加入新的;如果直接修改旧的nextHop,则可能导致该nextHop所属的另一个NextHopList属性被改变 l.RemoveNextHop(l.nextHops[index]) l.nextHops = append(l.nextHops, hop) @@ -113,7 +113,7 @@ 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() { + } else if l.nextHops[index].RouteCost.Cost() > hop.RouteCost.Cost() { // 注意,这里必须先删掉旧的,再加入新的;如果直接修改旧的nextHop,则可能导致该nextHop所属的另一个NextHopList属性被改变 l.RemoveNextHop(l.nextHops[index]) l.nextHops = append(l.nextHops, hop) diff --git a/route/NextHop_test.go b/route/NextHop_test.go index e4ad2e2..1343df6 100644 --- a/route/NextHop_test.go +++ b/route/NextHop_test.go @@ -23,7 +23,7 @@ func TestNewNextHop(t *testing.T) { nexthop, err := NewNextHop("/test", 543) if err == nil { fmt.Println(nexthop.IsHyperbolic) - fmt.Println(nexthop.RouteCost.RouteCost()) + fmt.Println(nexthop.RouteCost.Cost()) fmt.Println(nexthop.LogicFaceUri()) } else { fmt.Println("测试NewNextHop报错,", err.Error()) @@ -91,6 +91,6 @@ func TestNextHop_WireDecode(t *testing.T) { return } fmt.Println(base.IsHyperbolic) - fmt.Println(base.RouteCost.RouteCost()) + fmt.Println(base.RouteCost.Cost()) fmt.Println(base.LogicFaceUri()) } diff --git a/route/RouteCost.go b/route/RouteCost.go index e061b28..8313c4f 100644 --- a/route/RouteCost.go +++ b/route/RouteCost.go @@ -34,7 +34,7 @@ type RouteCost struct { // @receiver l // @return uint64 // -func (l *RouteCost) RouteCost() uint64 { +func (l *RouteCost) Cost() uint64 { return l.CommonUint64.Value() } @@ -44,7 +44,7 @@ func (l *RouteCost) RouteCost() uint64 { // @receiver l // @param linkCost // -func (l *RouteCost) SetRouteCost(linkCost uint64) { +func (l *RouteCost) SetRouteCost(linkCost uint64) { l.CommonUint64.SetValue(linkCost) } @@ -70,7 +70,7 @@ func (l *RouteCost) WireEncode(encoder *encoding.Encoder) (int, error) { // func (l *RouteCost) WireDecode(block *encoding.Block) error { // 检查type是否正确 - if err := encoding.ExpectType(block.GetType(),extensions.TlvMlsrRouteCost); err!=nil { + if err := encoding.ExpectType(block.GetType(), extensions.TlvMlsrRouteCost); err != nil { return err } return l.CommonUint64.WireDecode(block) diff --git a/route/RouteCost_test.go b/route/RouteCost_test.go index bf4d5b3..f795222 100644 --- a/route/RouteCost_test.go +++ b/route/RouteCost_test.go @@ -23,7 +23,7 @@ import ( func TestRouteCost_SetRouteCost(t *testing.T) { lsaSequenceNumber := RouteCost{} lsaSequenceNumber.SetRouteCost(77) - if lsaSequenceNumber.RouteCost() != 77 { + if lsaSequenceNumber.Cost() != 77 { t.Fatal("RouteCost设置失败") } } @@ -75,7 +75,7 @@ func TestRouteCost_WireDecode(t *testing.T) { t.Fatal("RouteCost解码失败", err.Error()) } - if linkCost.RouteCost() != 1234 { - t.Fatal("RouteCost解码内容错误", linkCost.RouteCost()) + if linkCost.Cost() != 1234 { + t.Fatal("RouteCost解码内容错误", linkCost.Cost()) } } diff --git a/route/RoutingTablePoolEntry.go b/route/RoutingTablePoolEntry.go index 50734b2..8f6ce4e 100644 --- a/route/RoutingTablePoolEntry.go +++ b/route/RoutingTablePoolEntry.go @@ -99,7 +99,7 @@ func (pe *RoutingTablePoolEntry) IsEqual(npe *RoutingTablePoolEntry) bool { b := true for i := 0; i < pe.NextHopList.Size(); i++ { if pe.GetNextHops()[i].LogicFaceUri() != npe.GetNextHops()[i].LogicFaceUri() || - pe.GetNextHops()[i].RouteCost.RouteCost() != npe.GetNextHops()[i].RouteCost.RouteCost() { + pe.GetNextHops()[i].RouteCost.Cost() != npe.GetNextHops()[i].RouteCost.Cost() { b = false } } From 95de71b135b780941f7035a10784117ce73f4a95 Mon Sep 17 00:00:00 2001 From: zhengqi <709030194@qq.com> Date: Sun, 11 Sep 2022 19:34:34 +0800 Subject: [PATCH 8/9] =?UTF-8?q?add:=20MLSR=20=E8=A1=A5=E5=85=A8=E6=96=B9?= =?UTF-8?q?=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- route/Fib.go | 551 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 551 insertions(+) create mode 100644 route/Fib.go diff --git a/route/Fib.go b/route/Fib.go new file mode 100644 index 0000000..5b9add8 --- /dev/null +++ b/route/Fib.go @@ -0,0 +1,551 @@ +// Package route +// @Author: zhengqi Wu +// @Description: +// @Version: 0.1.0 +// @Date: 2022/5/5 10:38 +// @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室 +// + +package route + +import ( + "errors" + "fmt" + common2 "minlib/common" + "minlib/component" + "minlib/mgmt" + "mlsr/common" + "mlsr/lsa" + "mlsr/lsdb" + "mlsr/utils" + "sync" +) + +const ( + MirTopPrefix = "/min-mir/mgmt/localhost" +) + +////////////////// MLSR FIB 交互接口 /////////////////////// +type FibEntry struct { + name *component.Identifier + seqNo int32 + nexthopSet *NextHopList +} + +// NewFibEntry FIBEntry 的工厂方法 +// +// @param name *component.Identifier +// +// @return *FibEntry +// +func NewFibEntry(name *component.Identifier) (*FibEntry, error) { + if name == nil { + return nil, errors.New("Invalid name: nil") + } + + fibEntry := new(FibEntry) + // name + fibEntry.name = name + // seqNo + fibEntry.seqNo = 1 + // nexthopSet + fibEntry.nexthopSet = new(NextHopList) + return fibEntry, nil +} + +type Fib struct { + ////////////////// const //////////////// + // MULTICAST_STRATEGY + MULTICAST_STRATEGY string + // BEST_ROUTE_STRATEGY + BEST_ROUTE_STRATEGY string + // GRACE_PERIOD + GRACE_PERIOD uint64 + // SEMANTIC + SEMANTIC string + ///////////////////////////////////////// + // OnPrefixRegistrationSuccess + OnPrefixRegistrationSuccess *utils.Signal + // scheduler + scheduler *lsdb.MlsrScheduler + // refreshTime + refreshTime int32 + // controller + controller *mgmt.MIRController + // table map[string]*FibEntry + table sync.Map + // adjacencyList + adjacencyList *lsa.AdjLsaAdjacenctList + // confParameter + confParameter *common.MlsrConfigParameters +} + +// NewFib Fib的工厂方法 +// +// @Description: +// +// @param: scheduler +// +// @param: controller +// +// @param: adjacencyList +// +// @param: conf +// +func NewFib(scheduler *lsdb.MlsrScheduler, controller *mgmt.MIRController, adjacencyList *lsa.AdjLsaAdjacenctList, conf *common.MlsrConfigParameters) (*Fib, error) { + // 参数校验 + if scheduler == nil || controller == nil || adjacencyList == nil || conf == nil { + return nil, errors.New("NewFib: Invalid Arguments") + } + + fib := new(Fib) + // 常量 + fib.MULTICAST_STRATEGY = "/strategy/multicast" + fib.BEST_ROUTE_STRATEGY = "/strategy/best-route" + fib.GRACE_PERIOD = 10 + fib.SEMANTIC = "pull" // 默认拉式语义 + + // 初始化信号量 + fib.OnPrefixRegistrationSuccess = utils.NewSignal() + + // 传参初始化 + fib.adjacencyList = adjacencyList + fib.scheduler = scheduler + fib.controller = controller + fib.confParameter = conf + return fib, nil +} + +// Remove +// +// @Description: 根据name从FIB表中完全移除一个FIB条目 +// 当某名称前缀从该路由器不再可达时,就会调用该方法删除FIB表中该前缀对应的FIB条目 +// +// @param name 名称前缀 +// +func (f *Fib) Remove(name *component.Identifier) error { + // 参数校验 + if name == nil { + return errors.New("Remove: Invalid arguments") + } + + prefix := name.ToUri() + + // 创建控制命令 + parameters := &component.ControlParameters{} + parameters.SetPrefix(name) + parameters.SetSemantics(component.GetSemanticsEnumByString(f.SEMANTIC)) + if !component.CheckSemanticsSupport(parameters.Semantics()) { + // 如果语义不支持,直接返回错误 + return errors.New("Not support semantics: " + f.SEMANTIC) + } + + // 构造一个命令执行器 + commandExecutor, err := f.controller.PrepareCommandExecutor(mgmt.CreateFibDeleteEntryCommand(MirTopPrefix, parameters)) + if err != nil { + return err + } + commandExecutor.SetAutoShutdown(true) + + // 执行命令 + response, err := commandExecutor.Start() + if err != nil { + return err + } + + // 如果请求成功,则输出结果 + if response.Code == mgmt.ControlResponseCodeSuccess { + common2.LogInfo(fmt.Sprintf("Delete fib entry for %s success!", prefix)) + } else { + // 请求失败,则输出错误信息 + common2.LogError(fmt.Sprintf("Delete fib entry for %s failed! errMsg: %s", prefix, response.Msg)) + } + return nil +} + +// Update 为一个名称前缀设置下一跳列表 +// +// @Description: 此方法是用于向FIB表中添加下一跳信息的一种方法。 +// +// 从形式上讲,这个方法在MIR中注册allHops中的所有下一跳,并注销所有属于oldHops - newHops的下一跳。 +// +// @param name 名称前缀 +// +// @param allHops 下一跳列表 +// +func (f *Fib) Update(name *component.Identifier, allHops *NextHopList) error { + // 参数校验 + if name == nil || allHops == nil { + return errors.New("Update: Invalid Arguments") + } + + // 获取最大可能的LogicFace数目,即配置设置和所有下一跳列表的长度的较小值 + maxFaces := f.getNumberOfFacesForName(allHops) + + // 确定待添加的下一跳 + hopsToAdd := new(NextHopList) + nFaces := 0 + for ; nFaces < maxFaces; nFaces++ { + hopsToAdd.AddNextHopBySmallerPriciple(allHops.GetNextHops()[nFaces]) + } + + prefix := name.ToUri() + var err error + if entryIt, ok := f.table.Load(prefix); !ok && hopsToAdd.Size() > 0 { + // 表示需要新创建一条FIBEntry + entry := new(FibEntry) + entry.name = name + + // 向该Entry 和 MIR 的 FIB表 中添加下一跳 + err = f.AddNextHopsToFIBEntryAndMIR(entry, hopsToAdd) + if err != nil { + return err + } + + // 更新 fib 的 table + f.table.Store(prefix, entry) + } else { + // 表示 FIBEntry 已存在 + + // 清除空的FIBEntry + if hopsToAdd.Size() == 0 { + return f.Remove(name) + } + + entry, ok := entryIt.(*FibEntry) + if !ok { + return errors.New("Invalid fib entry pointer.") + } + + // 向该Entry 和 MIR 的 FIB表 中添加下一跳 + err = f.AddNextHopsToFIBEntryAndMIR(entry, hopsToAdd) + if err != nil { + return err + } + + // 清除特定的下一跳 + hopsToRemove, err := nextHopSetDifference(entry.nexthopSet, hopsToAdd) + if err != nil { + return err + } + + // 判断是否需要删除MIR中FIBEntry的下一跳 + isUpdateable, err := f.IsNotNeighbor(entry.name) + if err != nil { + return err + } + + // 从MIR和FIBEntry中删除指定下一跳 + for _, hop := range hopsToRemove.GetNextHops() { + if isUpdateable { + err = f.UnRegisterPrefix(entry.name, hop.LogicFaceUri()) + if err != nil { + return err + } + } + entry.nexthopSet.RemoveNextHop(hop) + } + + // entry 序列号 + 1 + entry.seqNo += 1 + } + + return nil +} + +// Clean +// +// @Description: 清除MLSR注册的所有FIBEntry +// +func (f *Fib) Clean() { + f.table.Range(func(key, value interface{}) bool { + // 获取新增的MLSR本地的FIB条目 + entry := value.(*FibEntry) + + // 获取FIB条目中的下一跳信息 + for _, hop := range entry.nexthopSet.GetNextHops() { + f.UnRegisterPrefix(entry.name, hop.LogicFaceUri()) + } + // 无论是否UnRegister成功,都继续遍历table + return true + }) +} + +// SetEntryRefreshTime +// +// @Description: 设置条目过期时间 +// +// @param: fert RefreshTime +// +func (f *Fib) SetEntryRefreshTime(fert int32) { + panic("Implement me") +} + +// RegisterPrefix +// +// @Description: +// +func (f *Fib) RegisterPrefix(namePrefix *component.Identifier, faceUri string, faceCost uint64) error { + // 参数校验 + if namePrefix == nil { + return errors.New("RegisterPrefix: Invalid Arguments") + } + + // 获取faceUri对应的LogicFaceId + faceId, err := f.adjacencyList.FindLogicFaceId(faceUri) + if err != nil { + return err + } + + // 创建控制命令 + parameters := &component.ControlParameters{} + parameters.SetPrefix(namePrefix) + parameters.SetLogicFaceId(faceId) + parameters.SetCost(faceCost) + parameters.SetSemantics(component.GetSemanticsEnumByString(f.SEMANTIC)) + if !component.CheckSemanticsSupport(parameters.Semantics()) { + // 如果语义不支持,直接返回错误 + return errors.New("Not support semantics: " + f.SEMANTIC) + } + + // 构造一个命令执行器 + commandExecutor, err := f.controller.PrepareCommandExecutor(mgmt.CreateFibAddCommand(MirTopPrefix, parameters)) + if err != nil { + return err + } + commandExecutor.SetAutoShutdown(true) + + // 执行命令 + response, err := commandExecutor.Start() + if err != nil { + return err + } + + // 如果请求成功,则输出结果 + prefix := namePrefix.ToUri() + if response.Code == mgmt.ControlResponseCodeSuccess { + common2.LogInfo(fmt.Sprintf("Delete fib entry for %s success!", prefix)) + // 触发Register成功时的回调 + f.onRegistrationSuccess(parameters, faceUri) + } else { + // 请求失败,则输出错误信息 + common2.LogError(fmt.Sprintf("Delete fib entry for %s failed! errMsg: %s", prefix, response.Msg)) + } + + return nil +} + +// SetStrategy +// +// @Description: 为指定的命名空间设置指定的转发策略 +// +// @param: name 命名空间 +// +// @param: strategyName 转发策略名 +// +func (f *Fib) SetStrategy(name *component.Identifier, strategyName string, count uint32) error { + // 参数校验 + if name == nil { + return errors.New("SetStrategy: Invalid Arguments") + } + + namespace := name.ToUri() + + // 设置控制命令参数 + parameters := component.NewControlParameters() + parameters.ControlParameterPrefix.SetPrefix(name) + parameters.ControlParameterCommonString.SetValue(strategyName) + + // 构造一个命令执行器 + commandExecutor, err := f.controller.PrepareCommandExecutor(mgmt.CreateStrategySetCommand(MirTopPrefix, parameters)) + if err != nil { + return err + } + commandExecutor.SetAutoShutdown(true) + + // 执行命令 + response, err := commandExecutor.Start() + if err != nil { + return err + } + + // 如果请求成功,则输出结果 + if response.Code == mgmt.ControlResponseCodeSuccess { + common2.LogInfo(fmt.Sprintf("Set %s strategy for %s success!", strategyName, namespace)) + } else { + // 请求失败,则输出错误信息 + common2.LogError(fmt.Sprintf("Set %s strategy for %s failed! errMsg: %s", strategyName, namespace, response.Msg)) + } + + return nil +} + +// IsNotNeighbor 判断一个命名前缀代表的路由器是否是直连的邻居路由器 +// +// @Description: +// +func (f *Fib) IsNotNeighbor(name *component.Identifier) (bool, error) { + // 参数校验 + if name == nil { + return false, errors.New("IsNotNeighbor: Invalid Arguments") + } + return f.adjacencyList.IsNeighbor(name), nil +} + +// AddNextHopsToFIBEntryAndMIR 使用新的下一跳列表对FIBEntry进行更新 +// +// @Description: 将下一跳列表加入到FIBEntry中,并向MIR进行注册 +// +// @param: entry +// +// @param: hopsToAdd +// +func (f *Fib) AddNextHopsToFIBEntryAndMIR(entry *FibEntry, hopsToAdd *NextHopList) error { + // 参数校验 + if entry == nil || hopsToAdd == nil { + return errors.New("AddNextHopsToFIBEntryAndMIR: Invalid Arguments") + } + + // 判断是否需要向MIR中的FIBEntry进行更新 + name := entry.name + shouldRegister := f.adjacencyList.IsNeighbor(name) + + for _, hop := range hopsToAdd.GetNextHops() { + // 向FIBEntry中添加下一跳 + entry.nexthopSet.AddNextHopBySmallerPriciple(hop) + if shouldRegister { + // 向MIR-FIB中添加下一跳 + err := f.RegisterPrefix(name, hop.LogicFaceUri(), hop.Cost()) + if err != nil { + return err + } + } + } + return nil +} + +// GetNumberOfFacesForName +// +// @Description: 获取nNextHops 和 nMaxFaces 的较小值 +// +func (f *Fib) getNumberOfFacesForName(nextHopList *NextHopList) int { + nNextHops := len(nextHopList.GetNextHops()) + nMaxFaces := f.confParameter.GetMaxFacesPerPrefix() + + if nMaxFaces == 0 { + return nNextHops + } else if nNextHops < nMaxFaces { + return nNextHops + } else { + return nMaxFaces + } +} + +// UnRegisterPrefix +// +// @Description: 删除MIR-FIB中指定条目的指定下一跳信息 +// +// @param: namePrefix 命名前缀 +// +// @param: faceUri 指定LogicFace +// +func (f *Fib) UnRegisterPrefix(namePrefix *component.Identifier, faceUri string) error { + // 参数校验 + if namePrefix == nil { + return errors.New("UnRegisterPrefix: Invalid Arguments") + } + + // 根据faceUri查找邻接Lsa + adjs := f.adjacencyList.FindAdjacencyByLogicFaceUri(faceUri) + if len(adjs) == 0 { + return errors.New("No AdjLsas for " + faceUri) + } + + // 获取FaceId + faceId := adjs[0].LogicFaceId() + + // 创建控制命令 + parameters := &component.ControlParameters{} + parameters.SetPrefix(namePrefix) + parameters.SetLogicFaceId(faceId) + parameters.SetSemantics(component.GetSemanticsEnumByString(f.SEMANTIC)) + if !component.CheckSemanticsSupport(parameters.Semantics()) { + // 如果语义不支持,直接返回错误 + return errors.New("Not support semantics: " + f.SEMANTIC) + } + + // 构造一个命令执行器 /fib-mgmt/del + commandExecutor, err := f.controller.PrepareCommandExecutor(mgmt.CreateFibDeleteCommand(MirTopPrefix, parameters)) + if err != nil { + return err + } + commandExecutor.SetAutoShutdown(true) + + // 执行命令 + response, err := commandExecutor.Start() + if err != nil { + return err + } + + // 如果请求成功,则输出结果 + prefix := namePrefix.ToUri() + if response.Code == mgmt.ControlResponseCodeSuccess { + common2.LogInfo(fmt.Sprintf("Delete fib entry for %s success!", prefix)) + } else { + // 请求失败,则输出错误信息 + common2.LogError(fmt.Sprintf("Delete fib entry for %s failed! errMsg: %s", prefix, response.Msg)) + } + + return nil +} + +// onRegistrationSuccess +// +// @Description: 向MIR注册前缀成功时的回调 +// +// @param: controlParameters 向MIR发送的控制命令 +// +// @param: faceUri 指定LogicFace +// +func (f *Fib) onRegistrationSuccess(controlParameters *component.ControlParameters, faceUri string) { + adjacent := f.adjacencyList.FindAdjacencyByLogicFaceUri(faceUri) + if len(adjacent) == 0 { + common2.LogError("No Adjacent for " + faceUri) + return + } + adjacent[0].SetLogicFaceId(controlParameters.LogicFaceId()) + f.OnPrefixRegistrationSuccess.Emit(controlParameters.Prefix()) +} + +// nextHopSetDifference 计算nextHop集合的差集 +// +// @Description: +// +// @param: oldList nextHop集合 +// +// @param: newList nextHop集合 +// +// @return: *NextHopList, error +// +func nextHopSetDifference(oldList, newList *NextHopList) (*NextHopList, error) { + // 参数校验 + if oldList == nil || newList == nil { + return nil, errors.New("nextHopSetDifference: Invalid Arguments") + } + + // 初始化Set + newSet := make(map[*NextHop]struct{}) + for _, newNextHop := range newList.GetNextHops() { + newSet[newNextHop] = struct{}{} + } + + // oldList - newList 属于oldList但不属于newList的元素 + diff := new(NextHopList) + for _, oldNextHop := range oldList.GetNextHops() { + if _, exist := newSet[oldNextHop]; !exist { + diff.AddNextHopBySmallerPriciple(oldNextHop) + } + } + + return diff, nil +} From 42306a383f02fde3115bc5a9b157d14618aedcad Mon Sep 17 00:00:00 2001 From: zhengqi <709030194@qq.com> Date: Sun, 11 Sep 2022 21:25:11 +0800 Subject: [PATCH 9/9] =?UTF-8?q?add:=20Face=20=E5=88=97=E8=A1=A8=E5=88=9D?= =?UTF-8?q?=E5=A7=8B=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lsa/AdjLsaAdjacencyInfo.go | 22 ++-- mlsrcmd/mlsr.go | 206 ++++++++++++++++++++++++++++++++++--- 2 files changed, 200 insertions(+), 28 deletions(-) diff --git a/lsa/AdjLsaAdjacencyInfo.go b/lsa/AdjLsaAdjacencyInfo.go index 4a3eef5..d021b7b 100644 --- a/lsa/AdjLsaAdjacencyInfo.go +++ b/lsa/AdjLsaAdjacencyInfo.go @@ -32,7 +32,7 @@ type AdjLsaAdjacencyInfo struct { } // -// NewAdjLsaAdjacencyInfo +// NewAdjLsaAdjacencyInfo // @Description: 创建一个结构体对象 // @param adjLsaLinkCost // @param adjLsaLogicFaceUri @@ -50,7 +50,7 @@ func NewAdjLsaAdjacencyInfo(adjLsaLinkCost AdjLsaLinkCost, adjLsaLogicFaceUri Ad } // -// NewAdjLsaAdjacencyInfoByInstance +// NewAdjLsaAdjacencyInfoByInstance // @Description: 根据已有的结构体实例,创建邻接信息结构体 // @param adjLsaLinkCost // @param adjLsaLogicFaceUri @@ -74,7 +74,7 @@ func NewAdjLsaAdjacencyInfoByInstance(adjLsaLinkCost *AdjLsaLinkCost, adjLsaLogi } // -// GetNeighborRouterIdentidier +// GetNeighborRouterIdentifier // @Description: 获取相邻路由器的标识 // @receiver l // @return *component.Identifier @@ -84,7 +84,7 @@ func (l *AdjLsaAdjacencyInfo) GetNeighborRouterIdentifier() *component.Identifie } // -// SetNeighborRouterIdentifier +// SetNeighborRouterIdentifier // @Description:设置相邻路由器的标识 // @receiver l // @param identifier @@ -95,7 +95,7 @@ func (l *AdjLsaAdjacencyInfo) SetNeighborRouterIdentifier(routerIdentifier *comp } // -// Compare +// Compare // @Description: 判断本邻接信息是不是与某个邻居MIR的邻接信息 // @receiver l // @param identifier @@ -110,7 +110,7 @@ func (l *AdjLsaAdjacencyInfo) Compare(routerIdentifier *component.Identifier) bo } // -// CompareLogicFaceUri +// CompareLogicFaceUri // @Description: 根据FaceUri判断本邻接信息关联的Logicface // @receiver l // @param faceUri @@ -124,7 +124,7 @@ func (l *AdjLsaAdjacencyInfo) CompareLogicFaceUri(faceUri *AdjLsaLogicFaceUri) b } // -// CompareLogicFaceUriString +// CompareLogicFaceUriString // @Description: 根据LogicFaceUri判断本邻接信息关联的Logicface // @receiver l // @param faceUriString @@ -138,7 +138,7 @@ func (l *AdjLsaAdjacencyInfo) CompareLogicFaceUriString(faceUriString string) bo } // -// CompareLogicFaceId +// CompareLogicFaceId // @Description: 根据LogicFaceId判断关联的Logicface // @receiver l // @param faceId @@ -152,7 +152,7 @@ func (l *AdjLsaAdjacencyInfo) CompareLogicFaceId(faceId uint64) bool { } // -// ToString +// ToString // @Description: 转string // @receiver l // @@ -175,7 +175,7 @@ func (l *AdjLsaAdjacencyInfo) ToString() string { } // -// WireEncode +// WireEncode // @Description: 线速编码 // @receiver l // @param encoder @@ -220,7 +220,7 @@ func (l *AdjLsaAdjacencyInfo) WireEncode(encoder *encoding.Encoder) (int, error) } // -// WireDecode +// WireDecode // @Description: 线速解码 // @receiver l // @param block diff --git a/mlsrcmd/mlsr.go b/mlsrcmd/mlsr.go index 8de54fb..5765868 100644 --- a/mlsrcmd/mlsr.go +++ b/mlsrcmd/mlsr.go @@ -9,6 +9,7 @@ package mlsrcmd import ( + "encoding/json" common2 "minlib/common" "minlib/component" "minlib/logicface" @@ -19,20 +20,21 @@ import ( "mlsr/hello" "mlsr/lsa" "mlsr/lsdb" + "mlsr/mir" "mlsr/route" "mlsr/utils" + "time" ) const unixPath = "/tmp/mir.sock" type Mlsr struct { - LOCALHOST_PREFIX *component.Identifier - m_face *logicface.DummyClientLogicFace - m_scheduler *lsdb.MlsrScheduler - m_confParam *common.MlsrConfig - m_adjacencyList *lsa.AdjLsaAdjacenctList - m_namePrefixList *lsa.NameLsaNamePrefixList - //std::vector m_strategySetOnRouters; todo 不同前缀使用不同转发策略 + LOCALHOST_PREFIX *component.Identifier + m_face *logicface.DummyClientLogicFace + m_scheduler *lsdb.MlsrScheduler + m_confParam *common.MlsrConfig + m_adjacencyList *lsa.AdjLsaAdjacenctList + m_namePrefixList *lsa.NameLsaNamePrefixList m_fib *route.Fib m_lsdb *lsdb.Lsdb m_routingTable *route.RoutingTable @@ -43,10 +45,15 @@ type Mlsr struct { m_onNewLsaConnection *utils2.Connection m_onPrefixRegistrationSuccess *utils.SignalConnection m_onInitialHelloDataValidated *utils.SignalConnection + + // 用于与MIR进行交互的控制器 + m_controller *mgmt.MIRController + m_faceDatasetController *mgmt.MIRController + + // todo face通知流 } -// -// Init +// Init // @Description: Mlsr初始化 // @receiver m // @param face face @@ -181,10 +188,33 @@ func (m *Mlsr) Init(face *logicface.DummyClientLogicFace, scheduler *lsdb.MlsrSc common2.LogFatal("设置组播策略失败:", err) } + // 管理用 Controller + m.m_controller = mgmt.CreateMIRController(func() (mgmt.IMgmtLogicFace, error) { + face := new(logicface.LogicFace) + // 建立unix连接 + if err := face.InitWithUnixSocket(unixPath); err != nil { + return nil, err + } + return face, nil + }, true, chain) + + m.m_faceDatasetController = mgmt.CreateMIRController(func() (mgmt.IMgmtLogicFace, error) { + face := new(logicface.LogicFace) + // 建立unix连接 + if err := face.InitWithUnixSocket(unixPath); err != nil { + return nil, err + } + return face, nil + }, true, chain) + + // 拉取Face列表并初始化 + m.InitializeFaces(m.processFaceDataset, m.onFaceDatasetFetchTimeout) + + // todo: face通知流 + } -// -// RegisterStrategyForCerts +// RegisterStrategyForCerts // @Description: 为某个前缀设置转发策略 // @receiver m // @param originRouter @@ -194,21 +224,163 @@ func (m *Mlsr) RegisterStrategyForCerts(originRouter *component.Identifier) { // 然而MIR中默认策略即为BEST_ROUTE策略,所以该函数不用实现 } -// -// AddDispatcherTopPrefix -// @Description: 注册TopPrefix todo 去学习一下MIR原理 +// AddDispatcherTopPrefix +// @Description: 注册TopPrefix // @receiver m // func (m *Mlsr) AddDispatcherTopPrefix() { - + // Dispatcher 用于处理rib的请求 + // 暂时不需要实现 } -// -// RegisterPrefix +// RegisterPrefix // @Description: 使用MLSR的LogicFace注册一个前缀 // @receiver m // @param prefix // func (m *Mlsr) RegisterPrefix(prefix *component.Identifier) { + // Dispatcher 用于处理rib的请求 + // 暂时不需要实现 +} +// InitializeFaces +// @Description: 通过MIR的face列表初始化邻居节点 +// @receiver m +// @param notification +// +func (m *Mlsr) onFaceEventNotification(notification interface{}) { + panic("Implement me") +} + +// InitializeFaces +// +// @Description: 通过MIR的face列表初始化邻居节点 +// +// @receiver m +// +// @param onFetchSuccess 拉取成功的回调函数 +// +// @param onFetchFailure 拉取失败的回调函数 +// +func (m *Mlsr) InitializeFaces(onFetchSuccess func([]mgmt.FaceInfo), onFetchFailure func(int, string)) { + // 参数校验 + if onFetchFailure == nil || onFetchSuccess == nil { + common2.LogFatal("InitializeFaces: Invalid Arguments") + } + + // 开始拉取Face列表 + commandExecutor, err := m.m_faceDatasetController.PrepareCommandExecutor(mgmt.CreateLogicFaceListCommand(mir.TopPrefix)) + if err != nil { + common2.LogFatal(err.Error()) + } + commandExecutor.SetAutoShutdown(true) + + // 执行命令拉取结果 + response, err := commandExecutor.Start() + if err != nil { + // 拉取失败,调用onFetchFailure回调 + onFetchFailure(response.Code, err.Error()) + } + + // 反序列化,得到Face列表 + var faceInfoList []mgmt.FaceInfo + err = json.Unmarshal(response.GetBytes(), &faceInfoList) + if err != nil { + common2.LogFatal(err.Error()) + } + + // 拉取成功,调用onFetchSuccess回调 + onFetchSuccess(faceInfoList) +} + +// processFaceDataset(onFetchSuccess) +// +// @Description: 处理向MIR拉取到的Face列表 +// +// @receiver m +// +// @param faces 拉取到的Face信息列表 +// +func (m *Mlsr) processFaceDataset(faces []mgmt.FaceInfo) { + // 遍历nlsr.conf中指定的所有邻居节点 + for _, adjacent := range m.m_adjacencyList.GetAdjList() { + faceUriString := adjacent.LogicFaceUri() + // 遍历 face 列表,查看有无匹配项 + for _, face := range faces { + if adjacent.LogicFaceId() == 0 && faceUriString == face.RemoteUri { + // 更新邻居节点的LogicFaceId + adjacent.SetLogicFaceId(face.LogicFaceId) + m.registerAdjacencyPrefixes(adjacent) + } + } + + if adjacent.LogicFaceId() == 0 { + common2.LogWarn("The adjacency ", adjacent.GetNeighborRouterIdentifier().ToUri(), " has no Face information in this dataset.") + } + } + + // 继续调度FaceDataset的拉取任务 + m.scheduleDatasetFetch() +} + +// registerAdjacencyPrefixes +// +// @Description: 向MIR注册邻接节点的前缀 +// +// @receiver m +// +// @param adj 邻接节点信息 +// +func (m *Mlsr) registerAdjacencyPrefixes(adj *lsa.AdjLsaAdjacencyInfo) { + faceUri := adj.LogicFaceUri() + linkCost := adj.LinkCost() + adjName := adj.GetNeighborRouterIdentifier() + + // 注册前缀AdjName + if err := m.m_fib.RegisterPrefix(adjName, faceUri, linkCost); err != nil { + common2.LogError(err.Error()) + } + + // 注册前缀LsaPrefix + if err := m.m_fib.RegisterPrefix(m.m_confParam.GetLsaPrefix(), faceUri, linkCost); err != nil { + common2.LogError(err.Error()) + } +} + +// scheduleDatasetFetch +// +// @Description: 调度向MIR拉取Face列表的任务 +// +// @receiver m +// +func (m *Mlsr) scheduleDatasetFetch() { + // 生成调度任务 + job, err := m.m_scheduler.ScheduleTaskAtTime(time.Now(). + Add(time.Duration(m.m_confParam.LogicFaceDatasetFetchInterval)*time.Second), 1). + Do(func() { + m.InitializeFaces(m.processFaceDataset, m.onFaceDatasetFetchTimeout) + }) + if err != nil { + // 生成任务异常,暂停调度 + common2.LogError(err.Error()) + return + } + job.LimitRunsTo(1) + // 开始调度任务 + m.m_scheduler.StartAsync() +} + +// onFaceDatasetFetchTimeout +// +// @Description: 向MIR拉取Face列表失败时的回调函数 +// +// @receiver m +// +// @param code 错误代码 +// +// @param msg 错误信息 +// +func (m *Mlsr) onFaceDatasetFetchTimeout(code int, msg string) { + common2.LogError("Failed to fetch dataset: ", msg, "not trying again this time.") + m.scheduleDatasetFetch() }