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