summaryrefslogtreecommitdiff
path: root/sbin/dhcpleased/engine.c
diff options
context:
space:
mode:
authorFlorian Obser <florian@cvs.openbsd.org>2024-02-13 12:53:06 +0000
committerFlorian Obser <florian@cvs.openbsd.org>2024-02-13 12:53:06 +0000
commitd87b7abcce4235763a1c7971d2b1d07ceeb54e10 (patch)
tree01a10fef49448813692a0e2fff11f182dc820593 /sbin/dhcpleased/engine.c
parent2af97a0627e347928a0a032dcb1d303169dc4ddd (diff)
Only generate a new xid at the start of getting a new lease.
"RFC 2131 4.1 Constructing and sending DHCP messages" has this: | Selecting a new 'xid' for each retransmission is an implementation | decision. A client may choose to reuse the same 'xid' or select a new | 'xid' for each retransmitted message. We used to change xid for each request / response cycle but this ran into problems with slow dhcp servers where we would change the xid too frequently and would ignore late coming replies from the server. Andre S points out that table 5 in "4.4.1 Initialization and allocation of network address" says for the xid field in "DHCPREQUEST" messages: | 'xid' from server DHCPOFFER message This seems to suggest that we need to use the same xid for the whole DHCPDISCOVER / DHCPOFFER / DHCPREQUEST / DHCPACK exchange of messages. Nothing else in the RFC is saying this though. But since there are DHCP servers out there that depend on this, we only generate a new xid when entering the INIT, REBOOTING and RENEWING state. I do wonder if we should just go with a static value of 0x04, which was chosen by a fair dice roll, so guaranteed to be random. Issue reported, initial diff and fix tested by Andre S deraadt likes this version OK tb
Diffstat (limited to 'sbin/dhcpleased/engine.c')
-rw-r--r--sbin/dhcpleased/engine.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/sbin/dhcpleased/engine.c b/sbin/dhcpleased/engine.c
index 6d371a5a112..84d02cc12ee 100644
--- a/sbin/dhcpleased/engine.c
+++ b/sbin/dhcpleased/engine.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: engine.c,v 1.42 2024/01/26 21:14:08 jan Exp $ */
+/* $OpenBSD: engine.c,v 1.43 2024/02/13 12:53:05 florian Exp $ */
/*
* Copyright (c) 2017, 2021 Florian Obser <florian@openbsd.org>
@@ -1385,8 +1385,6 @@ state_transition(struct dhcpleased_iface *iface, enum if_state new_state)
char ifnamebuf[IF_NAMESIZE], *if_name;
iface->state = new_state;
- if (new_state != old_state)
- iface->xid = arc4random();
switch (new_state) {
case IF_DOWN:
@@ -1426,6 +1424,7 @@ state_transition(struct dhcpleased_iface *iface, enum if_state new_state)
case IF_DOWN:
case IF_IPV6_ONLY:
iface->timo.tv_sec = START_EXP_BACKOFF;
+ iface->xid = arc4random();
break;
case IF_BOUND:
fatal("invalid transition Bound -> Init");
@@ -1436,8 +1435,10 @@ state_transition(struct dhcpleased_iface *iface, enum if_state new_state)
case IF_REBOOTING:
if (old_state == IF_REBOOTING)
iface->timo.tv_sec *= 2;
- else
+ else {
iface->timo.tv_sec = START_EXP_BACKOFF;
+ iface->xid = arc4random();
+ }
request_dhcp_request(iface);
break;
case IF_REQUESTING:
@@ -1458,6 +1459,7 @@ state_transition(struct dhcpleased_iface *iface, enum if_state new_state)
if (old_state == IF_BOUND) {
iface->timo.tv_sec = (iface->rebinding_time -
iface->renewal_time) / 2; /* RFC 2131 4.4.5 */
+ iface->xid = arc4random();
} else
iface->timo.tv_sec /= 2;