diff options
author | Ondrej Zajicek <santiago@crfreenet.org> | 2013-07-13 01:39:41 +0200 |
---|---|---|
committer | Ondrej Zajicek <santiago@crfreenet.org> | 2013-07-13 01:39:41 +0200 |
commit | 48b15ef10fede35113af71bd0dbb0b27a5fcb8f5 (patch) | |
tree | 334e4f6dc25cbbbab792f47ba812e81ce0060c73 /proto | |
parent | 354496ace87341428e6005fbc073fbe57b4e6c0e (diff) |
Fixes stuck connection during BGP session shutdown.
If TX buffers were full during BGP session shutdown
then a protocol waited indefinitely to be able to
send notification packet to close the session.
Diffstat (limited to 'proto')
-rw-r--r-- | proto/bgp/bgp.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c index b1594b92..32153452 100644 --- a/proto/bgp/bgp.c +++ b/proto/bgp/bgp.c @@ -384,10 +384,12 @@ bgp_conn_enter_close_state(struct bgp_conn *conn) int os = conn->state; bgp_conn_set_state(conn, BS_CLOSE); - tm_stop(conn->hold_timer); tm_stop(conn->keepalive_timer); conn->sk->rx_hook = NULL; + /* Timeout for CLOSE state, if we cannot send notification soon then we just hangup */ + bgp_start_timer(conn->hold_timer, 10); + if (os == BS_ESTABLISHED) bgp_conn_leave_established_state(p); } @@ -478,9 +480,18 @@ static void bgp_hold_timeout(timer *t) { struct bgp_conn *conn = t->data; + struct bgp_proto *p = conn->bgp; DBG("BGP: Hold timeout\n"); + /* We are already closing the connection - just do hangup */ + if (conn->state == BS_CLOSE) + { + BGP_TRACE(D_EVENTS, "Connection stalled"); + bgp_conn_enter_idle_state(conn); + return; + } + /* If there is something in input queue, we are probably congested and perhaps just not processed BGP packets in time. */ |