From dc1188bb4d5be4df3f04a5448b85d23b895bd7db Mon Sep 17 00:00:00 2001 From: Quentin Young Date: Thu, 6 Apr 2017 23:45:57 +0000 Subject: [PATCH] bgpd: correctly schedule select() at session startup On TCP connection failure during session setup, bgp_stop() checks whether peer->t_read is non-null to know whether or not to unschedule select() on peer->fd before calling close() on it. Using the API exposed by thread.c instead of bgpd's wrapper macro BGP_READ_ON() results in this thread value never being set, which causes bgp_stop() to skip the cancellation of select() before calling close(). Subsequent calls to select() on that fd crash the daemon. Use the macro instead. Signed-off-by: Quentin Young --- bgpd/bgp_fsm.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index 3344bf3126..d965b49c49 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -1176,6 +1176,10 @@ static int bgp_connect_check(struct thread *thread) peer = THREAD_ARG(thread); + /* This value needs to be unset in order for bgp_read() to be scheduled + */ + BGP_READ_OFF(peer->t_read); + /* Check file descriptor. */ slen = sizeof(status); ret = getsockopt(peer->fd, SOL_SOCKET, SO_ERROR, (void *)&status, @@ -1356,7 +1360,7 @@ int bgp_start(struct peer *peer) // when the socket becomes ready (or fails to connect), // bgp_connect_check // will be called. - thread_add_read(bm->master, bgp_connect_check, peer, peer->fd); + BGP_READ_ON(peer->t_read, bgp_connect_check, peer->fd); break; } return 0; -- 2.39.5