udhcpc[6]: when renewing, send 1 packet (not 3), on failure go back to BOUND
This restores old behavior where we slept for 1/2 of lease, then tried renewing, thel slept for 1/4 and tried again, etc. But now we will NOT be listening to all packets for 1/2 of lease time, processing (rejecting) everyone else's DHCP traffic. We'll go back to bound state, where we have no listening socket at all. function old new delta udhcpc6_main 2600 2655 +55 udhcpc_main 2608 2625 +17 .rodata 103250 103249 -1 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/1 up/down: 72/-1) Total: 71 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
01daecca1d
commit
1c7253726f
@ -1420,7 +1420,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
retval = 1;
|
retval = 1;
|
||||||
goto ret;
|
goto ret;
|
||||||
}
|
}
|
||||||
/* wait before trying again */
|
/* Wait before trying again */
|
||||||
timeout = tryagain_timeout;
|
timeout = tryagain_timeout;
|
||||||
packet_num = 0;
|
packet_num = 0;
|
||||||
continue;
|
continue;
|
||||||
@ -1442,14 +1442,14 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
/* 1/2 lease passed, enter renewing state */
|
/* 1/2 lease passed, enter renewing state */
|
||||||
client_data.state = RENEWING;
|
client_data.state = RENEWING;
|
||||||
client_data.first_secs = 0; /* make secs field count from 0 */
|
client_data.first_secs = 0; /* make secs field count from 0 */
|
||||||
change_listen_mode(LISTEN_KERNEL);
|
got_SIGUSR1:
|
||||||
log1s("entering renew state");
|
log1s("entering renew state");
|
||||||
|
change_listen_mode(LISTEN_KERNEL);
|
||||||
/* fall right through */
|
/* fall right through */
|
||||||
case RENEW_REQUESTED: /* manual (SIGUSR1) renew */
|
case RENEW_REQUESTED: /* in manual (SIGUSR1) renew */
|
||||||
case_RENEW_REQUESTED:
|
|
||||||
case RENEWING:
|
case RENEWING:
|
||||||
if (packet_num < 3) {
|
if (packet_num == 0) {
|
||||||
/* send an unicast renew request */
|
/* Send an unicast renew request */
|
||||||
/* Sometimes observed to fail (EADDRNOTAVAIL) to bind
|
/* Sometimes observed to fail (EADDRNOTAVAIL) to bind
|
||||||
* a new UDP socket for sending inside send_renew.
|
* a new UDP socket for sending inside send_renew.
|
||||||
* I hazard to guess existing listening socket
|
* I hazard to guess existing listening socket
|
||||||
@ -1463,13 +1463,18 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
else
|
else
|
||||||
send_d6_renew(xid, &srv6_buf, requested_ipv6);
|
send_d6_renew(xid, &srv6_buf, requested_ipv6);
|
||||||
timeout = discover_timeout;
|
timeout = discover_timeout;
|
||||||
/* ^^^ used to be = lease_remaining / 2 - WAY too long */
|
|
||||||
packet_num++;
|
packet_num++;
|
||||||
continue;
|
continue;
|
||||||
|
} /* else: we had sent one packet, but got no reply */
|
||||||
|
log1s("no response to renew");
|
||||||
|
if (lease_remaining > 30) {
|
||||||
|
/* Some lease time remains, try to renew later */
|
||||||
|
change_listen_mode(LISTEN_NONE);
|
||||||
|
goto BOUND_for_half_lease;
|
||||||
}
|
}
|
||||||
/* Timed out, enter rebinding state */
|
/* Enter rebinding state */
|
||||||
log1s("entering rebinding state");
|
|
||||||
client_data.state = REBINDING;
|
client_data.state = REBINDING;
|
||||||
|
log1s("entering rebinding state");
|
||||||
/* Switch to bcast receive */
|
/* Switch to bcast receive */
|
||||||
change_listen_mode(LISTEN_RAW);
|
change_listen_mode(LISTEN_RAW);
|
||||||
packet_num = 0;
|
packet_num = 0;
|
||||||
@ -1509,8 +1514,14 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
/* Is it a signal? */
|
/* Is it a signal? */
|
||||||
switch (udhcp_sp_read()) {
|
switch (udhcp_sp_read()) {
|
||||||
case SIGUSR1:
|
case SIGUSR1:
|
||||||
|
if (client_data.state <= REQUESTING)
|
||||||
|
/* Initial negotiations in progress, do not disturb */
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (lease_remaining > 30) /* if renew fails, do not go back to BOUND */
|
||||||
|
lease_remaining = 30;
|
||||||
client_data.first_secs = 0; /* make secs field count from 0 */
|
client_data.first_secs = 0; /* make secs field count from 0 */
|
||||||
bb_simple_info_msg("performing DHCP renew");
|
packet_num = 0;
|
||||||
|
|
||||||
switch (client_data.state) {
|
switch (client_data.state) {
|
||||||
/* Try to renew/rebind */
|
/* Try to renew/rebind */
|
||||||
@ -1519,21 +1530,19 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
case REBINDING:
|
case REBINDING:
|
||||||
change_listen_mode(LISTEN_KERNEL);
|
change_listen_mode(LISTEN_KERNEL);
|
||||||
client_data.state = RENEW_REQUESTED;
|
client_data.state = RENEW_REQUESTED;
|
||||||
goto case_RENEW_REQUESTED;
|
goto got_SIGUSR1;
|
||||||
|
|
||||||
/* Start things over */
|
/* Two SIGUSR1 received, start things over */
|
||||||
case RENEW_REQUESTED: /* two or more SIGUSR1 received */
|
case RENEW_REQUESTED:
|
||||||
change_listen_mode(LISTEN_NONE);
|
change_listen_mode(LISTEN_NONE);
|
||||||
d6_run_script_no_option("deconfig");
|
d6_run_script_no_option("deconfig");
|
||||||
|
|
||||||
|
/* Wake from SIGUSR2-induced deconfigured state */
|
||||||
default:
|
default:
|
||||||
/* case REQUESTING: */
|
|
||||||
/* case RELEASED: */
|
/* case RELEASED: */
|
||||||
/* case INIT_SELECTING: */
|
|
||||||
change_listen_mode(LISTEN_NONE);
|
change_listen_mode(LISTEN_NONE);
|
||||||
}
|
}
|
||||||
client_data.state = INIT_SELECTING;
|
client_data.state = INIT_SELECTING;
|
||||||
packet_num = 0;
|
|
||||||
/* Kill any timeouts, user wants this to hurry along */
|
/* Kill any timeouts, user wants this to hurry along */
|
||||||
timeout = 0;
|
timeout = 0;
|
||||||
continue;
|
continue;
|
||||||
@ -1830,7 +1839,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// BOUND_for_half_lease:
|
BOUND_for_half_lease:
|
||||||
timeout = (unsigned)lease_remaining / 2;
|
timeout = (unsigned)lease_remaining / 2;
|
||||||
client_data.state = BOUND;
|
client_data.state = BOUND;
|
||||||
packet_num = 0;
|
packet_num = 0;
|
||||||
|
@ -1480,7 +1480,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
retval = 1;
|
retval = 1;
|
||||||
goto ret;
|
goto ret;
|
||||||
}
|
}
|
||||||
/* wait before trying again */
|
/* Wait before trying again */
|
||||||
timeout = tryagain_timeout;
|
timeout = tryagain_timeout;
|
||||||
packet_num = 0;
|
packet_num = 0;
|
||||||
continue;
|
continue;
|
||||||
@ -1502,14 +1502,14 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
/* 1/2 lease passed, enter renewing state */
|
/* 1/2 lease passed, enter renewing state */
|
||||||
client_data.state = RENEWING;
|
client_data.state = RENEWING;
|
||||||
client_data.first_secs = 0; /* make secs field count from 0 */
|
client_data.first_secs = 0; /* make secs field count from 0 */
|
||||||
change_listen_mode(LISTEN_KERNEL);
|
got_SIGUSR1:
|
||||||
log1s("entering renew state");
|
log1s("entering renew state");
|
||||||
|
change_listen_mode(LISTEN_KERNEL);
|
||||||
/* fall right through */
|
/* fall right through */
|
||||||
case RENEW_REQUESTED: /* manual (SIGUSR1) renew */
|
case RENEW_REQUESTED: /* in manual (SIGUSR1) renew */
|
||||||
case_RENEW_REQUESTED:
|
|
||||||
case RENEWING:
|
case RENEWING:
|
||||||
if (packet_num < 3) {
|
if (packet_num == 0) {
|
||||||
/* send an unicast renew request */
|
/* Send an unicast renew request */
|
||||||
/* Sometimes observed to fail (EADDRNOTAVAIL) to bind
|
/* Sometimes observed to fail (EADDRNOTAVAIL) to bind
|
||||||
* a new UDP socket for sending inside send_renew.
|
* a new UDP socket for sending inside send_renew.
|
||||||
* I hazard to guess existing listening socket
|
* I hazard to guess existing listening socket
|
||||||
@ -1520,7 +1520,6 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
*/
|
*/
|
||||||
if (send_renew(xid, server_addr, requested_ip) >= 0) {
|
if (send_renew(xid, server_addr, requested_ip) >= 0) {
|
||||||
timeout = discover_timeout;
|
timeout = discover_timeout;
|
||||||
/* ^^^ used to be = lease_remaining / 2 - WAY too long */
|
|
||||||
packet_num++;
|
packet_num++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1529,15 +1528,16 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
* which gave us bogus server ID 1.1.1.1
|
* which gave us bogus server ID 1.1.1.1
|
||||||
* which wasn't reachable (and probably did not exist).
|
* which wasn't reachable (and probably did not exist).
|
||||||
*/
|
*/
|
||||||
|
} /* else: we had sent one packet, but got no reply */
|
||||||
|
log1s("no response to renew");
|
||||||
|
if (lease_remaining > 30) {
|
||||||
|
/* Some lease time remains, try to renew later */
|
||||||
|
change_listen_mode(LISTEN_NONE);
|
||||||
|
goto BOUND_for_half_lease;
|
||||||
}
|
}
|
||||||
//TODO: if 3 renew's failed (no reply) but remaining lease is large enough,
|
/* Enter rebinding state */
|
||||||
//it might make sense to go back to BOUND and try later? a-la
|
|
||||||
// if (lease_remaining > 30) change_listen_mode(LISTEN_NONE) + goto BOUND_for_half_lease;
|
|
||||||
//If we do that, "packet_num < 3" test below might be superfluous
|
|
||||||
//(lease_remaining will run out anyway)
|
|
||||||
/* Timed out or error, enter rebinding state */
|
|
||||||
log1s("entering rebinding state");
|
|
||||||
client_data.state = REBINDING;
|
client_data.state = REBINDING;
|
||||||
|
log1s("entering rebinding state");
|
||||||
/* Switch to bcast receive */
|
/* Switch to bcast receive */
|
||||||
change_listen_mode(LISTEN_RAW);
|
change_listen_mode(LISTEN_RAW);
|
||||||
packet_num = 0;
|
packet_num = 0;
|
||||||
@ -1575,31 +1575,34 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
/* Is it a signal? */
|
/* Is it a signal? */
|
||||||
switch (udhcp_sp_read()) {
|
switch (udhcp_sp_read()) {
|
||||||
case SIGUSR1:
|
case SIGUSR1:
|
||||||
|
if (client_data.state <= REQUESTING)
|
||||||
|
/* Initial negotiations in progress, do not disturb */
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (lease_remaining > 30) /* if renew fails, do not go back to BOUND */
|
||||||
|
lease_remaining = 30;
|
||||||
client_data.first_secs = 0; /* make secs field count from 0 */
|
client_data.first_secs = 0; /* make secs field count from 0 */
|
||||||
bb_simple_info_msg("performing DHCP renew");
|
packet_num = 0;
|
||||||
|
|
||||||
switch (client_data.state) {
|
switch (client_data.state) {
|
||||||
/* Try to renew/rebind */
|
/* Try to renew/rebind */
|
||||||
case BOUND:
|
case BOUND:
|
||||||
case RENEWING:
|
case RENEWING:
|
||||||
case REBINDING:
|
case REBINDING:
|
||||||
change_listen_mode(LISTEN_KERNEL);
|
|
||||||
client_data.state = RENEW_REQUESTED;
|
client_data.state = RENEW_REQUESTED;
|
||||||
goto case_RENEW_REQUESTED;
|
goto got_SIGUSR1;
|
||||||
|
|
||||||
/* Start things over */
|
/* Two SIGUSR1 received, start things over */
|
||||||
case RENEW_REQUESTED: /* two or more SIGUSR1 received */
|
case RENEW_REQUESTED:
|
||||||
change_listen_mode(LISTEN_NONE);
|
change_listen_mode(LISTEN_NONE);
|
||||||
udhcp_run_script(NULL, "deconfig");
|
udhcp_run_script(NULL, "deconfig");
|
||||||
|
|
||||||
|
/* Wake from SIGUSR2-induced deconfigured state */
|
||||||
default:
|
default:
|
||||||
/* case REQUESTING: */
|
|
||||||
/* case RELEASED: */
|
/* case RELEASED: */
|
||||||
/* case INIT_SELECTING: */
|
|
||||||
change_listen_mode(LISTEN_NONE);
|
change_listen_mode(LISTEN_NONE);
|
||||||
}
|
}
|
||||||
client_data.state = INIT_SELECTING;
|
client_data.state = INIT_SELECTING;
|
||||||
packet_num = 0;
|
|
||||||
/* Kill any timeouts, user wants this to hurry along */
|
/* Kill any timeouts, user wants this to hurry along */
|
||||||
timeout = 0;
|
timeout = 0;
|
||||||
continue;
|
continue;
|
||||||
@ -1723,10 +1726,9 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
strcpy(server_str, inet_ntoa(temp_addr));
|
strcpy(server_str, inet_ntoa(temp_addr));
|
||||||
temp_addr.s_addr = packet.yiaddr;
|
temp_addr.s_addr = packet.yiaddr;
|
||||||
|
|
||||||
temp = udhcp_get_option32(&packet, DHCP_LEASE_TIME);
|
|
||||||
if (!temp) {
|
|
||||||
lease_remaining = 60 * 60;
|
lease_remaining = 60 * 60;
|
||||||
} else {
|
temp = udhcp_get_option32(&packet, DHCP_LEASE_TIME);
|
||||||
|
if (temp) {
|
||||||
uint32_t lease;
|
uint32_t lease;
|
||||||
/* it IS unaligned sometimes, don't "optimize" */
|
/* it IS unaligned sometimes, don't "optimize" */
|
||||||
move_from_unaligned32(lease, temp);
|
move_from_unaligned32(lease, temp);
|
||||||
@ -1798,8 +1800,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
opt = ((opt & ~OPT_b) | OPT_f);
|
opt = ((opt & ~OPT_b) | OPT_f);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
BOUND_for_half_lease:
|
||||||
// BOUND_for_half_lease:
|
|
||||||
timeout = (unsigned)lease_remaining / 2;
|
timeout = (unsigned)lease_remaining / 2;
|
||||||
client_data.state = BOUND;
|
client_data.state = BOUND;
|
||||||
/* make future renew packets use different xid */
|
/* make future renew packets use different xid */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user