udhcpc: emit "correct" secs field

In theory, sending secs set to constant zero should be ok too.
But some bleeping servers can actually be configured to answer ONLY
if secs is bigger than a preset value (!!)
http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man8/bootpd.8.html
grep for "reply_threshold_seconds"

function                                             old     new   delta
udhcpc_main                                         2573    2623     +50

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2011-03-12 05:37:54 +01:00
parent ea684c6aaf
commit 9ac5596a51
2 changed files with 17 additions and 0 deletions

View File

@ -407,11 +407,19 @@ static ALWAYS_INLINE uint32_t random_xid(void)
/* Initialize the packet with the proper defaults */ /* Initialize the packet with the proper defaults */
static void init_packet(struct dhcp_packet *packet, char type) static void init_packet(struct dhcp_packet *packet, char type)
{ {
uint16_t secs;
/* Fill in: op, htype, hlen, cookie fields; message type option: */ /* Fill in: op, htype, hlen, cookie fields; message type option: */
udhcp_init_header(packet, type); udhcp_init_header(packet, type);
packet->xid = random_xid(); packet->xid = random_xid();
client_config.last_secs = monotonic_sec();
if (client_config.first_secs == 0)
client_config.first_secs = client_config.last_secs;
secs = client_config.last_secs - client_config.first_secs;
packet->secs = htons(secs);
memcpy(packet->chaddr, client_config.client_mac, 6); memcpy(packet->chaddr, client_config.client_mac, 6);
if (client_config.clientid) if (client_config.clientid)
udhcp_add_binary_option(packet, client_config.clientid); udhcp_add_binary_option(packet, client_config.clientid);
@ -848,6 +856,7 @@ static void change_listen_mode(int new_mode)
/* else LISTEN_NONE: sockfd stays closed */ /* else LISTEN_NONE: sockfd stays closed */
} }
/* Called only on SIGUSR1 */
static void perform_renew(void) static void perform_renew(void)
{ {
bb_info_msg("Performing a DHCP renew"); bb_info_msg("Performing a DHCP renew");
@ -1260,6 +1269,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
case BOUND: case BOUND:
/* 1/2 lease passed, enter renewing state */ /* 1/2 lease passed, enter renewing state */
state = RENEWING; state = RENEWING;
client_config.first_secs = 0; /* make secs field count from 0 */
change_listen_mode(LISTEN_KERNEL); change_listen_mode(LISTEN_KERNEL);
log1("Entering renew state"); log1("Entering renew state");
/* fall right through */ /* fall right through */
@ -1299,6 +1309,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
bb_info_msg("Lease lost, entering init state"); bb_info_msg("Lease lost, entering init state");
udhcp_run_script(NULL, "deconfig"); udhcp_run_script(NULL, "deconfig");
state = INIT_SELECTING; state = INIT_SELECTING;
client_config.first_secs = 0; /* make secs field count from 0 */
/*timeout = 0; - already is */ /*timeout = 0; - already is */
packet_num = 0; packet_num = 0;
continue; continue;
@ -1315,6 +1326,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
/* note: udhcp_sp_read checks FD_ISSET before reading */ /* note: udhcp_sp_read checks FD_ISSET before reading */
switch (udhcp_sp_read(&rfds)) { switch (udhcp_sp_read(&rfds)) {
case SIGUSR1: case SIGUSR1:
client_config.first_secs = 0; /* make secs field count from 0 */
perform_renew(); perform_renew();
if (state == RENEW_REQUESTED) if (state == RENEW_REQUESTED)
goto case_RENEW_REQUESTED; goto case_RENEW_REQUESTED;
@ -1446,6 +1458,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
udhcp_run_script(NULL, "deconfig"); udhcp_run_script(NULL, "deconfig");
change_listen_mode(LISTEN_RAW); change_listen_mode(LISTEN_RAW);
state = INIT_SELECTING; state = INIT_SELECTING;
client_config.first_secs = 0; /* make secs field count from 0 */
requested_ip = 0; requested_ip = 0;
timeout = tryagain_timeout; timeout = tryagain_timeout;
packet_num = 0; packet_num = 0;
@ -1493,6 +1506,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
change_listen_mode(LISTEN_RAW); change_listen_mode(LISTEN_RAW);
sleep(3); /* avoid excessive network traffic */ sleep(3); /* avoid excessive network traffic */
state = INIT_SELECTING; state = INIT_SELECTING;
client_config.first_secs = 0; /* make secs field count from 0 */
requested_ip = 0; requested_ip = 0;
timeout = 0; timeout = 0;
packet_num = 0; packet_num = 0;

View File

@ -21,6 +21,9 @@ struct client_config_t {
uint8_t *vendorclass; /* Optional vendor class-id to use */ uint8_t *vendorclass; /* Optional vendor class-id to use */
uint8_t *hostname; /* Optional hostname to use */ uint8_t *hostname; /* Optional hostname to use */
uint8_t *fqdn; /* Optional fully qualified domain name to use */ uint8_t *fqdn; /* Optional fully qualified domain name to use */
uint16_t first_secs;
uint16_t last_secs;
} FIX_ALIASING; } FIX_ALIASING;
/* server_config sits in 1st half of bb_common_bufsiz1 */ /* server_config sits in 1st half of bb_common_bufsiz1 */