Skip to content
Snippets Groups Projects
fsm_active.go 1.48 KiB
Newer Older
Oliver Herms's avatar
Oliver Herms committed
package server

Oliver Herms's avatar
Oliver Herms committed
import (
	"fmt"
	"net"
)

Oliver Herms's avatar
Oliver Herms committed
type activeState struct {
Oliver Herms's avatar
Oliver Herms committed
	fsm *FSM
Oliver Herms's avatar
Oliver Herms committed
}

Oliver Herms's avatar
Oliver Herms committed
func newActiveState(fsm *FSM) *activeState {
Oliver Herms's avatar
Oliver Herms committed
	return &activeState{
		fsm: fsm,
	}
}

Oliver Herms's avatar
Oliver Herms committed
func (s activeState) run() (state, string) {
Oliver Herms's avatar
Oliver Herms committed
	for {
		select {
		case e := <-s.fsm.eventCh:
Oliver Herms's avatar
Oliver Herms committed
			switch e {
			case ManualStop:
				return s.manualStop()
			case Cease:
				return s.cease()
			default:
				continue
Oliver Herms's avatar
Oliver Herms committed
			}
		case <-s.fsm.connectRetryTimer.C:
Oliver Herms's avatar
Oliver Herms committed
			return s.connectRetryTimerExpired()
Oliver Herms's avatar
Oliver Herms committed
		case c := <-s.fsm.conCh:
Oliver Herms's avatar
Oliver Herms committed
			return s.connectionSuccess(c)
Oliver Herms's avatar
Oliver Herms committed
		}
	}
}
Oliver Herms's avatar
Oliver Herms committed

func (s *activeState) manualStop() (state, string) {
	s.fsm.con.Close()
	s.fsm.resetConnectRetryCounter()
	stopTimer(s.fsm.connectRetryTimer)
	return newIdleState(s.fsm), "Manual stop event"
}

func (s *activeState) cease() (state, string) {
	s.fsm.con.Close()
	return newCeaseState(), "Cease"
}

func (s *activeState) connectRetryTimerExpired() (state, string) {
	s.fsm.resetConnectRetryTimer()
	s.fsm.tcpConnect()
	return newConnectState(s.fsm), "Connect retry timer expired"
}

func (s *activeState) connectionSuccess(con net.Conn) (state, string) {
	if s.fsm.peer.ttl != 0 {
		SetTCPConnTTLSockopt(con, s.fsm.peer.ttl)
Oliver Herms's avatar
Oliver Herms committed
	} else if s.fsm.peer.isEBGP() {
		SetTCPConnTTLSockopt(con, 1)
	}

Oliver Herms's avatar
Oliver Herms committed
	s.fsm.con = con
	stopTimer(s.fsm.connectRetryTimer)
	err := s.fsm.sendOpen()
	if err != nil {
		s.fsm.resetConnectRetryTimer()
		s.fsm.connectRetryCounter++
		return newIdleState(s.fsm), fmt.Sprintf("Sending OPEN message failed: %v", err)
	}
	return newOpenSentState(s.fsm), "Sent OPEN message"
}