summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormbr <mbr@FreeBSD.org>2004-01-19 22:07:59 +0000
committermbr <mbr@FreeBSD.org>2004-01-19 22:07:59 +0000
commit43a6cd5e20685e537a0f0ad1d8394711988f06c4 (patch)
tree62d1ac8d62d71de66aef65ab5cac999cf3163df5
parentaf431306cd5bfd8ee4e300cb51a2dd9879ee376e (diff)
downloadFreeBSD-src-43a6cd5e20685e537a0f0ad1d8394711988f06c4.zip
FreeBSD-src-43a6cd5e20685e537a0f0ad1d8394711988f06c4.tar.gz
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.
-rw-r--r--contrib/isc-dhcp/FREEBSD-upgrade1
-rw-r--r--contrib/isc-dhcp/client/dhclient.c31
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 {
OpenPOWER on IntegriCloud