mirror of
https://gitee.com/willfree/mlsr.git
synced 2026-06-03 15:56:13 +08:00
344 lines
13 KiB
Go
344 lines
13 KiB
Go
// Package common
|
|
// @Author: Wang Feng
|
|
// @Description:
|
|
// @Version: 0.1.0
|
|
// @Date: 2022/3/29 11:10
|
|
// @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
|
|
//
|
|
|
|
package common
|
|
|
|
import (
|
|
"encoding/json"
|
|
"gopkg.in/ini.v1"
|
|
common2 "minlib/common"
|
|
"strconv"
|
|
)
|
|
|
|
const DefaultConfFileName = "mlsrConf.ini"
|
|
|
|
//
|
|
// MlsrConfig
|
|
// @Description: MLSR 配置文件的配置。与mlsrConf.ini一一对应
|
|
//
|
|
type MlsrConfig struct {
|
|
GeneralConfig `ini:"General"`
|
|
LogConfig `ini:"Log"`
|
|
NeighborsConfig `ini:"Neighbors"`
|
|
HyperbolicConfig `ini:"Hyperbolic"`
|
|
FibConfig `ini:"Fib"`
|
|
AdvertisingConfig `ini:"Advertising"`
|
|
SecurityConfig `ini:"Security"`
|
|
|
|
// 获取值的接口
|
|
MlsrConfigParameters
|
|
|
|
mlsrConfigPath string // 配置文件所在路径
|
|
neighbors []NeighborConfig // NeighborsConfig中的信息
|
|
}
|
|
|
|
//
|
|
// ToString
|
|
// @Description:
|
|
// @receiver c
|
|
//
|
|
func (c *MlsrConfig) ToString() string {
|
|
var str string
|
|
str += "----------------------- MlsrConfig -------------------------\n"
|
|
str += "Config File Path: " + c.mlsrConfigPath + "\n"
|
|
str += "----------------- 1. GeneralConfig -------------------------\n"
|
|
bytes, err := json.Marshal(c.GeneralConfig)
|
|
if err == nil {
|
|
str += string(bytes) + "\n"
|
|
}
|
|
str += "----------------- 2. LogConfig -----------------------------\n"
|
|
bytes, err = json.Marshal(c.LogConfig)
|
|
if err == nil {
|
|
str += string(bytes) + "\n"
|
|
}
|
|
str += "----------------- 3. NeighborsConfig -----------------------\n"
|
|
bytes, err = json.Marshal(c.NeighborsConfig)
|
|
if err == nil {
|
|
str += string(bytes) + "\n"
|
|
}
|
|
str += "----------------- 4. HyperbolicConfig ----------------------\n"
|
|
bytes, err = json.Marshal(c.HyperbolicConfig)
|
|
if err == nil {
|
|
str += string(bytes) + "\n"
|
|
}
|
|
str += "----------------- 5. FibConfig -----------------------------\n"
|
|
bytes, err = json.Marshal(c.FibConfig)
|
|
if err == nil {
|
|
str += string(bytes) + "\n"
|
|
}
|
|
str += "----------------- 6. AdvertisingConfig ---------------------\n"
|
|
bytes, err = json.Marshal(c.AdvertisingConfig)
|
|
if err == nil {
|
|
str += string(bytes) + "\n"
|
|
}
|
|
str += "----------------- 7. SecurityConfig ------------------------\n"
|
|
bytes, err = json.Marshal(c.SecurityConfig)
|
|
if err == nil {
|
|
str += string(bytes) + "\n"
|
|
}
|
|
str += "\n"
|
|
return str
|
|
}
|
|
|
|
func (c *MlsrConfig) ParametersToString() string {
|
|
var str string
|
|
str += "----------------------- MlsrConfigParameters -------------------------\n"
|
|
str += "----------------------- 1. 标识符 -------------------------------------\n"
|
|
str += "路由器定位符:" + c.MlsrConfigParameters.m_routerName.ToUri() + "\n"
|
|
str += "网域定位符:" + c.MlsrConfigParameters.m_siteName.ToUri() + "\n"
|
|
str += "网络定位符:" + c.MlsrConfigParameters.m_network.ToUri() + "\n"
|
|
str += "路由器前缀:" + c.MlsrConfigParameters.m_routerPrefix.ToUri() + "\n"
|
|
str += "同步用户前缀:" + c.MlsrConfigParameters.m_syncUserPrefix.ToUri() + "\n"
|
|
str += "同步前缀:" + c.MlsrConfigParameters.m_syncPrefix.ToUri() + "\n"
|
|
str += "LSA前缀:" + c.MlsrConfigParameters.m_lsaPrefix.ToUri() + "\n"
|
|
str += "----------------------- 2. 时间 ---------------------------------------\n"
|
|
str += "LSA刷新时间:" + strconv.Itoa(int(c.MlsrConfigParameters.m_lsaRefreshTime.Seconds())) + " " +
|
|
"秒 = " + strconv.Itoa(int(c.MlsrConfigParameters.m_lsaRefreshTime.Seconds())/60) + "分钟\n"
|
|
str += "LSA兴趣包生命周期:" + strconv.Itoa(int(c.MlsrConfigParameters.m_lsaInterestLifetime.Seconds())) + " 秒" + "\n"
|
|
str += "路由器死亡间隔:" + strconv.Itoa(int(c.MlsrConfigParameters.m_routerDeadInterval.Seconds())) + " " +
|
|
"秒 = " + strconv.Itoa(int(c.MlsrConfigParameters.m_routerDeadInterval.Seconds())/60) + "分钟\n"
|
|
str += "同步兴趣包生命周期:" + strconv.Itoa(int(c.MlsrConfigParameters.m_syncInterestLifetime.Seconds())) + " 秒" + "\n"
|
|
|
|
str += "hello超时时间:" + strconv.Itoa(int(c.MlsrConfigParameters.m_helloTimeout.Seconds())) + " 秒" + "\n"
|
|
str += "hello发送间隔:" + strconv.Itoa(int(c.MlsrConfigParameters.m_helloInterval.Seconds())) + " 秒" + "\n"
|
|
str += "邻接LSA构建间隔:" + strconv.Itoa(int(c.MlsrConfigParameters.m_adjLsaBuildInterval.Seconds())) + " 秒" + "\n"
|
|
str += "LogicFace数据集请求间隔:" + strconv.Itoa(int(c.MlsrConfigParameters.m_faceDatasetFetchInterval.Seconds())) + " " +
|
|
"秒 = " + strconv.Itoa(int(c.MlsrConfigParameters.m_faceDatasetFetchInterval.Seconds())/60) + "分钟\n"
|
|
str += "路由计算间隔:" + strconv.Itoa(int(c.MlsrConfigParameters.m_RoutingCalcInterval.Seconds())) + " 秒" + "\n"
|
|
str += "\n"
|
|
return str
|
|
}
|
|
|
|
//
|
|
// GeneralConfig
|
|
// @Description: 一、最基础配置信息:LSA、同步协议
|
|
//
|
|
type GeneralConfig struct {
|
|
Network string `ini:"Network"` // 所属网络
|
|
Site string `ini:"Site"` // 所属站点
|
|
Router string `ini:"Router"` // 所属路由器
|
|
|
|
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兴趣包生存周期。当使用推式包时,此值无效【单位:毫秒】
|
|
|
|
SyncProtocol string `ini:"SyncProtocol"` // 同步协议
|
|
SyncInterestLifetime uint32 `ini:"SyncInterestLifetime"` // 同步协议兴趣包生命周期【单位:毫秒】
|
|
}
|
|
|
|
//
|
|
// LogConfig
|
|
// @Description: 二、日志模块
|
|
//
|
|
type LogConfig struct {
|
|
LogLevel string `ini:"LogLevel"` // 日志等级
|
|
ReportCaller bool `ini:"ReportCaller"` // 日志输出时是否添加文件名和函数名
|
|
LogFormat string `ini:"LogFormat"` // 输出日志的格式 "json" | "text"
|
|
LogFilePath string `ini:"LogFilePath"` // 日志输出文件路径,为空则输出至控制台
|
|
}
|
|
|
|
//
|
|
// NeighborsConfig
|
|
// @Description: 三、邻居路由器相关配置
|
|
//
|
|
type NeighborsConfig struct {
|
|
HelloRetries int `ini:"HelloRetries"` // hello协议探测最大次数【单位:毫秒】
|
|
HelloTimeout uint32 `ini:"HelloTimeout"` // hello协议中的超时时间【单位:毫秒】
|
|
HelloInterval uint32 `ini:"HelloInterval"` // 两个hello包之间的间隔时间【单位:毫秒】
|
|
|
|
AdjLsaBuildInterval uint32 `ini:"AdjLsaBuildInterval"` // 邻接LSA构建的时间间隔【单位:毫秒】
|
|
LogicFaceDatasetFetchRetries uint32 `ini:"LogicFaceDatasetFetchRetries"` // 获取FaceStatus数据集的重试次数
|
|
LogicFaceDatasetFetchInterval uint32 `ini:"LogicFaceDatasetFetchInterval"` // FaceStatus数据集获取尝试之间的间隔【单位:毫秒】
|
|
|
|
NeighborsInfo NeighborsJsonString `ini:"NeighborsInfo"` // 邻居路由器链路信息
|
|
}
|
|
|
|
type NeighborsJsonString string
|
|
|
|
type NeighborConfig struct {
|
|
NeighborName string `ini:"NeighborName"` // 邻居路由器的名称前缀
|
|
LogicFaceUri string `ini:"LogicFaceUri"` // 连接该邻居路由器的LogicFace的URI
|
|
LinkCost uint64 `ini:"LinkCost"` // 链路开销(用uint64还是double待决)
|
|
}
|
|
|
|
//
|
|
// parseNeighborConfigToJsonString
|
|
// @Description: 将neighbors结构体数组转为json字符串
|
|
// @param neighbors
|
|
// @return NeighborsJsonString
|
|
// @return error
|
|
//
|
|
func parseNeighborConfigToJsonString(neighbors []NeighborConfig) (NeighborsJsonString, error) {
|
|
bytes, err := json.Marshal(neighbors)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return NeighborsJsonString(bytes), nil
|
|
}
|
|
|
|
//
|
|
// parseJsonStringToNeighbors
|
|
// @Description: 将json字符串neighbors结构体数组
|
|
// @receiver c
|
|
// @param jsonString
|
|
// @return []NeighborConfig
|
|
// @return error
|
|
//
|
|
func parseJsonStringToNeighbors(jsonString NeighborsJsonString) ([]NeighborConfig, error) {
|
|
var neighbors []NeighborConfig
|
|
err := json.Unmarshal([]byte(jsonString), &neighbors)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return neighbors, nil
|
|
}
|
|
|
|
//
|
|
// HyperbolicConfig
|
|
// @Description: 四、预留双曲坐标的配置
|
|
//
|
|
type HyperbolicConfig struct {
|
|
}
|
|
|
|
//
|
|
// FibConfig
|
|
// @Description: 五、路由计算与FIB更新相关配置
|
|
//
|
|
type FibConfig struct {
|
|
MaxLogicFacesPerPrefix int `ini:"MaxLogicFacesPerPrefix"` // 每个前缀对应的下一跳face列表的最大数目
|
|
RoutingCalcInterval uint32 `ini:"RoutingCalcInterval"` // 两次路由计算的时间间隔【单位:毫秒】
|
|
}
|
|
|
|
//
|
|
// AdvertisingConfig
|
|
// @Description: 六、需要通告给其它路由器的前缀
|
|
//
|
|
type AdvertisingConfig struct {
|
|
Prefixs []string `ini:"Prefixs"` // 需要广告给其他路由器的本机前缀
|
|
}
|
|
|
|
//
|
|
// SecurityConfig
|
|
// @Description: 七、预留安全相关的配置
|
|
//
|
|
type SecurityConfig struct {
|
|
}
|
|
|
|
//
|
|
// Init
|
|
// @Description: 初始化配置,给所有的配置设置默认值
|
|
// @receiver c
|
|
//
|
|
func (c *MlsrConfig) Init() {
|
|
// 1. 通用配置参数
|
|
c.GeneralConfig.Network = "/min"
|
|
c.GeneralConfig.Site = "/pkusz"
|
|
c.GeneralConfig.Router = "/routerA"
|
|
c.GeneralConfig.LsaRefreshTime = 30 * 60 * 1000 // 60*4-60*120,范围是4分钟-2小时。默认半小时
|
|
c.GeneralConfig.RouterDeadInterval = 2 * c.GeneralConfig.LsaRefreshTime // 默认一小时
|
|
c.GeneralConfig.LsaInterestLifetime = 4 * 1000 // 4-60,范围是4秒钟到1分钟。默认4秒钟
|
|
c.GeneralConfig.SyncProtocol = "min-sync"
|
|
c.GeneralConfig.SyncInterestLifetime = 60 * 1000 // 1000-120*1000,范围是1秒到2分钟。默认1分钟
|
|
|
|
// 2. Log
|
|
c.LogConfig.LogLevel = "ALL"
|
|
c.LogConfig.ReportCaller = true
|
|
c.LogConfig.LogFormat = "text"
|
|
c.LogConfig.LogFilePath = ""
|
|
|
|
// 3. 邻居路由器配置参数
|
|
c.NeighborsConfig.HelloRetries = 3 // 1-15,次数
|
|
c.NeighborsConfig.HelloTimeout = 1 * 1000 // 1-15,超时时间,范围1秒-15秒。默认1秒钟
|
|
c.NeighborsConfig.HelloInterval = 60 * 1000 // 30-90,间隔时间,范围30秒到1分钟。默认1分钟
|
|
c.NeighborsConfig.AdjLsaBuildInterval = 10 * 1000 // 5-30,构建间隔,范围5秒到30秒。默认10秒钟
|
|
c.NeighborsConfig.LogicFaceDatasetFetchRetries = 3 // 1-10,次数
|
|
c.NeighborsConfig.LogicFaceDatasetFetchInterval = 60 * 60 * 1000 // 30*60-90*60,半小时到一个半小时。默认1小时
|
|
// 邻接链路信息
|
|
c.neighbors = []NeighborConfig{}
|
|
// 将邻居链路信息存储到配置文件中 todo:用于测试
|
|
neighborConfig1 := NeighborConfig{
|
|
NeighborName: "/routerB",
|
|
LogicFaceUri: "tcp://1.1.1.1",
|
|
LinkCost: 10,
|
|
}
|
|
neighborConfig2 := NeighborConfig{
|
|
NeighborName: "/routerC",
|
|
LogicFaceUri: "tcp://1.1.1.0",
|
|
LinkCost: 10,
|
|
}
|
|
//neighborsJsonString, _ := parseNeighborConfigToJsonString(
|
|
// []NeighborConfig{neighborConfig1,neighborConfig2})
|
|
//c.NeighborsConfig.NeighborsInfo=neighborsJsonString
|
|
c.neighbors = append(c.neighbors, neighborConfig1)
|
|
c.neighbors = append(c.neighbors, neighborConfig2)
|
|
|
|
// 5. FIB更新配置参数
|
|
c.FibConfig.MaxLogicFacesPerPrefix = 0 // 0-60,个数,最多有多少个下一跳。置0表示保留所有计算出的下一跳
|
|
c.FibConfig.RoutingCalcInterval = 15 * 1000 // 0-15,路由计算间隔。默认15秒计算一次
|
|
|
|
// 6. 广播本地前缀配置参数
|
|
// c.AdvertisingConfig.Prefixs = []string{} // 非测试状态
|
|
c.AdvertisingConfig.Prefixs = []string{"/videos", "/files", "/voices"} // todo:用于测试
|
|
}
|
|
|
|
//
|
|
// Save
|
|
// @Description: 保存当前配置状态到配置文件当中
|
|
// @receiver c
|
|
// @return error
|
|
//
|
|
func (c *MlsrConfig) Save() error {
|
|
cfg := ini.Empty()
|
|
if len(c.neighbors) > 0 {
|
|
c.NeighborsInfo, _ = parseNeighborConfigToJsonString(c.neighbors)
|
|
}
|
|
if err := ini.ReflectFrom(cfg, c); err != nil {
|
|
return err
|
|
}
|
|
return cfg.SaveTo(c.mlsrConfigPath)
|
|
}
|
|
|
|
//
|
|
// ParseConfig
|
|
// @Description: 从指定路径中解析配置文件
|
|
// @receiver c
|
|
// @param configPath
|
|
// @return *MlsrConfig
|
|
// @return error
|
|
//
|
|
func ParseConfig(configPath string) (*MlsrConfig, error) {
|
|
cfg, err := ini.Load(configPath)
|
|
if err != nil {
|
|
common2.LogFatal("ParseConfig error, load error, path is ", configPath, err.Error())
|
|
return nil, err
|
|
}
|
|
mlsrConfig := new(MlsrConfig)
|
|
mlsrConfig.mlsrConfigPath = configPath
|
|
// 初始化配置,给所有的配置项设置默认值
|
|
mlsrConfig.Init()
|
|
// 加载配置文件中的配置:如果有,则理应覆盖Init中设置的默认配置
|
|
if err = cfg.MapTo(&mlsrConfig); err != nil {
|
|
common2.LogFatal("ParseConfig error, mapTo error, path is ", configPath, err.Error())
|
|
return nil, err
|
|
}
|
|
if mlsrConfig.NeighborsInfo != "" {
|
|
mlsrConfig.neighbors, _ = parseJsonStringToNeighbors(mlsrConfig.NeighborsInfo)
|
|
}
|
|
// 将配置中的参数进行初始化,以支持直接获取结构体形式的参数
|
|
mlsrConfig.MlsrConfigParameters.Init(mlsrConfig)
|
|
// 按照配置文件中的参数,对日志模块进行初始化。不做这一步,则日志模块的配置失效
|
|
InitLogger(mlsrConfig)
|
|
return mlsrConfig, nil
|
|
}
|