udhcpc: emit "correct" secs field
authorDenys Vlasenko <vda.linux@googlemail.com>
Sat, 12 Mar 2011 04:37:54 +0000 (05:37 +0100)
committerDenys Vlasenko <vda.linux@googlemail.com>
Sat, 12 Mar 2011 04:37:54 +0000 (05:37 +0100)
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>
networking/udhcp/dhcpc.c
networking/udhcp/dhcpc.h

index e9a8412042dc7d6aa06042293971458d3982c28b..ca82d37e60d09c1e02ed5f648ba73659aea1556f 100644 (file)
@@ -407,11 +407,19 @@ static ALWAYS_INLINE uint32_t random_xid(void)
 /* Initialize the packet with the proper defaults */
 static void init_packet(struct dhcp_packet *packet, char type)
 {
+       uint16_t secs;
+
        /* Fill in: op, htype, hlen, cookie fields; message type option: */
        udhcp_init_header(packet, type);
 
        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);
        if (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 */
 }
 
+/* Called only on SIGUSR1 */
 static void perform_renew(void)
 {
        bb_info_msg("Performing a DHCP renew");
@@ -1260,6 +1269,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
                        case BOUND:
                                /* 1/2 lease passed, enter renewing state */
                                state = RENEWING;
+                               client_config.first_secs = 0; /* make secs field count from 0 */
                                change_listen_mode(LISTEN_KERNEL);
                                log1("Entering renew state");
                                /* fall right through */
@@ -1299,6 +1309,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
                                bb_info_msg("Lease lost, entering init state");
                                udhcp_run_script(NULL, "deconfig");
                                state = INIT_SELECTING;
+                               client_config.first_secs = 0; /* make secs field count from 0 */
                                /*timeout = 0; - already is */
                                packet_num = 0;
                                continue;
@@ -1315,6 +1326,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
                /* note: udhcp_sp_read checks FD_ISSET before reading */
                switch (udhcp_sp_read(&rfds)) {
                case SIGUSR1:
+                       client_config.first_secs = 0; /* make secs field count from 0 */
                        perform_renew();
                        if (state == RENEW_REQUESTED)
                                goto case_RENEW_REQUESTED;
@@ -1446,6 +1458,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
                                                        udhcp_run_script(NULL, "deconfig");
                                                change_listen_mode(LISTEN_RAW);
                                                state = INIT_SELECTING;
+                                               client_config.first_secs = 0; /* make secs field count from 0 */
                                                requested_ip = 0;
                                                timeout = tryagain_timeout;
                                                packet_num = 0;
@@ -1493,6 +1506,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
                                change_listen_mode(LISTEN_RAW);
                                sleep(3); /* avoid excessive network traffic */
                                state = INIT_SELECTING;
+                               client_config.first_secs = 0; /* make secs field count from 0 */
                                requested_ip = 0;
                                timeout = 0;
                                packet_num = 0;
index 9ef053a1beb418dce1f8fe5f8674572fb9116d82..2b3599120f09e25d20462d5c9586202201eefb1c 100644 (file)
@@ -21,6 +21,9 @@ struct client_config_t {
        uint8_t *vendorclass;           /* Optional vendor class-id to use */
        uint8_t *hostname;              /* Optional hostname to use */
        uint8_t *fqdn;                  /* Optional fully qualified domain name to use */
+
+       uint16_t first_secs;
+       uint16_t last_secs;
 } FIX_ALIASING;
 
 /* server_config sits in 1st half of bb_common_bufsiz1 */