summaryrefslogtreecommitdiff
path: root/sbin/dhclient
diff options
context:
space:
mode:
Diffstat (limited to 'sbin/dhclient')
-rw-r--r--sbin/dhclient/dhclient.c45
-rw-r--r--sbin/dhclient/dhcpd.h4
2 files changed, 35 insertions, 14 deletions
diff --git a/sbin/dhclient/dhclient.c b/sbin/dhclient/dhclient.c
index b45dc868f6c..8ec981d57bd 100644
--- a/sbin/dhclient/dhclient.c
+++ b/sbin/dhclient/dhclient.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dhclient.c,v 1.710 2021/03/09 14:32:24 krw Exp $ */
+/* $OpenBSD: dhclient.c,v 1.711 2021/03/11 15:30:49 krw Exp $ */
/*
* Copyright 2004 Henning Brauer <henning@openbsd.org>
@@ -807,12 +807,18 @@ state_reboot(struct interface_info *ifi)
void
state_init(struct interface_info *ifi)
{
+ const struct timespec offer_intvl = {config->offer_interval, 0};
+ struct timespec now;
+
ifi->xid = arc4random();
make_discover(ifi, ifi->active);
ifi->destination.s_addr = INADDR_BROADCAST;
ifi->state = S_SELECTING;
- time(&ifi->first_sending);
+ clock_gettime(CLOCK_REALTIME, &now);
+ ifi->first_sending = now.tv_sec;
+ timespecadd(&now, &offer_intvl, &ifi->offer_timeout);
+ ifi->select_timeout = ifi->offer_timeout;
ifi->interval = 0;
send_discover(ifi);
@@ -892,10 +898,11 @@ void
process_offer(struct interface_info *ifi, struct option_data *options,
const char *src)
{
+ const struct timespec select_intvl = {config->select_interval, 0};
+ struct timespec now, remaining;
struct client_lease *lease;
- time_t cur_time, stop_selecting;
- time(&cur_time);
+ clock_gettime(CLOCK_REALTIME, &now);
lease = packet_to_lease(ifi, options);
if (lease != NULL) {
@@ -903,6 +910,10 @@ process_offer(struct interface_info *ifi, struct option_data *options,
ifi->offer = lease;
free(ifi->offer_src);
ifi->offer_src = strdup(src); /* NULL is OK */
+ timespecadd(&now, &select_intvl, &ifi->select_timeout);
+ if (timespeccmp(&ifi->select_timeout,
+ &ifi->offer_timeout, >))
+ ifi->select_timeout = ifi->offer_timeout;
} else if (lease->address.s_addr ==
ifi->offer->address.s_addr) {
/* Decline duplicate offers. */
@@ -920,12 +931,16 @@ process_offer(struct interface_info *ifi, struct option_data *options,
}
}
- /* Figure out when we're supposed to stop selecting. */
- stop_selecting = ifi->first_sending + config->select_interval;
- if (stop_selecting <= cur_time)
+ if (timespeccmp(&now, &ifi->select_timeout, >=))
state_selecting(ifi);
- else
- set_timeout(ifi, stop_selecting - cur_time, state_selecting);
+ else {
+ timespecsub(&ifi->select_timeout, &now, &remaining);
+ if (remaining.tv_sec == 0 || remaining.tv_nsec > 500000000LL)
+ remaining.tv_sec++;
+ log_debug("%s: waiting %lld seconds for better offers",
+ log_procname, (long long)remaining.tv_sec);
+ set_timeout(ifi, remaining.tv_sec, state_selecting);
+ }
}
void
@@ -1378,9 +1393,13 @@ set_interval(struct interface_info *ifi, time_t cur_time)
if (cur_time + interval > ifi->expiry)
interval = ifi->expiry - cur_time;
break;
+ case S_SELECTING:
+ if (cur_time + interval > ifi->select_timeout.tv_sec)
+ interval = ifi->select_timeout.tv_sec - cur_time;
+ break;
case S_REQUESTING:
- if (cur_time + interval > ifi->first_sending + config->offer_interval)
- interval = (ifi->first_sending + config->offer_interval) - cur_time;
+ if (cur_time + interval > ifi->offer_timeout.tv_sec)
+ interval = ifi->offer_timeout.tv_sec - cur_time;
break;
default:
break;
@@ -1420,7 +1439,7 @@ send_discover(struct interface_info *ifi)
clock_gettime(CLOCK_REALTIME, &now);
cur_time = now.tv_sec;
- if (cur_time > ifi->first_sending + config->offer_interval) {
+ if (timespeccmp(&now, &ifi->offer_timeout, >=)) {
state_panic(ifi);
return;
}
@@ -1514,7 +1533,7 @@ send_request(struct interface_info *ifi)
}
break;
case S_REQUESTING:
- if (interval > config->offer_interval)
+ if (timespeccmp(&now, &ifi->offer_timeout, >=))
ifi->state = S_INIT;
else {
destination.sin_addr.s_addr = INADDR_BROADCAST;
diff --git a/sbin/dhclient/dhcpd.h b/sbin/dhclient/dhcpd.h
index 08ac22f3ddd..692a693cda1 100644
--- a/sbin/dhclient/dhcpd.h
+++ b/sbin/dhclient/dhcpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: dhcpd.h,v 1.296 2021/03/09 14:32:24 krw Exp $ */
+/* $OpenBSD: dhcpd.h,v 1.297 2021/03/11 15:30:49 krw Exp $ */
/*
* Copyright (c) 2004 Henning Brauer <henning@openbsd.org>
@@ -141,6 +141,8 @@ struct interface_info {
uint16_t secs;
time_t first_sending;
struct timespec link_timeout;
+ struct timespec offer_timeout;
+ struct timespec select_timeout;
enum dhcp_state state;
struct in_addr destination;
time_t interval;