summaryrefslogtreecommitdiff
path: root/proto/bgp
diff options
context:
space:
mode:
authorOndrej Zajicek (work) <santiago@crfreenet.org>2016-02-11 16:38:28 +0100
committerOndrej Zajicek (work) <santiago@crfreenet.org>2016-02-11 16:38:28 +0100
commit487c6961cb29046dbe9560262e3e742e38691b83 (patch)
tree924075b0645eac572b1468397bd1e8413c47d991 /proto/bgp
parent52e21323b6c49af9d076586241451973a7d1e7c6 (diff)
BGP: Fix bug in incoming connection handling
When a BGP session was established by an outgoing connection with Graceful Restart behavior negotiated, a pending incoming connection in OpenSent state, and another incoming connection was received, then the outgoing connection (and whole BGP session) was closed, but the old incoming connection was just overwritten by the new one. That later caused a crash when the hold timer from the old connection fired.
Diffstat (limited to 'proto/bgp')
-rw-r--r--proto/bgp/bgp.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c
index f549b0ed..11f33b14 100644
--- a/proto/bgp/bgp.c
+++ b/proto/bgp/bgp.c
@@ -813,7 +813,13 @@ bgp_incoming_connection(sock *sk, int dummy UNUSED)
return 0;
}
- /* We are in proper state and there is no other incoming connection */
+ /*
+ * BIRD should keep multiple incoming connections in OpenSent state (for
+ * details RFC 4271 8.2.1 par 3), but it keeps just one. Duplicate incoming
+ * connections are rejected istead. The exception is the case where an
+ * incoming connection triggers a graceful restart.
+ */
+
acc = (p->p.proto_state == PS_START || p->p.proto_state == PS_UP) &&
(p->start_state >= BSS_CONNECT) && (!p->incoming_conn.sk);
@@ -823,6 +829,10 @@ bgp_incoming_connection(sock *sk, int dummy UNUSED)
bgp_handle_graceful_restart(p);
bgp_conn_enter_idle_state(p->conn);
acc = 1;
+
+ /* There might be separate incoming connection in OpenSent state */
+ if (p->incoming_conn.state > BS_ACTIVE)
+ bgp_close_conn(&p->incoming_conn);
}
BGP_TRACE(D_EVENTS, "Incoming connection from %I%J (port %d) %s",