golang实现BFD协议

Posted lovedan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了golang实现BFD协议相关的知识,希望对你有一定的参考价值。

技术图片

毫秒级实现状态监测.

参考了aiobfd ,看了协议文档,

协议帧,包编码解码,用了gopacket的bfd.go ,

然后就是实现 状态 init, up, down的监控.

主要的问题是,时间上,需要快速 的检查发送失败,以判断对端为down掉

// 发送超时失败
func (s *Session) DetectFailure() {
	for {
		select {
		case <-s.clientDone:
			return
		default:
			if !(s.DemandMode || s.asyncDetectTime == 0) {
				if (s.State == layers.BFDStateInit || s.State == layers.BFDStateUp) &&
					((time.Now().UnixNano()/1e6 - s.LastRxPacketTime) > (int64(s.asyncDetectTime) / 1000)) {

					// 状态变化,执行回调函数
					go s.callFunc(s.Remote, int(s.State), int(layers.BFDStateDown))

					s.State = layers.BFDStateDown
					s.LocalDiag = layers.BFDDiagnosticTimeExpired
					s.setDesiredMinTxInterval(DesiredMinTXInterval)

					slogger.Errorf("Detected BFD remote %s going DOWN ", s.Remote)

					slogger.Infof("Time since last packet: %d ms; Detect Time: %d ms ", (time.Now().UnixNano()/1e6 - s.LastRxPacketTime), int64(s.asyncDetectTime)/1000)

					//fmt.Printf("Detected BFD remote %s going DOWN 
", s.Remote)
					fmt.Printf("Time since last packet: %d ms; Detect Time: %d ms 
", (time.Now().UnixNano()/1e6 - s.LastRxPacketTime), int64(s.asyncDetectTime) / 1000)

				}
			}

			time.Sleep(time.Millisecond / 10) // 这里等待时间, 如果太短,cpu占用就大,等待时长,最后的结果不是很准

		}
	}
}

  

时间上要对应得上来.

 

最后,实现了协议,当然是要用上来。

package gobfd

import (
	"fmt"
	"syscall"
	"testing"
	"time"
)

const (
	family = syscall.AF_INET // 默认ipv4
	local = "0.0.0.0"

	passive = false          // 是否是被动模式
	rxInterval = 400  // 400 毫秒
	txInterval = 400  // 400 毫秒
	detectMult = 1           // 报文最大失效的个数
)


// 回调函数
func PrintIpBFDState1(ipAddr string, preState, curState int) error {
	fmt.Println("ipAddr:", ipAddr, ",preState:", preState, ",curState:", curState)
	return nil
}


// 回调函数
func PrintIpBFDState2(ipAddr string, preState, curState int) error {
	fmt.Println("ipAddr:", ipAddr, ",preState:", preState, ",curState:", curState)
	return nil
}


//
func TestNewControl(t *testing.T) {
	fmt.Println("start ..")

	// 启动
	control := NewControl(local, family)
	// 添加监测
	remote1 := "192.168.1.244"  // 远程ip
	control.AddSession(remote1, passive, rxInterval, txInterval, detectMult, PrintIpBFDState1)

	// 添加监测2
	remote2 := "192.168.1.185"  // 远程ip2
	control.AddSession(remote2, passive, rxInterval, txInterval, detectMult, PrintIpBFDState2)


	fmt.Println("sleep 30 second...")
	time.Sleep(time.Second * 30)


	// 删除监测
	fmt.Println("del session ...")
	control.DelSession(remote1)
	control.DelSession(remote2)

	time.Sleep(time.Second * 3)

}

  

以上是关于golang实现BFD协议的主要内容,如果未能解决你的问题,请参考以下文章

代码片段 - Golang 实现集合操作

golang代码片段(摘抄)

BFD (Bidirectional Forwarding Dectection,双向转发检测)

BFD技术的全面解析

BFD与VRRP协议

静态路由和BFD联动