Newer
Older
package server
import (
"bytes"
"fmt"
"github.com/bio-routing/bio-rd/protocols/bgp/packet"
)
type openConfirmState struct {
func newOpenConfirmState(fsm *FSM) *openConfirmState {
}
case <-s.fsm.holdTimer.C:
return s.holdTimerExpired()
case <-s.fsm.keepaliveTimer.C:
return s.keepaliveTimerExpired()
case recvMsg := <-s.fsm.msgRecvCh:
return s.msgReceived(recvMsg)
}
}
}
func (s *openConfirmState) manualStop() (state, string) {
s.fsm.sendNotification(packet.Cease, 0)
stopTimer(s.fsm.connectRetryTimer)
s.fsm.con.Close()
s.fsm.resetConnectRetryCounter()
return newIdleState(s.fsm), "Manual stop event"
}
func (s *openConfirmState) automaticStop() (state, string) {
s.fsm.sendNotification(packet.Cease, 0)
stopTimer(s.fsm.connectRetryTimer)
s.fsm.con.Close()
s.fsm.connectRetryCounter++
return newIdleState(s.fsm), "Automatic stop event"
}
func (s *openConfirmState) cease() (state, string) {
s.fsm.sendNotification(packet.Cease, 0)
s.fsm.con.Close()
return newCeaseState(), "Cease"
}
func (s *openConfirmState) holdTimerExpired() (state, string) {
s.fsm.sendNotification(packet.HoldTimeExpired, 0)
stopTimer(s.fsm.connectRetryTimer)
s.fsm.con.Close()
s.fsm.connectRetryCounter++
return newIdleState(s.fsm), "Holdtimer expired"
}
func (s *openConfirmState) keepaliveTimerExpired() (state, string) {
err := s.fsm.sendKeepalive()
if err != nil {
stopTimer(s.fsm.connectRetryTimer)
s.fsm.con.Close()
s.fsm.connectRetryCounter++
return newIdleState(s.fsm), fmt.Sprintf("Failed to send keepalive: %v", err)
}
func (s *openConfirmState) msgReceived(data []byte) (state, string) {
msg, err := packet.Decode(bytes.NewBuffer(data))
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
if err != nil {
switch bgperr := err.(type) {
case packet.BGPError:
s.fsm.sendNotification(bgperr.ErrorCode, bgperr.ErrorSubCode)
}
stopTimer(s.fsm.connectRetryTimer)
s.fsm.con.Close()
s.fsm.connectRetryCounter++
return newIdleState(s.fsm), fmt.Sprintf("Failed to decode BGP message: %v", err)
}
switch msg.Header.Type {
case packet.NotificationMsg:
return s.notification(msg)
case packet.KeepaliveMsg:
return s.keepaliveReceived()
default:
return s.unexpectedMessage()
}
}
func (s *openConfirmState) notification(msg *packet.BGPMessage) (state, string) {
stopTimer(s.fsm.connectRetryTimer)
s.fsm.con.Close()
nMsg := msg.Body.(*packet.BGPNotification)
if nMsg.ErrorCode != packet.UnsupportedVersionNumber {
s.fsm.connectRetryCounter++
}
return newIdleState(s.fsm), "Received NOTIFICATION"
}
func (s *openConfirmState) keepaliveReceived() (state, string) {
return newEstablishedState(s.fsm), "Received KEEPALIVE"
}
func (s *openConfirmState) unexpectedMessage() (state, string) {
s.fsm.sendNotification(packet.FiniteStateMachineError, 0)
stopTimer(s.fsm.connectRetryTimer)
s.fsm.con.Close()
s.fsm.connectRetryCounter++
return newIdleState(s.fsm), "FSM Error"
}