From 43a6cd5e20685e537a0f0ad1d8394711988f06c4 Mon Sep 17 00:00:00 2001 From: mbr Date: Mon, 19 Jan 2004 22:07:59 +0000 Subject: If we have a working link again after connectivity loss, or if we need to renew a lease, contact the dhcp-server directly instead of using INADDR_BROADCAST all the time. This should fix some brain-dead dhcp server implementations which give you all the time a new IP if the lease has not yet expired. Instead of using ICMP to check if the server is alive, we just check the return value of sendto() and additionally have a timeout there. --- contrib/isc-dhcp/FREEBSD-upgrade | 1 + contrib/isc-dhcp/client/dhclient.c | 31 +++++++++++++++++++++++++++---- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/contrib/isc-dhcp/FREEBSD-upgrade b/contrib/isc-dhcp/FREEBSD-upgrade index e67b83f..b1c2424 100644 --- a/contrib/isc-dhcp/FREEBSD-upgrade +++ b/contrib/isc-dhcp/FREEBSD-upgrade @@ -46,6 +46,7 @@ Local Changes: r1.6 - document -D option. - remove dhcpd from SEE ALSO section. client/dhclient.c + r1.35 - interface polling r1.32 - interface polling r1.31 - interface polling r1.30 - interface polling diff --git a/contrib/isc-dhcp/client/dhclient.c b/contrib/isc-dhcp/client/dhclient.c index c2e3023..15da9c9 100644 --- a/contrib/isc-dhcp/client/dhclient.c +++ b/contrib/isc-dhcp/client/dhclient.c @@ -1773,6 +1773,19 @@ void send_request (cpp) client -> packet.secs = htons (65535); } + + /* + * Only try the first ten seconds to renew a lease from a + * given dhcp-server adress. After that, fall back to use + * state_reboot with INADDR_BROADCAST. + */ + if (destination.sin_addr.s_addr != INADDR_BROADCAST && + (client -> state == S_RENEWING || client -> state == S_REBINDING)) { + if (client -> active && client -> active -> expiry > cur_time && + interval >= 10) + goto cancel; + } + log_info ("DHCPREQUEST on %s to %s port %d", client -> name ? client -> name : client -> interface -> name, inet_ntoa (destination.sin_addr), @@ -1794,6 +1807,16 @@ void send_request (cpp) from, &destination, (struct hardware *)0); + /* + * If sendto() for a direct request fails, fall back to use + * state_reboot with INADDR_BROADCAST. + */ + if (result == -1 && destination.sin_addr.s_addr != INADDR_BROADCAST && + (client -> state == S_RENEWING || client -> state == S_REBINDING)) { + if (client -> active && client -> active -> expiry > cur_time) + goto cancel; + } + add_timeout (cur_time + client -> interval, send_request, client, 0, 0); } @@ -3413,9 +3436,9 @@ void state_polling (cpp) printf ("%s: Found Link on interface\n", ip -> name); #endif /* - * Set the interface to state_reboot. But of - * course we can not be sure that we really got link, - * we just assume it. + * Set the interface to state_bound. We assume that we have + * a working link. If we cannot reach the server directly, + * INADDR_BROADCAST is used. */ for (client = ip -> client; client; client = client -> next) { @@ -3423,7 +3446,7 @@ void state_polling (cpp) cancel_timeout (state_reboot, client); cancel_timeout (state_selecting, client); add_timeout (cur_time + random () % 5, - state_reboot, client, 0, 0); + state_bound, client, 0, 0); } ip -> linkstate = HAVELINK; } else { -- cgit v1.1