diff options
author | Kenneth R Westerback <krw@cvs.openbsd.org> | 2020-04-27 15:40:22 +0000 |
---|---|---|
committer | Kenneth R Westerback <krw@cvs.openbsd.org> | 2020-04-27 15:40:22 +0000 |
commit | 5434fbc34e7c41e55b5e59ab0ea73b6070c354ec (patch) | |
tree | e5160dad995fcfcb3778894f2572d836cd62ddbb /sbin/dhclient/dhclient.c | |
parent | a9683be85c07f63aae155cef7c4bce11f4cffddf (diff) |
If the DHCP server disappears between OFFER'ing and ACK'ing a lease,
stop trying to get an ACK from that server after 'timeout'
seconds. Give up and try to get another lease.
Possible infinite loop pointed out by Alexander Markert on tech@.
Diffstat (limited to 'sbin/dhclient/dhclient.c')
-rw-r--r-- | sbin/dhclient/dhclient.c | 45 |
1 files changed, 20 insertions, 25 deletions
diff --git a/sbin/dhclient/dhclient.c b/sbin/dhclient/dhclient.c index 3e8331240ac..e0909a27c0f 100644 --- a/sbin/dhclient/dhclient.c +++ b/sbin/dhclient/dhclient.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dhclient.c,v 1.663 2020/04/26 14:02:23 krw Exp $ */ +/* $OpenBSD: dhclient.c,v 1.664 2020/04/27 15:40:21 krw Exp $ */ /* * Copyright 2004 Henning Brauer <henning@openbsd.org> @@ -814,6 +814,7 @@ state_selecting(struct interface_info *ifi) } ifi->destination.s_addr = INADDR_BROADCAST; + time(&ifi->first_sending); ifi->interval = 0; /* @@ -1460,32 +1461,26 @@ send_request(struct interface_info *ifi) /* Figure out how long it's been since we started transmitting. */ interval = cur_time - ifi->first_sending; - /* - * If we're in the INIT-REBOOT state and we've been trying longer - * than reboot_timeout, go to INIT state and DISCOVER an address. - * - * In the INIT-REBOOT state, if we don't get an ACK, it - * means either that we're on a network with no DHCP server, - * or that our server is down. In the latter case, assuming - * that there is a backup DHCP server, DHCPDISCOVER will get - * us a new address, but we could also have successfully - * reused our old address. In the former case, we're hosed - * anyway. This is not a win-prone situation. - */ - if (ifi->state == S_REBOOTING && interval > - config->reboot_timeout) { + switch (ifi->state) { + case S_REBOOTING: + if (interval > config->reboot_timeout) + ifi->state = S_INIT; + break; + case S_RENEWING: + if (cur_time > ifi->expiry) + ifi->state = S_INIT; + break; + case S_REQUESTING: + if (interval > config->timeout) + ifi->state = S_INIT; + break; + default: + /* Something has gone wrong. Start over. */ ifi->state = S_INIT; - cancel_timeout(ifi); - state_init(ifi); - return; + break; } - - /* - * If the lease has expired go back to the INIT state. - */ - if (ifi->state != S_REQUESTING && cur_time > ifi->expiry) { - ifi->active = NULL; - ifi->state = S_INIT; + if (ifi->state == S_INIT) { + cancel_timeout(ifi); state_init(ifi); return; } |