2
0
mirror of https://gitlab.isc.org/isc-projects/dhcp synced 2025-08-31 22:35:25 +00:00

Move top_level_config to clparse.c; use more defaults from client config structure; be less noisy about broadcasts that aren't for us; fix up exponential backoff code; time out in REQUESTING state if server doesn't ACK; record how long we've been trying to boot in the DHCP packet.

This commit is contained in:
Ted Lemon
1997-03-28 23:57:47 +00:00
parent 8262070795
commit 34fdad6c77

View File

@@ -56,7 +56,7 @@
#ifndef lint #ifndef lint
static char copyright[] = static char copyright[] =
"$Id: dhclient.c,v 1.33 1997/03/06 20:13:42 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n"; "$Id: dhclient.c,v 1.34 1997/03/28 23:57:47 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */ #endif /* not lint */
#include "dhcpd.h" #include "dhcpd.h"
@@ -66,8 +66,6 @@ TIME default_lease_time = 43200; /* 12 hours... */
TIME max_lease_time = 86400; /* 24 hours... */ TIME max_lease_time = 86400; /* 24 hours... */
struct tree_cache *global_options [256]; struct tree_cache *global_options [256];
struct client_config top_level_config;
char *path_dhclient_conf = _PATH_DHCLIENT_CONF; char *path_dhclient_conf = _PATH_DHCLIENT_CONF;
char *path_dhclient_db = _PATH_DHCLIENT_DB; char *path_dhclient_db = _PATH_DHCLIENT_DB;
char *path_dhclient_pid = _PATH_DHCLIENT_PID; char *path_dhclient_pid = _PATH_DHCLIENT_PID;
@@ -274,7 +272,7 @@ void state_reboot (ipp)
ip -> client -> xid = ip -> client -> packet.xid; ip -> client -> xid = ip -> client -> packet.xid;
ip -> client -> destination = iaddr_broadcast; ip -> client -> destination = iaddr_broadcast;
ip -> client -> first_sending = cur_time; ip -> client -> first_sending = cur_time;
ip -> client -> interval = 0; ip -> client -> interval = ip -> client -> config -> initial_interval;
/* Add an immediate timeout to cause the first DHCPDISCOVER packet /* Add an immediate timeout to cause the first DHCPDISCOVER packet
to go out. */ to go out. */
@@ -298,7 +296,7 @@ void state_init (ipp)
ip -> client -> destination = iaddr_broadcast; ip -> client -> destination = iaddr_broadcast;
ip -> client -> state = S_SELECTING; ip -> client -> state = S_SELECTING;
ip -> client -> first_sending = cur_time; ip -> client -> first_sending = cur_time;
ip -> client -> interval = 0; ip -> client -> interval = ip -> client -> config -> initial_interval;
/* Add an immediate timeout to cause the first DHCPDISCOVER packet /* Add an immediate timeout to cause the first DHCPDISCOVER packet
to go out. */ to go out. */
@@ -365,7 +363,7 @@ void state_selecting (ipp)
ip -> client -> destination = iaddr_broadcast; ip -> client -> destination = iaddr_broadcast;
ip -> client -> state = S_REQUESTING; ip -> client -> state = S_REQUESTING;
ip -> client -> first_sending = cur_time; ip -> client -> first_sending = cur_time;
ip -> client -> interval = 0; ip -> client -> interval = ip -> client -> config -> initial_interval;
/* Make a DHCPREQUEST packet from the lease we picked. */ /* Make a DHCPREQUEST packet from the lease we picked. */
make_request (ip, picked); make_request (ip, picked);
@@ -388,15 +386,10 @@ void dhcpack (packet)
struct client_lease *lease; struct client_lease *lease;
int i; int i;
note ("DHCPACK from %s",
print_hw_addr (packet -> raw -> htype,
packet -> raw -> hlen,
packet -> raw -> chaddr));
/* If we're not receptive to an offer right now, or if the offer /* If we're not receptive to an offer right now, or if the offer
has an unrecognizable transaction id, then just drop it. */ has an unrecognizable transaction id, then just drop it. */
if (packet -> interface -> client -> xid != packet -> raw -> xid) { if (packet -> interface -> client -> xid != packet -> raw -> xid) {
note ("DHCPACK in wrong transaction."); debug ("DHCPACK in wrong transaction.");
return; return;
} }
@@ -404,10 +397,15 @@ void dhcpack (packet)
ip -> client -> state != S_REQUESTING && ip -> client -> state != S_REQUESTING &&
ip -> client -> state != S_RENEWING && ip -> client -> state != S_RENEWING &&
ip -> client -> state != S_REBINDING) { ip -> client -> state != S_REBINDING) {
note ("DHCPACK in wrong state."); debug ("DHCPACK in wrong state.");
return; return;
} }
note ("DHCPACK from %s",
print_hw_addr (packet -> raw -> htype,
packet -> raw -> hlen,
packet -> raw -> chaddr));
lease = packet_to_lease (packet); lease = packet_to_lease (packet);
if (!lease) { if (!lease) {
note ("packet_to_lease failed."); note ("packet_to_lease failed.");
@@ -513,7 +511,7 @@ void state_bound (ipp)
ip -> client -> destination = iaddr_broadcast; ip -> client -> destination = iaddr_broadcast;
ip -> client -> first_sending = cur_time; ip -> client -> first_sending = cur_time;
ip -> client -> interval = 0; ip -> client -> interval = ip -> client -> config -> initial_interval;
ip -> client -> state = S_RENEWING; ip -> client -> state = S_RENEWING;
/* Send the first packet immediately. */ /* Send the first packet immediately. */
@@ -573,12 +571,6 @@ void dhcpoffer (packet)
int i; int i;
int arp_timeout_needed, stop_selecting; int arp_timeout_needed, stop_selecting;
note ("DHCPOFFER from %s",
print_hw_addr (packet -> raw -> htype,
packet -> raw -> hlen,
packet -> raw -> chaddr));
#ifdef DEBUG_PACKET #ifdef DEBUG_PACKET
dump_packet (packet); dump_packet (packet);
#endif #endif
@@ -587,10 +579,15 @@ void dhcpoffer (packet)
has an unrecognizable transaction id, then just drop it. */ has an unrecognizable transaction id, then just drop it. */
if (ip -> client -> state != S_SELECTING || if (ip -> client -> state != S_SELECTING ||
packet -> interface -> client -> xid != packet -> raw -> xid) { packet -> interface -> client -> xid != packet -> raw -> xid) {
note ("DHCPOFFER in wrong transaction."); debug ("DHCPOFFER in wrong transaction.");
return; return;
} }
note ("DHCPOFFER from %s",
print_hw_addr (packet -> raw -> htype,
packet -> raw -> hlen,
packet -> raw -> chaddr));
/* If this lease doesn't supply the minimum required parameters, /* If this lease doesn't supply the minimum required parameters,
blow it off. */ blow it off. */
for (i = 0; ip -> client -> config -> required_options [i]; i++) { for (i = 0; ip -> client -> config -> required_options [i]; i++) {
@@ -607,7 +604,7 @@ void dhcpoffer (packet)
if (lease -> address.len == sizeof packet -> raw -> yiaddr && if (lease -> address.len == sizeof packet -> raw -> yiaddr &&
!memcmp (lease -> address.iabuf, !memcmp (lease -> address.iabuf,
&packet -> raw -> yiaddr, lease -> address.len)) { &packet -> raw -> yiaddr, lease -> address.len)) {
note ("DHCPOFFER already seen."); debug ("DHCPOFFER already seen.");
return; return;
} }
} }
@@ -773,15 +770,10 @@ void dhcpnak (packet)
{ {
struct interface_info *ip = packet -> interface; struct interface_info *ip = packet -> interface;
note ("DHCPNAK from %s",
print_hw_addr (packet -> raw -> htype,
packet -> raw -> hlen,
packet -> raw -> chaddr));
/* If we're not receptive to an offer right now, or if the offer /* If we're not receptive to an offer right now, or if the offer
has an unrecognizable transaction id, then just drop it. */ has an unrecognizable transaction id, then just drop it. */
if (packet -> interface -> client -> xid != packet -> raw -> xid) { if (packet -> interface -> client -> xid != packet -> raw -> xid) {
note ("DHCPNAK in wrong transaction."); debug ("DHCPNAK in wrong transaction.");
return; return;
} }
@@ -789,10 +781,15 @@ void dhcpnak (packet)
ip -> client -> state != S_REQUESTING && ip -> client -> state != S_REQUESTING &&
ip -> client -> state != S_RENEWING && ip -> client -> state != S_RENEWING &&
ip -> client -> state != S_REBINDING) { ip -> client -> state != S_REBINDING) {
note ("DHCPNAK in wrong state."); debug ("DHCPNAK in wrong state.");
return; return;
} }
note ("DHCPNAK from %s",
print_hw_addr (packet -> raw -> htype,
packet -> raw -> hlen,
packet -> raw -> chaddr));
if (!ip -> client -> active) { if (!ip -> client -> active) {
note ("DHCPNAK with no active lease.\n"); note ("DHCPNAK with no active lease.\n");
return; return;
@@ -869,18 +866,24 @@ void send_discover (ipp)
will double with every transmission. */ will double with every transmission. */
if (increase) { if (increase) {
if (!ip -> client -> interval) if (!ip -> client -> interval)
ip -> client -> interval = 1; ip -> client -> interval =
ip -> client -> config -> initial_interval;
else { else {
ip -> client -> interval += ip -> client -> interval +=
random () % (2 * ip -> client -> interval); ((random () >> 2) %
(2 * ip -> client -> interval));
} }
/* Don't backoff past 30 seconds. */ /* Don't backoff past cutoff. */
if (ip -> client -> interval > 30) if (ip -> client -> interval >
ip -> client -> config -> backoff_cutoff)
ip -> client -> interval = ip -> client -> interval =
15 + random () % ip -> client -> interval; ((ip -> client -> config -> backoff_cutoff / 2)
+ ((random () >> 2)
% ip -> client -> interval));
} else if (!ip -> client -> interval) } else if (!ip -> client -> interval)
ip -> client -> interval = 1; ip -> client -> interval =
ip -> client -> config -> initial_interval;
/* If the backoff would take us to the panic timeout, just use that /* If the backoff would take us to the panic timeout, just use that
as the interval. */ as the interval. */
@@ -895,6 +898,12 @@ void send_discover (ipp)
inet_ntoa (sockaddr_broadcast.sin_addr), inet_ntoa (sockaddr_broadcast.sin_addr),
ntohs (sockaddr_broadcast.sin_port), ip -> client -> interval); ntohs (sockaddr_broadcast.sin_port), ip -> client -> interval);
/* Record the number of seconds since we started sending. */
if (interval < 255)
ip -> client -> packet -> secs = interval;
else
ip -> client -> packet -> secs = 255;
/* Send out a packet. */ /* Send out a packet. */
result = send_packet (ip, (struct packet *)0, result = send_packet (ip, (struct packet *)0,
&ip -> client -> packet, &ip -> client -> packet,
@@ -981,7 +990,9 @@ void state_panic (ipp)
for (lp = ip -> client -> leases; lp -> next; lp = lp -> next) for (lp = ip -> client -> leases; lp -> next; lp = lp -> next)
; ;
lp -> next = ip -> client -> active; lp -> next = ip -> client -> active;
lp -> next -> next = (struct client_lease *)0; if (lp -> next) {
lp -> next -> next = (struct client_lease *)0;
}
ip -> client -> active = ip -> client -> leases; ip -> client -> active = ip -> client -> leases;
ip -> client -> leases = ip -> client -> leases -> next; ip -> client -> leases = ip -> client -> leases -> next;
@@ -1018,15 +1029,18 @@ void send_request (ipp)
/* Figure out how long it's been since we started transmitting. */ /* Figure out how long it's been since we started transmitting. */
interval = cur_time - ip -> client -> first_sending; interval = cur_time - ip -> client -> first_sending;
/* If we're in INIT-REBOOT and we're past the reboot timeout, /* If we're in the INIT-REBOOT or REQUESTING state and we're
go to INIT and see if we can DISCOVER an address... */ past the reboot timeout, go to INIT and see if we can
/* XXX if we don't get an ACK, it means either that we're on DISCOVER an address... */
a network with no DHCP server, or that our server is down. /* XXX In the INIT-REBOOT state, if we don't get an ACK, it
In the latter case, DHCPDISCOVER will get us a new address, means either that we're on a network with no DHCP server,
but we could also have successfully reused our old address. or that our server is down. In the latter case, assuming
In the former case, we're hosed anyway. This is not a win-prone that there is a backup DHCP server, DHCPDISCOVER will get
situation. */ us a new address, but we could also have successfully
if (ip -> client -> state == S_REBOOTING && reused our old address. In the former case, we're hosed
anyway. This is not a win-prone situation. */
if ((ip -> client -> state == S_REBOOTING ||
ip -> client -> state == S_REQUESTING) &&
interval > ip -> client -> config -> reboot_timeout) { interval > ip -> client -> config -> reboot_timeout) {
ip -> client -> state = S_INIT; ip -> client -> state = S_INIT;
cancel_timeout (send_request, ip); cancel_timeout (send_request, ip);
@@ -1053,15 +1067,21 @@ void send_request (ipp)
/* Do the exponential backoff... */ /* Do the exponential backoff... */
if (!ip -> client -> interval) if (!ip -> client -> interval)
ip -> client -> interval = 1;
else
ip -> client -> interval +=
random () % (2 * ip -> client -> interval);
/* Don't backoff past 30 seconds. */
if (ip -> client -> interval > 30)
ip -> client -> interval = ip -> client -> interval =
15 + random () % ip -> client -> interval; ip -> client -> config -> initial_interval;
else {
ip -> client -> interval +=
((random () >> 2) %
(2 * ip -> client -> interval));
}
/* Don't backoff past cutoff. */
if (ip -> client -> interval >
ip -> client -> config -> backoff_cutoff)
ip -> client -> interval =
((ip -> client -> config -> backoff_cutoff / 2)
+ ((random () >> 2)
% ip -> client -> interval));
/* If the backoff would take us to the expiry time, just set the /* If the backoff would take us to the expiry time, just set the
timeout to the expiry time. */ timeout to the expiry time. */
@@ -1092,6 +1112,12 @@ void send_request (ipp)
else else
from.s_addr = INADDR_ANY; from.s_addr = INADDR_ANY;
/* Record the number of seconds since we started sending. */
if (interval < 255)
ip -> client -> packet -> secs = interval;
else
ip -> client -> packet -> secs = 255;
note ("DHCPREQUEST on %s to %s port %d", ip -> name, note ("DHCPREQUEST on %s to %s port %d", ip -> name,
inet_ntoa (destination.sin_addr), inet_ntoa (destination.sin_addr),
ntohs (destination.sin_port)); ntohs (destination.sin_port));