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.
This commit is contained in:
mbr 2004-01-19 22:07:59 +00:00
parent af431306cd
commit 43a6cd5e20
2 changed files with 28 additions and 4 deletions

View File

@ -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

View File

@ -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 {