mirror of
https://gitee.com/willfree/mlsr.git
synced 2026-10-04 19:42:02 +08:00
实现LSDB中功能点:LSA安装、安排LSA超期任务、LSA超期刷新或删除
This commit is contained in:
1 parent
4846c362ea
commit
6a43efb6d5
3 files changed
+132
-6
No files matched your search
@@ -125,6 +125,10 @@ type GeneralConfig struct {
|
||||
|
||||
LsaRefreshTime uint32 `ini:"LsaRefreshTime"` // LSA刷新时间【单位:毫秒】
|
||||
|
||||
// 路由器死亡后,本机NameLsa和AdjLsa将超期失效,从而被LSDB清除
|
||||
// 路由器死亡时间是本机LSA构建时的超期时间,但它在本机进行刷新时,是不按照死亡时间进行刷新的,而是按照LSA刷新时间做刷新的触发
|
||||
// 路由器死亡时间是给其他路由器的LSA超期时间,例如路由器B在死亡时间间隔后会将路由器A的LSA删除,但路由器A其实在LSA刷新时间就已经
|
||||
// 刷新该LSA,并通知给路由器B,因而保证了路由器B一直有路由器A的LSA。
|
||||
RouterDeadInterval uint32 `ini:"RouterDeadInterval"` // 路由器判断死亡的时间间隔(必须大于LSA刷新时间)【单位:毫秒】
|
||||
|
||||
LsaInterestLifetime int `ini:"LsaInterestLifetime"` // LSA兴趣包生存周期。当使用推式包时,此值无效【单位:毫秒】
|
||||
|
||||
+96
-6
@@ -28,6 +28,8 @@ const (
|
||||
REMOVED = -1 // 已移除
|
||||
)
|
||||
|
||||
const GRACE_PERIOD = 10 * time.Second // 超期宽限期。LSA比设定时间晚几秒钟被删除,以避免信息过早失效。
|
||||
|
||||
type Lsdb struct {
|
||||
// 配置参数
|
||||
mlsrConfig *common.MlsrConfig
|
||||
@@ -117,7 +119,7 @@ func (l *Lsdb) BuildAndInstallOwnNameLsa() {
|
||||
nlsa := new(lsa.NameLsa)
|
||||
nlsa.SetOriginRouter(l.thisRouterPrefix) // 源路由
|
||||
nlsa.SetSeqNo(l.sequencingManager.GetNameLsaSeq() + 1) // 序列号
|
||||
nlsa.SetLsaExpirationTime(uint64(l.getLsaExpirationTimePoint().UnixMilli())) // 超期时间
|
||||
nlsa.SetLsaExpirationTime(l.getLsaExpirationTimePoint()) // 超期时间
|
||||
nlsa.NameLsaNamePrefixList.InsertNamePrefixList(l.mlsrConfig.GetNamePrefixList()) // 名称前缀列表
|
||||
// 刷新序列号管理器中的名称LSA序列号
|
||||
l.sequencingManager.IncreaseNameLsaSeq()
|
||||
@@ -231,6 +233,46 @@ func (l *Lsdb) IsLsaNew(routerIdentifier *component.Identifier,
|
||||
}
|
||||
|
||||
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 lsa == 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的动作信号
|
||||
// todo: onLsdbModified(lsa, LsdbUpdate::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的动作信号
|
||||
// todo: onLsdbModified(lsa, LsdbUpdate::UPDATED, namesToAdd, namesToRemove);
|
||||
// 3. 设置LSA超期时间事件
|
||||
l.ScheduleLsaExpiration(lsa, timeToExpire)
|
||||
common2.LogDebug("Updated Lsa ", lsa.ToString())
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Lsdb) RemoveLsa(routerIdentifier *component.Identifier,
|
||||
@@ -262,11 +304,55 @@ func (l *Lsdb) BuildAndInstallOwnAdjLsa() {
|
||||
// @Description: 在调度器中安排一个刷新或过期事件
|
||||
// @receiver l
|
||||
//
|
||||
func (l *Lsdb) ScheduleLsaExpiration(lsa lsa.ILsa, duration *time.Duration) {
|
||||
|
||||
func (l *Lsdb) ScheduleLsaExpiration(lsa lsa.ILsa, duration time.Duration) {
|
||||
// 安排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())
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// ExpireOrRefreshLsa
|
||||
// @Description: LSA过期时间触发后,执行该函数
|
||||
// @receiver l
|
||||
// @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.GetOriginRouter(), lsaInDb.GetType())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Lsdb) ProcessInterestForLsa(interest *packet.Interest,
|
||||
@@ -306,9 +392,13 @@ func (l *Lsdb) OnFetchLsaError(errorCode uint32, msg string,
|
||||
func (l *Lsdb) AfterFetchLsa(buffer bytes.Buffer, interestName *component.Identifier) {
|
||||
}
|
||||
|
||||
func (l *Lsdb) getLsaExpirationTimePoint() time.Time {
|
||||
func (l *Lsdb) getLsaExpirationTimePoint() uint64 {
|
||||
timeExpire := time.Now()
|
||||
timeExpire.Add(l.mlsrConfig.GetRouterDeadInterval())
|
||||
timeExpire = timeExpire.Add(l.mlsrConfig.GetRouterDeadInterval())
|
||||
|
||||
return timeExpire
|
||||
return uint64(timeExpire.UnixMilli())
|
||||
}
|
||||
|
||||
func (l *Lsdb) uintToTime(uintTime uint64) time.Time {
|
||||
return time.UnixMilli(int64(uintTime))
|
||||
}
|
||||
@@ -17,6 +17,11 @@ import (
|
||||
|
||||
const testConfigPath = "D:\\" + common.DefaultConfFileName
|
||||
|
||||
//
|
||||
// TestLsdb_Init
|
||||
// @Description: 测试LSDB初始化
|
||||
// @param t
|
||||
//
|
||||
func TestLsdb_Init(t *testing.T) {
|
||||
// 配置文件初始化
|
||||
mlsrConfig, err := common.ParseConfig(testConfigPath)
|
||||
@@ -32,3 +37,30 @@ func TestLsdb_Init(t *testing.T) {
|
||||
lsdb := new(Lsdb)
|
||||
lsdb.Init(mlsrConfig, sche, face)
|
||||
}
|
||||
|
||||
//
|
||||
// TestUnixTime
|
||||
// @Description: 测试时间与时间戳的转换。将用于LSA中过期时间的保存,非常重要。
|
||||
// @param t
|
||||
//
|
||||
func TestUnixTime(t *testing.T) {
|
||||
// 配置文件初始化
|
||||
mlsrConfig, err := common.ParseConfig(testConfigPath)
|
||||
if err != nil {
|
||||
fmt.Println("配置文件解析错误")
|
||||
}
|
||||
// 调度器初始化
|
||||
sche := new(MlsrScheduler)
|
||||
sche.Init()
|
||||
// LogicFace初始化(假设初始化,暂时用不到)
|
||||
face := new(logicface.LogicFace)
|
||||
// LSDB初始化
|
||||
lsdb := new(Lsdb)
|
||||
lsdb.Init(mlsrConfig, sche, face)
|
||||
|
||||
// 获取过期时间的时间戳
|
||||
timeExpire := lsdb.getLsaExpirationTimePoint()
|
||||
// 时间戳转回过期时间
|
||||
timeTemplate := "2006-01-02 15:04:05" // 时间戳常规类型
|
||||
fmt.Println(lsdb.uintToTime(timeExpire).Format(timeTemplate))
|
||||
}
|
||||
Reference in new issue
Block a user