From ec278710f10c2cae7d6b3e393aa957edfd536181 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Sun, 18 Jan 2015 16:04:13 +0900 Subject: server: support idlehold time after reset After resetting a peer, the peer will remain idle for idlehold time (by default 30 seconds). It can be configured via IdleHoldTImeAfterReset. Signed-off-by: FUJITA Tomonori --- server/fsm.go | 19 +++++++++++++++++-- server/peer.go | 1 + server/server.go | 4 +++- 3 files changed, 21 insertions(+), 3 deletions(-) (limited to 'server') diff --git a/server/fsm.go b/server/fsm.go index af6718ca..5c93fce6 100644 --- a/server/fsm.go +++ b/server/fsm.go @@ -44,6 +44,7 @@ type FSM struct { state bgp.FSMState passiveConn *net.TCPConn passiveConnCh chan *net.TCPConn + idleHoldTime float64 } func (fsm *FSM) bgpMessageStateUpdate(MessageType uint8, isIn bool) { @@ -139,13 +140,27 @@ func (h *FSMHandler) Stop() error { func (h *FSMHandler) idle() bgp.FSMState { fsm := h.fsm - // TODO: support idle hold timer if fsm.keepaliveTicker != nil { fsm.keepaliveTicker.Stop() fsm.keepaliveTicker = nil } - return bgp.BGP_FSM_ACTIVE + + idleHoldTimer := time.NewTimer(time.Second * time.Duration(fsm.idleHoldTime)) + for { + select { + case <-h.t.Dying(): + return 0 + case <-idleHoldTimer.C: + log.WithFields(log.Fields{ + "Topic": "Peer", + "Key": fsm.peerConfig.NeighborAddress, + "Duration": fsm.idleHoldTime, + }).Debug("IdleHoldTimer expired") + fsm.idleHoldTime = 0 + return bgp.BGP_FSM_ACTIVE + } + } } func (h *FSMHandler) active() bgp.FSMState { diff --git a/server/peer.go b/server/peer.go index 79209983..c86aabb5 100644 --- a/server/peer.go +++ b/server/peer.go @@ -178,6 +178,7 @@ func (peer *Peer) handleREST(restReq *api.RestRequest) { case api.REQ_NEIGHBOR_SHUTDOWN: peer.outgoing <- bgp.NewBGPNotificationMessage(bgp.BGP_ERROR_CEASE, bgp.BGP_ERROR_SUB_ADMINISTRATIVE_SHUTDOWN, nil) case api.REQ_NEIGHBOR_RESET: + peer.fsm.idleHoldTime = peer.peerConfig.Timers.IdleHoldTImeAfterReset peer.outgoing <- bgp.NewBGPNotificationMessage(bgp.BGP_ERROR_CEASE, bgp.BGP_ERROR_SUB_ADMINISTRATIVE_RESET, nil) case api.REQ_NEIGHBOR_SOFT_RESET: case api.REQ_NEIGHBOR_SOFT_RESET_IN: diff --git a/server/server.go b/server/server.go index cbd67732..5823859a 100644 --- a/server/server.go +++ b/server/server.go @@ -106,7 +106,9 @@ func (server *BgpServer) Serve() { server.bgpConfig.Global = <-server.globalTypeCh listenerMap := make(map[string]*net.TCPListener) - acceptCh := make(chan *net.TCPConn) + // workaround: we should close an accepted connection + // immediately if we are not in the state we continue? + acceptCh := make(chan *net.TCPConn, 4) l4, err1 := listenAndAccept("tcp4", server.listenPort, acceptCh) listenerMap["tcp4"] = l4 l6, err2 := listenAndAccept("tcp6", server.listenPort, acceptCh) -- cgit v1.2.3