From 32bab3b6920ec1e662677c4467903c68962a5caf Mon Sep 17 00:00:00 2001 From: cheloha Date: Tue, 2 Feb 2021 15:46:16 +0000 Subject: [PATCH] dhclient(8): fork_privchld, take_charge, propose_release: poll(2) -> ppoll(2) Switch from poll(2) to ppoll(2) in a few more functions. Because we're working with ppoll(2) and clock_gettime(2) it is easier to encode the various timeouts as static const timespecs instead of preprocessor macros. This way we aren't packing timespecs in the middle of the code, which distracts from the (more important) logic of what the code is doing. Part of a larger campaign improve "time stuff" in dhclient(8). Prompted by and discussed with krw@. Based on a diff by krw@. ok krw@ --- sbin/dhclient/dhclient.c | 63 +++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/sbin/dhclient/dhclient.c b/sbin/dhclient/dhclient.c index 23fa185ec8c..8790a7f4be1 100644 --- a/sbin/dhclient/dhclient.c +++ b/sbin/dhclient/dhclient.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dhclient.c,v 1.690 2020/12/10 18:35:31 krw Exp $ */ +/* $OpenBSD: dhclient.c,v 1.691 2021/02/02 15:46:16 cheloha Exp $ */ /* * Copyright 2004 Henning Brauer @@ -2367,11 +2367,11 @@ fork_privchld(struct interface_info *ifi, int fd, int fd2) pfd[0].fd = priv_ibuf->fd; pfd[0].events = POLLIN; - nfds = poll(pfd, 1, INFTIM); + nfds = ppoll(pfd, 1, NULL, NULL); if (nfds == -1) { if (errno == EINTR) continue; - log_warn("%s: poll(priv_ibuf)", log_procname); + log_warn("%s: ppoll(priv_ibuf)", log_procname); break; } if ((pfd[0].revents & (POLLERR | POLLHUP | POLLNVAL)) != 0) @@ -2531,18 +2531,17 @@ cleanup: int take_charge(struct interface_info *ifi, int routefd, char *leasespath) { + const struct timespec max_timeout = { 9, 0 }; + const struct timespec resend_intvl = { 3, 0 }; + const struct timespec leasefile_intvl = { 0, 3000000 }; + struct timespec now, resend, stop, timeout; struct pollfd fds[1]; struct rt_msghdr rtm; - time_t cur_time, sent_time, start_time; int fd, nfds; -#define MAXSECONDS 9 -#define SENTSECONDS 3 -#define POLLMILLISECONDS 3 - - if (time(&start_time) == -1) - fatal("time"); - sent_time = start_time; + clock_gettime(CLOCK_REALTIME, &now); + resend = now; + timespecadd(&now, &max_timeout, &stop); /* * Send RTM_PROPOSAL with RTF_PROTO3 set. @@ -2561,32 +2560,35 @@ take_charge(struct interface_info *ifi, int routefd, char *leasespath) rtm.rtm_addrs = 0; rtm.rtm_flags = RTF_UP | RTF_PROTO3; - rtm.rtm_seq = ifi->xid = arc4random(); - if (write(routefd, &rtm, sizeof(rtm)) == -1) - fatal("write(routefd)"); - for (fd = -1; fd == -1 && quit != TERMINATE;) { - if (time(&cur_time) == -1) - fatal("time"); - if (cur_time - start_time >= MAXSECONDS) + clock_gettime(CLOCK_REALTIME, &now); + if (timespeccmp(&now, &stop, >=)) fatalx("failed to take charge"); if ((ifi->flags & IFI_IN_CHARGE) == 0) { - if ((cur_time - sent_time) >= SENTSECONDS) { - sent_time = cur_time; + if (timespeccmp(&now, &resend, >=)) { + timespecadd(&resend, &resend_intvl, &resend); rtm.rtm_seq = ifi->xid = arc4random(); if (write(routefd, &rtm, sizeof(rtm)) == -1) fatal("write(routefd)"); } + timespecsub(&resend, &now, &timeout); + } else { + /* + * Keep trying to open leasefile in 3ms intervals + * while continuing to process any RTM_* messages + * that come in. + */ + timeout = leasefile_intvl; } fds[0].fd = routefd; fds[0].events = POLLIN; - nfds = poll(fds, 1, POLLMILLISECONDS); + nfds = ppoll(fds, 1, &timeout, NULL); if (nfds == -1) { if (errno == EINTR) continue; - fatal("poll(routefd)"); + fatal("ppoll(routefd)"); } if ((fds[0].revents & (POLLERR | POLLHUP | POLLNVAL)) != 0) @@ -2801,13 +2803,14 @@ release_lease(struct interface_info *ifi) void propose_release(struct interface_info *ifi) { + const struct timespec max_timeout = { 3, 0 }; + struct timespec now, stop, timeout; struct pollfd fds[1]; struct rt_msghdr rtm; - time_t start_time, cur_time; int nfds, routefd, rtfilter; - if (time(&start_time) == -1) - fatal("time"); + clock_gettime(CLOCK_REALTIME, &now); + timespecadd(&now, &max_timeout, &stop); if ((routefd = socket(AF_ROUTE, SOCK_RAW, AF_INET)) == -1) fatal("socket(AF_ROUTE, SOCK_RAW)"); @@ -2838,17 +2841,17 @@ propose_release(struct interface_info *ifi) log_debug("%s: sent RTM_PROPOSAL to release lease", log_procname); while (quit == 0) { - if (time(&cur_time) == -1) - fatal("time"); - if ((cur_time - start_time) > 3) + clock_gettime(CLOCK_REALTIME, &now); + if (timespeccmp(&now, &stop, >=)) break; + timespecsub(&stop, &now, &timeout); fds[0].fd = routefd; fds[0].events = POLLIN; - nfds = poll(fds, 1, 3); + nfds = ppoll(fds, 1, &timeout, NULL); if (nfds == -1) { if (errno == EINTR) continue; - fatal("poll(routefd)"); + fatal("ppoll(routefd)"); } if ((fds[0].revents & (POLLERR | POLLHUP | POLLNVAL)) != 0) fatalx("routefd: ERR|HUP|NVAL"); -- 2.20.1