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 */

Reply via email to