On Wed, Oct 21, 2020 at 07:16:07PM +0200, Claudio Jeker wrote: > This refactors the control code a bit and removes the common var from the > session.h header. The session engine no longer walks the control > connection list. Additionally cleanup the control.c code around > control_dispatch_msg(). E.g. don't do double lookups of control sessions > by fd to close them. > > OK?
Ping -- :wq Claudio Index: control.c =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/control.c,v retrieving revision 1.100 diff -u -p -r1.100 control.c --- control.c 10 May 2020 13:38:46 -0000 1.100 +++ control.c 21 Oct 2020 16:57:53 -0000 @@ -29,11 +29,13 @@ #include "session.h" #include "log.h" +TAILQ_HEAD(ctl_conns, ctl_conn) ctl_conns = TAILQ_HEAD_INITIALIZER(ctl_conns); + #define CONTROL_BACKLOG 5 struct ctl_conn *control_connbyfd(int); struct ctl_conn *control_connbypid(pid_t); -int control_close(int); +int control_close(struct ctl_conn *); void control_result(struct ctl_conn *, u_int); ssize_t imsg_read_nofd(struct imsgbuf *); @@ -136,6 +138,22 @@ control_shutdown(int fd) close(fd); } +size_t +control_fill_pfds(struct pollfd *pfd, size_t size) +{ + struct ctl_conn *ctl_conn; + size_t i = 0; + + TAILQ_FOREACH(ctl_conn, &ctl_conns, entry) { + pfd[i].fd = ctl_conn->ibuf.fd; + pfd[i].events = POLLIN; + if (ctl_conn->ibuf.w.queued > 0) + pfd[i].events |= POLLOUT; + i++; + } + return i; +} + unsigned int control_accept(int listenfd, int restricted) { @@ -198,15 +216,8 @@ control_connbypid(pid_t pid) } int -control_close(int fd) +control_close(struct ctl_conn *c) { - struct ctl_conn *c; - - if ((c = control_connbyfd(fd)) == NULL) { - log_warn("control_close: fd %d: not found", fd); - return (0); - } - if (c->terminate && c->ibuf.pid) imsg_ctl_rde(IMSG_CTL_TERMINATE, c->ibuf.pid, NULL, 0); @@ -220,8 +231,7 @@ control_close(int fd) } int -control_dispatch_msg(struct pollfd *pfd, u_int *ctl_cnt, - struct peer_head *peers) +control_dispatch_msg(struct pollfd *pfd, struct peer_head *peers) { struct imsg imsg; struct ctl_conn *c; @@ -237,10 +247,8 @@ control_dispatch_msg(struct pollfd *pfd, } if (pfd->revents & POLLOUT) { - if (msgbuf_write(&c->ibuf.w) <= 0 && errno != EAGAIN) { - *ctl_cnt -= control_close(pfd->fd); - return (1); - } + if (msgbuf_write(&c->ibuf.w) <= 0 && errno != EAGAIN) + return control_close(c); if (c->throttled && c->ibuf.w.queued < CTL_MSG_LOW_MARK) { if (imsg_ctl_rde(IMSG_XON, c->ibuf.pid, NULL, 0) != -1) c->throttled = 0; @@ -251,16 +259,12 @@ control_dispatch_msg(struct pollfd *pfd, return (0); if (((n = imsg_read_nofd(&c->ibuf)) == -1 && errno != EAGAIN) || - n == 0) { - *ctl_cnt -= control_close(pfd->fd); - return (1); - } + n == 0) + return control_close(c); for (;;) { - if ((n = imsg_get(&c->ibuf, &imsg)) == -1) { - *ctl_cnt -= control_close(pfd->fd); - return (1); - } + if ((n = imsg_get(&c->ibuf, &imsg)) == -1) + return control_close(c); if (n == 0) break; Index: session.c =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/session.c,v retrieving revision 1.402 diff -u -p -r1.402 session.c --- session.c 27 Jun 2020 07:24:42 -0000 1.402 +++ session.c 21 Oct 2020 16:49:10 -0000 @@ -196,7 +196,6 @@ session_main(int debug, int verbose) struct peer *p, **peer_l = NULL, *next; struct mrt *m, *xm, **mrt_l = NULL; struct pollfd *pfd = NULL; - struct ctl_conn *ctl_conn; struct listen_addr *la; void *newp; time_t now; @@ -237,7 +236,6 @@ session_main(int debug, int verbose) fatal(NULL); imsg_init(ibuf_main, 3); - TAILQ_INIT(&ctl_conns); LIST_INIT(&mrthead); listener_cnt = 0; peer_cnt = 0; @@ -438,13 +436,10 @@ session_main(int debug, int verbose) idx_mrts = i; - TAILQ_FOREACH(ctl_conn, &ctl_conns, entry) { - pfd[i].fd = ctl_conn->ibuf.fd; - pfd[i].events = POLLIN; - if (ctl_conn->ibuf.w.queued > 0) - pfd[i].events |= POLLOUT; - i++; - } + i += control_fill_pfds(pfd + i, pfd_elms -i); + + if (i > pfd_elms) + fatalx("poll pfd overflow"); if (pauseaccept && timeout > 1) timeout = 1; @@ -511,7 +506,7 @@ session_main(int debug, int verbose) mrt_write(mrt_l[j - idx_peers]); for (; j < i; j++) - control_dispatch_msg(&pfd[j], &ctl_cnt, &conf->peers); + ctl_cnt -= control_dispatch_msg(&pfd[j], &conf->peers); } RB_FOREACH_SAFE(p, peer_head, &conf->peers, next) { Index: session.h =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/session.h,v retrieving revision 1.146 diff -u -p -r1.146 session.h --- session.h 10 May 2020 13:38:46 -0000 1.146 +++ session.h 21 Oct 2020 16:49:43 -0000 @@ -146,8 +146,6 @@ struct ctl_conn { int terminate; }; -TAILQ_HEAD(ctl_conns, ctl_conn) ctl_conns; - struct peer_stats { unsigned long long msg_rcvd_open; unsigned long long msg_rcvd_update; @@ -260,8 +258,9 @@ int prepare_listeners(struct bgpd_confi int control_check(char *); int control_init(int, char *); int control_listen(int); +size_t control_fill_pfds(struct pollfd *, size_t); void control_shutdown(int); -int control_dispatch_msg(struct pollfd *, u_int *, struct peer_head *); +int control_dispatch_msg(struct pollfd *, struct peer_head *); unsigned int control_accept(int, int); /* log.c */