diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2019-04-07 10:52:31 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2019-04-07 10:52:31 +0000 |
commit | a3fbfcf9541945ceb7af025fe7b00d7b2de2afe0 (patch) | |
tree | ee848a4656c8d8175d3c9dbad789273339be93f6 | |
parent | d118c01713e8d4e6c3dbf3f34049e0ddeae7f9e5 (diff) |
Be more careful when setting timeout to 0 because there is pending work
on a peer. Just checking the peer read buffer size is not enough since
the data present could be a partial message and so the SE should sleep
until a new POLLIN event fires. Adjust the logic by adding a rpending
flag that is only set if reading the session buffer was exited early
because MSG_PROCESS_LIMIT was hit.
OK benno@
-rw-r--r-- | usr.sbin/bgpd/session.c | 23 | ||||
-rw-r--r-- | usr.sbin/bgpd/session.h | 3 |
2 files changed, 13 insertions, 13 deletions
diff --git a/usr.sbin/bgpd/session.c b/usr.sbin/bgpd/session.c index 3844916ee39..4ded57c2520 100644 --- a/usr.sbin/bgpd/session.c +++ b/usr.sbin/bgpd/session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: session.c,v 1.377 2019/03/31 16:57:38 claudio Exp $ */ +/* $OpenBSD: session.c,v 1.378 2019/04/07 10:52:30 claudio Exp $ */ /* * Copyright (c) 2003, 2004, 2005 Henning Brauer <henning@openbsd.org> @@ -81,7 +81,7 @@ void session_rrefresh(struct peer *, u_int8_t); int session_graceful_restart(struct peer *); int session_graceful_stop(struct peer *); int session_dispatch_msg(struct pollfd *, struct peer *); -int session_process_msg(struct peer *); +void session_process_msg(struct peer *); int parse_header(struct peer *, u_char *, u_int16_t *, u_int8_t *); int parse_open(struct peer *); int parse_update(struct peer *); @@ -426,7 +426,7 @@ session_main(int debug, int verbose) if (p->wbuf.queued > 0 || p->state == STATE_CONNECT) events |= POLLOUT; /* is there still work to do? */ - if (p->rbuf && p->rbuf->wpos) + if (p->rpending) timeout = 0; /* poll events */ @@ -1779,7 +1779,7 @@ session_dispatch_msg(struct pollfd *pfd, struct peer *p) return (0); } -int +void session_process_msg(struct peer *p) { struct mrt *mrt; @@ -1790,19 +1790,20 @@ session_process_msg(struct peer *p) rpos = 0; av = p->rbuf->wpos; + p->rpending = 0; /* * session might drop to IDLE -> buffers deallocated * we MUST check rbuf != NULL before use */ for (;;) { - if (rpos + MSGSIZE_HEADER > av) - break; if (p->rbuf == NULL) + return; + if (rpos + MSGSIZE_HEADER > av) break; if (parse_header(p, p->rbuf->buf + rpos, &msglen, &msgtype) == -1) - return (0); + return; if (rpos + msglen > av) break; p->rbuf->rptr = p->rbuf->buf + rpos; @@ -1847,11 +1848,11 @@ session_process_msg(struct peer *p) bgp_fsm(p, EVNT_CON_FATAL); } rpos += msglen; - if (++processed > MSG_PROCESS_LIMIT) + if (++processed > MSG_PROCESS_LIMIT) { + p->rpending = 1; break; + } } - if (p->rbuf == NULL) - return (1); if (rpos < av) { left = av - rpos; @@ -1859,8 +1860,6 @@ session_process_msg(struct peer *p) p->rbuf->wpos = left; } else p->rbuf->wpos = 0; - - return (1); } int diff --git a/usr.sbin/bgpd/session.h b/usr.sbin/bgpd/session.h index 22183e2f8e2..c2f30c78fdb 100644 --- a/usr.sbin/bgpd/session.h +++ b/usr.sbin/bgpd/session.h @@ -1,4 +1,4 @@ -/* $OpenBSD: session.h,v 1.135 2019/03/31 16:57:38 claudio Exp $ */ +/* $OpenBSD: session.h,v 1.136 2019/04/07 10:52:30 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -231,6 +231,7 @@ struct peer { u_int8_t demoted; u_int8_t passive; u_int8_t throttled; + u_int8_t rpending; }; extern time_t pauseaccept; |