From 959a873f21f06b28fe1156f765b6ccce672465b4 Mon Sep 17 00:00:00 2001 From: Zhang Jun Hao Date: Tue, 16 Apr 2019 16:19:50 +0800 Subject: [PATCH] fix(lwip): fix some dhcp bugs remove some dhcp options in rebind state add t0 for dhcp lease time change t2 to 0.875*t0 --- third_party/include/lwip/dhcp.h | 4 +++ third_party/lwip/core/dhcp.c | 61 +++++++++++++++++++++------------ 2 files changed, 44 insertions(+), 21 deletions(-) diff --git a/third_party/include/lwip/dhcp.h b/third_party/include/lwip/dhcp.h index dcbb3cd4..57baab34 100644 --- a/third_party/include/lwip/dhcp.h +++ b/third_party/include/lwip/dhcp.h @@ -49,6 +49,10 @@ struct dhcp u16_t request_timeout; /* #ticks with period DHCP_FINE_TIMER_SECS for request timeout */ u16_t t1_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for renewal time */ u16_t t2_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for rebind time */ + u16_t t1_renew_time; /* #ticks with period DHCP_COARSE_TIMER_SECS until next renew try */ + u16_t t2_rebind_time; /* #ticks with period DHCP_COARSE_TIMER_SECS until next rebind try */ + u16_t lease_used; /* #ticks with period DHCP_COARSE_TIMER_SECS since last received DHCP ack */ + u16_t t0_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for lease time */ ip_addr_t server_ip_addr; /* dhcp server address that offered this lease */ ip_addr_t offered_ip_addr; ip_addr_t offered_sn_mask; diff --git a/third_party/lwip/core/dhcp.c b/third_party/lwip/core/dhcp.c index e6bb1843..4fddd628 100755 --- a/third_party/lwip/core/dhcp.c +++ b/third_party/lwip/core/dhcp.c @@ -382,13 +382,19 @@ dhcp_coarse_tmr() while (netif != NULL) { /* only act on DHCP configured interfaces */ if (netif->dhcp != NULL) { + /* compare lease time to expire timeout */ + if (netif->dhcp->t0_timeout && (++netif->dhcp->lease_used == netif->dhcp->t0_timeout)) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t0 timeout\n")); + /* this clients' lease time has expired */ + dhcp_release(netif); + dhcp_discover(netif); /* timer is active (non zero), and triggers (zeroes) now? */ - if (netif->dhcp->t2_timeout-- == 1) { + } else if (netif->dhcp->t2_rebind_time && (netif->dhcp->t2_rebind_time-- == 1)) { LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t2 timeout\n")); /* this clients' rebind timeout triggered */ dhcp_t2_timeout(netif); /* timer is active (non zero), and triggers (zeroes) now */ - } else if (netif->dhcp->t1_timeout-- == 1) { + } else if (netif->dhcp->t1_renew_time && (netif->dhcp->t1_renew_time-- == 1)) { LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t1 timeout\n")); /* this clients' renewal timeout triggered */ dhcp_t1_timeout(netif); @@ -480,23 +486,6 @@ dhcp_timeout(struct netif *netif) dhcp_bind(netif); } #endif /* DHCP_DOES_ARP_CHECK */ - } - /* did not get response to renew request? */ - else if (dhcp->state == DHCP_RENEWING) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): RENEWING, DHCP request timed out\n")); - /* just retry renewal */ - /* note that the rebind timer will eventually time-out if renew does not work */ - dhcp_renew(netif); - /* did not get response to rebind request? */ - } else if (dhcp->state == DHCP_REBINDING) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): REBINDING, DHCP request timed out\n")); - if (dhcp->tries <= 8) { - dhcp_rebind(netif); - } else { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): RELEASING, DISCOVERING\n")); - dhcp_release(netif); - dhcp_discover(netif); - } } else if (dhcp->state == DHCP_REBOOTING) { if (dhcp->tries < REBOOT_TRIES) { dhcp_reboot(netif); @@ -525,6 +514,11 @@ dhcp_t1_timeout(struct netif *netif) /* This slightly different to RFC2131: DHCPREQUEST will be sent from state DHCP_RENEWING, not DHCP_BOUND */ dhcp_renew(netif); + /* Calculate next timeout */ + if (((dhcp->t2_timeout - dhcp->lease_used) / 2) >= ((60 + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS)) + { + dhcp->t1_renew_time = ((dhcp->t2_timeout - dhcp->lease_used) / 2); + } } } @@ -546,6 +540,11 @@ dhcp_t2_timeout(struct netif *netif) /* This slightly different to RFC2131: DHCPREQUEST will be sent from state DHCP_REBINDING, not DHCP_BOUND */ dhcp_rebind(netif); + /* Calculate next timeout */ + if (((dhcp->t0_timeout - dhcp->lease_used) / 2) >= ((60 + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS)) + { + dhcp->t2_rebind_time = ((dhcp->t0_timeout - dhcp->lease_used) / 2); + } } } @@ -589,7 +588,7 @@ dhcp_handle_ack(struct netif *netif) dhcp->offered_t2_rebind = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_T2); } else { /* calculate safe periods for rebinding */ - dhcp->offered_t2_rebind = dhcp->offered_t0_lease; + dhcp->offered_t2_rebind = (dhcp->offered_t0_lease * 7U) / 8U; } /* (y)our internet address */ @@ -1018,6 +1017,22 @@ dhcp_bind(struct netif *netif) dhcp = netif->dhcp; LWIP_ERROR("dhcp_bind: dhcp != NULL", (dhcp != NULL), return;); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); + /* reset time used of lease */ + dhcp->lease_used = 0; + + if (dhcp->offered_t0_lease != 0xffffffffUL) { + /* set renewal period timer */ + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t0 renewal timer %"U32_F" secs\n", dhcp->offered_t0_lease)); + timeout = (dhcp->offered_t0_lease + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS; + if (timeout > 0xffff) { + timeout = 0xffff; + } + dhcp->t0_timeout = (u16_t)timeout; + if (dhcp->t0_timeout == 0) { + dhcp->t0_timeout = 1; + } + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t0_lease*1000)); + } /* temporary DHCP lease? */ if (dhcp->offered_t1_renew != 0xffffffffUL) { @@ -1032,6 +1047,7 @@ dhcp_bind(struct netif *netif) dhcp->t1_timeout = 1; } LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t1_renew*1000)); + dhcp->t1_renew_time = dhcp->t1_timeout; } /* set renewal period timer */ if (dhcp->offered_t2_rebind != 0xffffffffUL) { @@ -1045,6 +1061,7 @@ dhcp_bind(struct netif *netif) dhcp->t2_timeout = 1; } LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t2_rebind*1000)); + dhcp->t2_rebind_time = dhcp->t2_timeout; } /* If we have sub 1 minute lease, t2 and t1 will kick in at the same time. modify by ives at 2014.4.22*/ @@ -1230,7 +1247,7 @@ dhcp_rebind(struct netif *netif) } } -#if 1 +#if 0 dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4); dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr)); @@ -1325,6 +1342,7 @@ dhcp_release(struct netif *netif) ip_addr_set_zero(&dhcp->offered_si_addr); #endif /* LWIP_DHCP_BOOTP_FILE */ dhcp->offered_t0_lease = dhcp->offered_t1_renew = dhcp->offered_t2_rebind = 0; + dhcp->t1_renew_time = dhcp->t2_rebind_time = dhcp->lease_used = dhcp->t0_timeout = 0; /* create and initialize the DHCP message header */ result = dhcp_create_msg(netif, dhcp, DHCP_RELEASE); @@ -1725,6 +1743,7 @@ dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t } /* already bound to the given lease address? */ else if ((dhcp->state == DHCP_REBOOTING) || (dhcp->state == DHCP_REBINDING) || (dhcp->state == DHCP_RENEWING)) { + dhcp_handle_ack(netif); dhcp_bind(netif); } }