dhcpcd-discuss

Re: behaviour of TIMEOUT on version 7.0.0

Roy Marples

Thu Aug 20 20:52:32 2020

Didn't spot that.
Try this one insted.

On 20/08/2020 18:17, Shyamlee Badole wrote:
Hey,

Thank You for sending the patch.
I've tested this patch (version 7.0.0), but the issue is still reproducible.

The option that is given in dhcpcd.conf is lastlease and not lastleaseextend.
Could this be the cause since in dhcp_expire() we are checking for the latter as follows:
if (ifp->options->options & DHCPCD_LASTLEASE_EXTEND)

Thanks,
Shyamlee

On Thu, Aug 20, 2020 at 9:48 PM Roy Marples <roy@xxxxxxxxxxxx <mailto:roy@xxxxxxxxxxxx>> wrote:

    I don't maintain dhcpcd-7 anymore - many bugs have been fixed since.
    Anyway the attached patch should work - let me know.

    Roy

    On 20/08/2020 17:10, Shyamlee Badole wrote:
     > Hi,
     >
     > Thank You for sending the patch.
     > Since we are using dhcpcd 7.0.0 if you have, can you please share the
    patch for
     > this version?
     >
     > Thanks,
     > Shyamlee
     >
     > On Thu, Aug 20, 2020 at 8:43 PM Roy Marples <roy@xxxxxxxxxxxx
    <mailto:roy@xxxxxxxxxxxx>
     > <mailto:roy@xxxxxxxxxxxx <mailto:roy@xxxxxxxxxxxx>>> wrote:
     >
     >     On 20/08/2020 11:57, Shyamlee Badole wrote:
     >      > Hi,
     >      >
     >      > I am attaching the pcap file to give you a better idea of the issue.
     >      >
     >      > As seen from the pcap, when the link is detected on the interface
    (eth1),
     >      > initially the client tried to contact the dhcp server after which it
     >     broadcasted
     >      > the request asking for previous lease. After that a timeout occurs
    (eth1:
     >     timed
     >      > out contacting a DHCP server, using last lease)
     >      >
     >      > After timeout(since that router is down), the client has sent a
    Broadcast
     >      > DISCOVER, to which a dhcp server belonging to another network has
    offered
     >     an ip.
     >      > (eth1: offered 192.168.44.6 from 192.168.44.1)
     >      > The client is now sending REQUEST to the server(192.168.44.1)
    using the
     >     previous
     >      > IP(66.170.65.115).
     >      > This REQUEST is sent unicast to the old router gateway and the
    client is not
     >      > able to accept the offered ip and continuously sends the unicast
    REQUEST.
     >      > Since the client has already entered the Discover phase, it should
     >     broadcast the
     >      > request instead of unicasting to the old gateway (which is no
    longer valid).
     >      > If this request to accept the offer was broadcasted, it will be
    able to
     >     receive
     >      > the reply from the new server.
     >
     >     Thanks, makes it simple to fix I hope!
     >     Comitted this to fix:
     >
    https://roy.marples.name/cgit/dhcpcd.git/commit/?id=f021b552b5c53cfa785bc5f8df1c97fa8ffa9b86
     >
     >     Can you test it please?
     >
     >     Roy
     >

diff --git a/src/dhcp.c b/src/dhcp.c
index ed1b0a6d..71f844ed 100644
--- a/src/dhcp.c
+++ b/src/dhcp.c
@@ -778,7 +778,7 @@ make_message(struct bootp **bootpm, const struct interface *ifp, uint8_t type)
 	    (type == DHCP_REQUEST &&
 	    state->addr->mask.s_addr == lease->mask.s_addr &&
 	    (state->new == NULL || IS_DHCP(state->new)) &&
-	    !(state->added & STATE_FAKE))))
+	    !(state->added & (STATE_FAKE | STATE_EXPIRED)))))
 		bootp->ciaddr = state->addr->addr.s_addr;
 
 	bootp->op = BOOTREQUEST;
@@ -1968,6 +1968,9 @@ dhcp_expire(void *arg)
 
 	logerrx("%s: DHCP lease expired", ifp->name);
 	if (ifp->options->options & DHCPCD_LASTLEASE_EXTEND) {
+		struct dhcp_state *state = D_STATE(ifp);
+
+		state->added |= STATE_EXPIRED;
 		if (dhcp_leaseextend(ifp) == 0)
 			return;
 		logerr(__func__);
@@ -2332,6 +2335,8 @@ dhcp_lastlease(void *arg)
 	loginfox("%s: timed out contacting a DHCP server, using last lease",
 	    ifp->name);
 	dhcp_bind(ifp);
+	/* Although the lease hasn't expired, we don't want to send requests from it either. */
+	state->added |= STATE_EXPIRED;
 	/* If we forked, stop here. */
 	if (ifp->ctx->options & DHCPCD_FORKED)
 		return;
diff --git a/src/ipv4.h b/src/ipv4.h
index bcd0031f..03b9ac61 100644
--- a/src/ipv4.h
+++ b/src/ipv4.h
@@ -117,6 +117,7 @@ bool inet_getroutes(struct dhcpcd_ctx *, struct rt_head *);
 
 #define STATE_ADDED		0x01
 #define STATE_FAKE		0x02
+#define STATE_EXPIRED		0x04
 
 int ipv4_deladdr(struct ipv4_addr *, int);
 struct ipv4_addr *ipv4_addaddr(struct interface *,

Follow-Ups:
Re: behaviour of TIMEOUT on version 7.0.0Shyamlee Badole
References:
behaviour of TIMEOUT on version 7.0.0shamli badole
Re: behaviour of TIMEOUT on version 7.0.0Roy Marples
Re: behaviour of TIMEOUT on version 7.0.0Shyamlee Badole
Re: behaviour of TIMEOUT on version 7.0.0Shyamlee Badole
Re: behaviour of TIMEOUT on version 7.0.0Roy Marples
Re: behaviour of TIMEOUT on version 7.0.0Shyamlee Badole
Re: behaviour of TIMEOUT on version 7.0.0Roy Marples
Re: behaviour of TIMEOUT on version 7.0.0Shyamlee Badole
Archive administrator: postmaster@marples.name