udhcpc: limit renew/rebind timeout
Denys Vlasenko
vda.linux at googlemail.com
Mon Oct 17 23:43:48 UTC 2011
On Wednesday 14 September 2011 13:34, Vladislav Grishenko wrote:
> In some cases it's good to have control over manual renew/rebind timeout
> before deconfig state.
> Scenario:
> 1. udhcpc gets lease for 86400 secs and sleeps for 43200 before renew
> attempt
> 2. PC gets physically disconnected and connected to another network
> 3. some phy control software sends SIGUSR1 to renew the lease, SIGUSR2 isn't
> used because newly connected network could be the same as before
> 4. udhcpc sends unicast renew requests up to 60 timeout, which are ignored
> by new network dhcp servers
I guess this is a wrong behavior. SIGUSR was most likely meant to
force udhcpc to renew to completely renegotiate the lease *quickly*,
that it, to broadcast (at once, or after a few inucast tries),
instead of unicasting until current lease expirea.
> 5. udhcpc sends broadcast rebind requests, which could be naked or ignored
> too, if there's no authority dhcp servers configured
> 6. udhcpc deconfigs and starting from discover state, gets new lease for the
> new network
> So, pt.4+5 it could take up to 86400 secs without correct lease, which is
> too long and not acceptable in my case.
> Second SIGUSR1 will immediately run into deconfig/discover state, which is
> not preferable in case of the same subnet replugged.
>
> With the patch, it's possible to limit pt.4 and pt.5 stage timeouts, for
> example:
> By specifying -N61 option udhcpc will make one unicast renew attempt
> (timeout greater than 60) and will get 61/2 timeout for broadcast rebind, if
> original timeout before signal is greater than 61 sec.
> By specifying -N60 and lower, no unicast renew attempt will be made, only
> broadcast rebind.
> Default behavior - is to continue use of unchanged timeouts, like before
> patch.
When is "before patch" behavior is useful? I don't see it.
I propose to use your fix unconditionally.
This way, we don't need a new option. We can use hardcoded value (~30 sec?)
or abuse one of existing tweakable values.
I think -A N can be used, it's 20 by default. The fact that we don't try
unicast even once is likely not a problem in practice.
How about this patch?
(I applied it to git)
--
vda
diff -ad -urpN busybox.0/networking/udhcp/dhcpc.c busybox.1/networking/udhcp/dhcpc.c
--- busybox.0/networking/udhcp/dhcpc.c 2011-10-16 05:16:40.000000000 +0200
+++ busybox.1/networking/udhcp/dhcpc.c 2011-10-18 01:29:01.000000000 +0200
@@ -1362,8 +1362,22 @@ int udhcpc_main(int argc UNUSED_PARAM, c
case SIGUSR1:
client_config.first_secs = 0; /* make secs field count from 0 */
perform_renew();
- if (state == RENEW_REQUESTED)
+ if (state == RENEW_REQUESTED) {
+ already_waited_sec = 0;
+ /* We might be either on the same network
+ * (in which case renew might work),
+ * or maybe we are on a completely different one
+ * (in which case renew won't ever succeed!).
+ * For the second case, must make sure timeout
+ * is not too big, or else we can send renew requests
+ * for hours.
+ * (Ab)use -A TIMEOUT value (usually 20 sec)
+ * as a cap on the timeout.
+ */
+ if (timeout > tryagain_timeout)
+ timeout = tryagain_timeout;
goto case_RENEW_REQUESTED;
+ }
/* Start things over */
packet_num = 0;
/* Kill any timeouts, user wants this to hurry along */
More information about the busybox
mailing list