From: Roy Marples Date: Tue, 17 Sep 2019 08:20:23 +0000 (+0100) Subject: DHCP: Improve from/to address selection X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ed73359d215cc6793e79599794a541e1cdc08d46;p=thirdparty%2Fdhcpcd.git DHCP: Improve from/to address selection While here add a comment about broadcasting over UDP, why we don't do it and why we need BPF. --- diff --git a/src/dhcp.c b/src/dhcp.c index 0a87e036..5e549171 100644 --- a/src/dhcp.c +++ b/src/dhcp.c @@ -1738,15 +1738,32 @@ send_message(struct interface *ifp, uint8_t type, if (r == -1) goto fail; len = (size_t)r; - from.s_addr = bootp->ciaddr; - if (from.s_addr != INADDR_ANY) + + if (ipv4_iffindaddr(ifp, &state->lease.addr, NULL) != NULL) + from.s_addr = state->lease.addr.s_addr; + else + from.s_addr = INADDR_ANY; + if (from.s_addr != INADDR_ANY && + state->lease.server.s_addr != INADDR_ANY) to.s_addr = state->lease.server.s_addr; else - to.s_addr = INADDR_ANY; + to.s_addr = INADDR_BROADCAST; - /* If unicasting, try and avoid sending by BPF so we don't - * use a L2 broadcast. */ - if (to.s_addr != INADDR_ANY && to.s_addr != INADDR_BROADCAST) { + /* + * If not listening on the unspecified address we can + * only receive broadcast messages via BPF. + * Sockets bound to an address cannot receive broadcast messages + * even if they are setup to send them. + * Broadcasting from UDP is only an optimisation for rebinding + * and on BSD, at least, is reliant on the subnet route being + * correctly configured to recieve the unicast reply. + * As such, we always broadcast and receive the reply to it via BPF. + * This also guarantees we have a DHCP server attached to the + * interface we want to configure because we can't dictate the + * interface via IP_PKTINFO unlike for IPv6. + */ + if (to.s_addr != INADDR_BROADCAST) + { if (dhcp_sendudp(ifp, &to, bootp, len) != -1) goto out; logerr("%s: dhcp_sendudp", ifp->name);