From: David Gwynne Subject: dhcpd(8): make pollfd array slot handling more robust To: tech@openbsd.org Date: Sat, 31 May 2025 16:35:45 +1000 ive been working on a big change to dhcpd internals and hit a problem where this code would get confused about which fd generated which event. this simplifies the handling by storing the pfd index used by the event sources to make it easy to marry them up after poll() returns. i think it's easier to read too. ok? Index: dhcpd.h =================================================================== RCS file: /cvs/src/usr.sbin/dhcpd/dhcpd.h,v diff -u -p -r1.71 dhcpd.h --- dhcpd.h 31 May 2025 01:42:22 -0000 1.71 +++ dhcpd.h 31 May 2025 06:31:46 -0000 @@ -287,6 +287,7 @@ struct protocol { int fd; void (*handler)(struct protocol *); void *local; + int pfd; /* slot used in the pollfd array */ }; #define _PATH_DHCPD_CONF "/etc/dhcpd.conf" Index: dispatch.c =================================================================== RCS file: /cvs/src/usr.sbin/dhcpd/dispatch.c,v diff -u -p -r1.46 dispatch.c --- dispatch.c 31 May 2025 06:27:59 -0000 1.46 +++ dispatch.c 31 May 2025 06:31:46 -0000 @@ -349,13 +349,17 @@ another: /* Set up the descriptors to be polled. */ for (i = 0, l = protocols; l; l = l->next) { - struct interface_info *ip = l->local; - - if (ip && (l->handler != got_one || !ip->dead)) { - fds[i].fd = l->fd; - fds[i].events = POLLIN; - ++i; + if (l->handler == got_one) { + struct interface_info *ip = l->local; + if (ip->dead) { + l->pfd = -1; + continue; + } } + + fds[i].fd = l->fd; + fds[i].events = POLLIN; + l->pfd = i++; } if (i == 0) @@ -378,17 +382,13 @@ another: } time(&cur_time); - for (i = 0, l = protocols; l; l = l->next) { - struct interface_info *ip = l->local; + for (l = protocols; l; l = l->next) { + i = l->pfd; + if (i == -1) + continue; - if ((fds[i].revents & (POLLIN | POLLHUP))) { - if (ip && (l->handler != got_one || - !ip->dead)) - (*(l->handler))(l); - if (interfaces_invalidated) - break; - } - ++i; + if (fds[i].revents & (POLLIN | POLLHUP)) + (*(l->handler))(l); } if ((syncfd != -1) && (fds[i].revents & (POLLIN | POLLHUP))) sync_recv();