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)

}

  

github 链接:

https://github.com/WLmutou/gobfd

原文地址:https://www.cnblogs.com/LoveDan/p/12056372.html