2
0
mirror of https://gitlab.isc.org/isc-projects/dhcp synced 2025-08-30 05:47:45 +00:00

- Allow the user to specify giaddr on the command line, for testing.

- If giaddr is specified, and it's not INADDR_LOOPBACK, use port 67 as
  the source port and also listen on port 67, since we're pretending to
  be a relay agent, and not a client.
- Stagger the first renew by +/- 1/4 of a lease interval, to mitigate 9am
  syndrome.
- Stagger startup time by up to five seconds, to even out the startup load.
This commit is contained in:
Ted Lemon 1999-10-24 19:44:15 +00:00
parent 1b87110042
commit 11373fb651

View File

@ -22,7 +22,7 @@
#ifndef lint #ifndef lint
static char ocopyright[] = static char ocopyright[] =
"$Id: dhclient.c,v 1.86 1999/10/14 17:40:05 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n"; "$Id: dhclient.c,v 1.87 1999/10/24 19:44:15 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */ #endif /* not lint */
#include "dhcpd.h" #include "dhcpd.h"
@ -47,6 +47,7 @@ struct iaddr iaddr_broadcast = { 4, { 255, 255, 255, 255 } };
struct iaddr iaddr_any = { 4, { 0, 0, 0, 0 } }; struct iaddr iaddr_any = { 4, { 0, 0, 0, 0 } };
struct in_addr inaddr_any; struct in_addr inaddr_any;
struct sockaddr_in sockaddr_broadcast; struct sockaddr_in sockaddr_broadcast;
struct in_addr giaddr;
/* ASSERT_STATE() does nothing now; it used to be /* ASSERT_STATE() does nothing now; it used to be
assert (state_is == state_shouldbe). */ assert (state_is == state_shouldbe). */
@ -78,6 +79,7 @@ int main (argc, argv, envp)
unsigned seed; unsigned seed;
int quiet = 0; int quiet = 0;
char *server = (char *)0; char *server = (char *)0;
char *relay = (char *)0;
isc_result_t status; isc_result_t status;
#ifdef SYSLOG_4_2 #ifdef SYSLOG_4_2
@ -121,6 +123,10 @@ int main (argc, argv, envp)
if (++i == argc) if (++i == argc)
usage (); usage ();
server = argv [i]; server = argv [i];
} else if (!strcmp (argv [i], "-g")) {
if (++i == argc)
usage ();
relay = argv [i];
} else if (argv [i][0] == '-') { } else if (argv [i][0] == '-') {
usage (); usage ();
} else { } else {
@ -147,18 +153,43 @@ int main (argc, argv, envp)
log_info (url); log_info (url);
} }
/* If we're given a relay agent address to insert, for testing
purposes, figure out what it is. */
if (relay) {
if (!inet_aton (relay, &giaddr)) {
struct hostent *he;
he = gethostbyname (relay);
if (he) {
memcpy (&giaddr, he -> h_addr_list [0],
sizeof giaddr);
} else {
log_fatal ("%s: no such host", relay);
}
}
}
/* Default to the DHCP/BOOTP port. */ /* Default to the DHCP/BOOTP port. */
if (!local_port) { if (!local_port) {
ent = getservbyname ("dhcpc", "udp"); if (relay && giaddr.s_addr != INADDR_LOOPBACK) {
if (!ent) local_port = 67;
local_port = htons (68); } else {
else ent = getservbyname ("dhcpc", "udp");
local_port = ent -> s_port; if (!ent)
local_port = htons (68);
else
local_port = ent -> s_port;
#ifndef __CYGWIN32__ #ifndef __CYGWIN32__
endservent (); endservent ();
#endif #endif
}
} }
remote_port = htons (ntohs (local_port) - 1); /* XXX */
/* If we're faking a relay agent, and we're not using loopback,
use the server port, not the client port. */
if (relay && giaddr.s_addr != INADDR_LOOPBACK)
remote_port = 67;
else
remote_port = htons (ntohs (local_port) - 1); /* XXX */
/* Get the current time... */ /* Get the current time... */
GET_TIME (&cur_time); GET_TIME (&cur_time);
@ -180,9 +211,7 @@ int main (argc, argv, envp)
} else { } else {
sockaddr_broadcast.sin_addr.s_addr = INADDR_BROADCAST; sockaddr_broadcast.sin_addr.s_addr = INADDR_BROADCAST;
} }
#ifdef HAVE_SA_LEN
sockaddr_broadcast.sin_len = sizeof sockaddr_broadcast;
#endif
inaddr_any.s_addr = INADDR_ANY; inaddr_any.s_addr = INADDR_ANY;
/* Set up the OMAPI. */ /* Set up the OMAPI. */
@ -263,7 +292,10 @@ int main (argc, argv, envp)
for (ip = interfaces; ip; ip = ip -> next) { for (ip = interfaces; ip; ip = ip -> next) {
for (client = ip -> client; client; client = client -> next) { for (client = ip -> client; client; client = client -> next) {
client -> state = S_INIT; client -> state = S_INIT;
state_reboot (client); /* Set up a timeout to start the initialization
process. */
add_timeout (cur_time + random () % 5,
state_reboot, client);
} }
} }
@ -591,6 +623,11 @@ void dhcpack (packet)
client -> new -> renewal = client -> new -> renewal =
client -> new -> expiry / 2; client -> new -> expiry / 2;
/* Now introduce some randomness to the renewal time: */
client -> new -> renewal = (((client -> new -> renewal + 3) * 3 / 4) +
(random () % /* XXX NUMS */
((client -> new -> renewal + 3) / 4)));
/* Same deal with the rebind time. */ /* Same deal with the rebind time. */
oc = lookup_option (&dhcp_universe, client -> new -> options, oc = lookup_option (&dhcp_universe, client -> new -> options,
DHO_DHCP_REBINDING_TIME); DHO_DHCP_REBINDING_TIME);
@ -608,9 +645,12 @@ void dhcpack (packet)
if (!client -> new -> rebind) if (!client -> new -> rebind)
client -> new -> rebind = client -> new -> rebind =
client -> new -> renewal + (client -> new -> expiry * 7) / 8; /* XXX NUMS */
client -> new -> renewal / 2 +
client -> new -> renewal / 4; /* Make sure our randomness didn't run the renewal time past the
rebind time. */
if (client -> new -> renewal > client -> new -> rebind)
client -> new -> renewal = (client -> new -> rebind * 3) / 4;
client -> new -> expiry += cur_time; client -> new -> expiry += cur_time;
/* Lease lengths can never be negative. */ /* Lease lengths can never be negative. */
@ -1251,13 +1291,15 @@ void state_panic (cpp)
/* No leases were available, or what was available didn't work, so /* No leases were available, or what was available didn't work, so
tell the shell script that we failed to allocate an address, tell the shell script that we failed to allocate an address,
and try again later. */ and try again later. */
log_info ("No working leases in persistent database - sleeping.\n"); log_info ("No working leases in persistent database - sleeping.");
script_init (client, "FAIL", (struct string_list *)0); script_init (client, "FAIL", (struct string_list *)0);
if (client -> alias) if (client -> alias)
script_write_params (client, "alias_", client -> alias); script_write_params (client, "alias_", client -> alias);
script_go (client); script_go (client);
client -> state = S_INIT; client -> state = S_INIT;
add_timeout (cur_time + client -> config -> retry_interval, add_timeout (cur_time +
((client -> config -> retry_interval + 1) / 2 +
(random () % client -> config -> retry_interval)),
state_init, client); state_init, client);
go_daemon (); go_daemon ();
} }
@ -1579,8 +1621,7 @@ void make_discover (client, lease)
0, sizeof client -> packet.yiaddr); 0, sizeof client -> packet.yiaddr);
memset (&(client -> packet.siaddr), memset (&(client -> packet.siaddr),
0, sizeof client -> packet.siaddr); 0, sizeof client -> packet.siaddr);
memset (&(client -> packet.giaddr), client -> packet.giaddr = giaddr;
0, sizeof client -> packet.giaddr);
memcpy (client -> packet.chaddr, memcpy (client -> packet.chaddr,
client -> interface -> hw_address.haddr, client -> interface -> hw_address.haddr,
client -> interface -> hw_address.hlen); client -> interface -> hw_address.hlen);
@ -1657,8 +1698,7 @@ void make_request (client, lease)
sizeof client -> packet.yiaddr); sizeof client -> packet.yiaddr);
memset (&client -> packet.siaddr, 0, memset (&client -> packet.siaddr, 0,
sizeof client -> packet.siaddr); sizeof client -> packet.siaddr);
memset (&client -> packet.giaddr, 0, client -> packet.giaddr = giaddr;
sizeof client -> packet.giaddr);
memcpy (client -> packet.chaddr, memcpy (client -> packet.chaddr,
client -> interface -> hw_address.haddr, client -> interface -> hw_address.haddr,
client -> interface -> hw_address.hlen); client -> interface -> hw_address.hlen);
@ -1713,8 +1753,7 @@ void make_decline (client, lease)
sizeof client -> packet.yiaddr); sizeof client -> packet.yiaddr);
memset (&client -> packet.siaddr, 0, memset (&client -> packet.siaddr, 0,
sizeof client -> packet.siaddr); sizeof client -> packet.siaddr);
memset (&client -> packet.giaddr, 0, client -> packet.giaddr = giaddr;
sizeof client -> packet.giaddr);
memcpy (client -> packet.chaddr, memcpy (client -> packet.chaddr,
client -> interface -> hw_address.haddr, client -> interface -> hw_address.haddr,
client -> interface -> hw_address.hlen); client -> interface -> hw_address.hlen);
@ -1766,8 +1805,7 @@ void make_release (client, lease)
sizeof client -> packet.yiaddr); sizeof client -> packet.yiaddr);
memset (&client -> packet.siaddr, 0, memset (&client -> packet.siaddr, 0,
sizeof client -> packet.siaddr); sizeof client -> packet.siaddr);
memset (&client -> packet.giaddr, 0, client -> packet.giaddr = giaddr;
sizeof client -> packet.giaddr);
memcpy (client -> packet.chaddr, memcpy (client -> packet.chaddr,
client -> interface -> hw_address.haddr, client -> interface -> hw_address.haddr,
client -> interface -> hw_address.hlen); client -> interface -> hw_address.hlen);