aboutsummaryrefslogtreecommitdiff
path: root/sbin/dhclient
diff options
context:
space:
mode:
authorColin Percival <cperciva@FreeBSD.org>2025-04-08 22:50:01 +0000
committerColin Percival <cperciva@FreeBSD.org>2025-04-13 02:09:56 +0000
commit43d19e6a4c42ade0f276ceca18a09e2e3829fce4 (patch)
treea1224ef3420b42acff5cc81d178d18b04d083059 /sbin/dhclient
parent63578bf225df37944b78febfb177e8c1c81f54e4 (diff)
Diffstat (limited to 'sbin/dhclient')
-rw-r--r--sbin/dhclient/dhclient.c50
-rw-r--r--sbin/dhclient/dhcpd.h4
-rw-r--r--sbin/dhclient/dispatch.c14
3 files changed, 33 insertions, 35 deletions
diff --git a/sbin/dhclient/dhclient.c b/sbin/dhclient/dhclient.c
index 93988d5ce7a4..cbab3fa2973c 100644
--- a/sbin/dhclient/dhclient.c
+++ b/sbin/dhclient/dhclient.c
@@ -90,8 +90,8 @@
cap_channel_t *capsyslog;
-time_t cur_time;
-struct timespec time_now;
+time_t cur_time; /* Seconds since epoch. */
+struct timespec time_now; /* CLOCK_MONOTONIC. */
static time_t default_lease_time = 43200; /* 12 hours... */
const char *path_dhclient_conf = _PATH_DHCLIENT_CONF;
@@ -450,7 +450,7 @@ main(int argc, char *argv[])
tzset();
clock_gettime(CLOCK_MONOTONIC, &time_now);
- cur_time = time_now.tv_sec;
+ cur_time = time(NULL);
inaddr_broadcast.s_addr = INADDR_BROADCAST;
inaddr_any.s_addr = INADDR_ANY;
@@ -1030,13 +1030,13 @@ dhcpoffer(struct packet *packet)
struct client_lease *lease, *lp;
int i;
struct timespec arp_timeout_needed;
- struct timespec stop_selecting = { .tv_sec = 0, .tv_nsec = 0 };
- time_now.tv_sec = cur_time;
- time_now.tv_nsec = 0;
-
+ time_t stop_selecting;
+ struct timespec stop_time;
const char *name = packet->options[DHO_DHCP_MESSAGE_TYPE].len ?
"DHCPOFFER" : "BOOTREPLY";
+ clock_gettime(CLOCK_MONOTONIC, &time_now);
+
/* If we're not receptive to an offer right now, or if the offer
has an unrecognizable transaction id, then just drop it. */
if (ip->client->state != S_SELECTING ||
@@ -1095,7 +1095,7 @@ dhcpoffer(struct packet *packet)
arp_timeout_needed = arp_timeout;
/* Figure out when we're supposed to stop selecting. */
- stop_selecting.tv_sec =
+ stop_selecting =
ip->client->first_sending + ip->client->config->select_interval;
/* If this is the lease we asked for, put it at the head of the
@@ -1116,7 +1116,7 @@ dhcpoffer(struct packet *packet)
timespecadd(&time_now, &arp_timeout_needed, &interm_struct);
if (ip->client->offered_leases &&
- timespeccmp(&interm_struct, &stop_selecting, >))
+ interm_struct.tv_sec >= stop_selecting)
arp_timeout_needed = zero_timespec;
/* Put the lease at the end of the list. */
@@ -1131,27 +1131,21 @@ dhcpoffer(struct packet *packet)
}
}
- /* If we're supposed to stop selecting before we've had time
- to wait for the ARPREPLY, add some delay to wait for
- the ARPREPLY. */
- struct timespec time_left;
- timespecsub(&stop_selecting, &time_now, &time_left);
-
+ /*
+ * Wait until stop_selecting seconds past the epoch, or until
+ * arp_timeout_needed past now, whichever is longer. Note that
+ * the first case only occurs if select-timeout is set to nonzero
+ * in dhclient.conf.
+ */
+ struct timespec time_left =
+ {.tv_sec = stop_selecting - cur_time, .tv_nsec = 0};
if (timespeccmp(&time_left, &arp_timeout_needed, <)) {
- timespecadd(&time_now, &arp_timeout_needed, &stop_selecting);
- }
-
- /* If the selecting interval has expired, go immediately to
- state_selecting(). Otherwise, time out into
- state_selecting at the select interval. */
-
-
- if (timespeccmp(&stop_selecting, &zero_timespec, <=))
- state_selecting(ip);
- else {
- add_timeout_timespec(stop_selecting, state_selecting, ip);
- cancel_timeout(send_discover, ip);
+ timespecadd(&time_now, &arp_timeout_needed, &stop_time);
+ } else {
+ timespecadd(&time_now, &time_left, &stop_time);
}
+ add_timeout_timespec(stop_time, state_selecting, ip);
+ cancel_timeout(send_discover, ip);
}
/* Allocate a client_lease structure and initialize it from the parameters
diff --git a/sbin/dhclient/dhcpd.h b/sbin/dhclient/dhcpd.h
index 6f1f6679875c..c61564067598 100644
--- a/sbin/dhclient/dhcpd.h
+++ b/sbin/dhclient/dhcpd.h
@@ -361,8 +361,8 @@ char *piaddr(struct iaddr);
extern cap_channel_t *capsyslog;
extern const char *path_dhclient_conf;
extern char *path_dhclient_db;
-extern struct timespec time_now;
-extern time_t cur_time;
+extern struct timespec time_now; /* CLOCK_MONOTONIC */
+extern time_t cur_time; /* Seconds since epoch */
extern int log_priority;
extern int log_perror;
diff --git a/sbin/dhclient/dispatch.c b/sbin/dhclient/dispatch.c
index 72230c01a491..06bd31e5ec82 100644
--- a/sbin/dhclient/dispatch.c
+++ b/sbin/dhclient/dispatch.c
@@ -159,8 +159,8 @@ dispatch(void)
struct protocol *l;
struct pollfd *fds;
struct timespec howlong;
- time_now.tv_sec = cur_time;
- time_now.tv_nsec = 0;
+
+ clock_gettime(CLOCK_MONOTONIC, &time_now);
for (l = protocols; l; l = l->next)
nfds++;
@@ -224,7 +224,7 @@ another:
if (count == -1) {
if (errno == EAGAIN || errno == EINTR) {
clock_gettime(CLOCK_MONOTONIC, &time_now);
- cur_time = time_now.tv_sec;
+ cur_time = time(NULL);
continue;
} else
error("poll: %m");
@@ -232,7 +232,7 @@ another:
/* Get the current time... */
clock_gettime(CLOCK_MONOTONIC, &time_now);
- cur_time = time_now.tv_sec;
+ cur_time = time(NULL);
i = 0;
for (l = protocols; l; l = l->next) {
@@ -365,7 +365,11 @@ active:
void
add_timeout(time_t when_s, void (*where)(void *), void *what)
{
- struct timespec when = { .tv_sec = when_s, .tv_nsec = 0 };
+ struct timespec when;
+
+ cur_time = time(NULL);
+ clock_gettime(CLOCK_MONOTONIC, &when);
+ when.tv_sec += when_s - cur_time;
add_timeout_timespec(when, where, what);
}