From 48b15ef10fede35113af71bd0dbb0b27a5fcb8f5 Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Sat, 13 Jul 2013 01:39:41 +0200 Subject: [PATCH] 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. --- proto/bgp/bgp.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) 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. */