fixed bug #38204 (DHCP lease time not handled correctly)

This commit is contained in:
sg 2015-03-21 10:09:31 +01:00
parent 45d82c8d99
commit 4463239d6e
3 changed files with 50 additions and 25 deletions

View File

@ -216,6 +216,9 @@ HISTORY
++ Bugfixes: ++ Bugfixes:
2015-03-21: Simon Goldschmidt (patch by Christoffer Lind)
* dhcp.h/.c: fixed bug #38204 (DHCP lease time not handled correctly)
2015-03-20: Simon Goldschmidt 2015-03-20: Simon Goldschmidt
* dhcp.c: fixed bug #38714 (Missing option and client address in DHCPRELEASE message) * dhcp.c: fixed bug #38714 (Missing option and client address in DHCPRELEASE message)

View File

@ -360,13 +360,19 @@ dhcp_coarse_tmr()
while (netif != NULL) { while (netif != NULL) {
/* only act on DHCP configured interfaces */ /* only act on DHCP configured interfaces */
if (netif->dhcp != NULL) { if (netif->dhcp != NULL) {
/* compare lease time to expire timeout */
if (++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? */ /* timer is active (non zero), and triggers (zeroes) now? */
if (netif->dhcp->t2_timeout-- == 1) { } else if (netif->dhcp->t2_rebind_time-- == 1) {
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t2 timeout\n")); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t2 timeout\n"));
/* this clients' rebind timeout triggered */ /* this clients' rebind timeout triggered */
dhcp_t2_timeout(netif); dhcp_t2_timeout(netif);
/* timer is active (non zero), and triggers (zeroes) now */ /* timer is active (non zero), and triggers (zeroes) now */
} else if (netif->dhcp->t1_timeout-- == 1) { } else if (netif->dhcp->t1_renew_time-- == 1) {
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t1 timeout\n")); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t1 timeout\n"));
/* this clients' renewal timeout triggered */ /* this clients' renewal timeout triggered */
dhcp_t1_timeout(netif); dhcp_t1_timeout(netif);
@ -448,23 +454,6 @@ dhcp_timeout(struct netif *netif)
dhcp_bind(netif); dhcp_bind(netif);
} }
#endif /* DHCP_DOES_ARP_CHECK */ #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) { } else if (dhcp->state == DHCP_REBOOTING) {
if (dhcp->tries < REBOOT_TRIES) { if (dhcp->tries < REBOOT_TRIES) {
dhcp_reboot(netif); dhcp_reboot(netif);
@ -493,6 +482,11 @@ dhcp_t1_timeout(struct netif *netif)
/* This slightly different to RFC2131: DHCPREQUEST will be sent from state /* This slightly different to RFC2131: DHCPREQUEST will be sent from state
DHCP_RENEWING, not DHCP_BOUND */ DHCP_RENEWING, not DHCP_BOUND */
dhcp_renew(netif); dhcp_renew(netif);
/* Calculate next timeout */
if (((netif->dhcp->t2_timeout - dhcp->lease_used) / 2) >= ((60 + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS))
{
netif->dhcp->t1_renew_time = ((netif->dhcp->t2_timeout - dhcp->lease_used) / 2);
}
} }
} }
@ -507,13 +501,18 @@ dhcp_t2_timeout(struct netif *netif)
struct dhcp *dhcp = netif->dhcp; struct dhcp *dhcp = netif->dhcp;
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_t2_timeout()\n")); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_t2_timeout()\n"));
if ((dhcp->state == DHCP_REQUESTING) || (dhcp->state == DHCP_BOUND) || if ((dhcp->state == DHCP_REQUESTING) || (dhcp->state == DHCP_BOUND) ||
(dhcp->state == DHCP_RENEWING)) { (dhcp->state == DHCP_RENEWING) || (dhcp->state == DHCP_REBINDING)) {
/* just retry to rebind */ /* just retry to rebind */
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("dhcp_t2_timeout(): must rebind\n")); ("dhcp_t2_timeout(): must rebind\n"));
/* This slightly different to RFC2131: DHCPREQUEST will be sent from state /* This slightly different to RFC2131: DHCPREQUEST will be sent from state
DHCP_REBINDING, not DHCP_BOUND */ DHCP_REBINDING, not DHCP_BOUND */
dhcp_rebind(netif); dhcp_rebind(netif);
/* Calculate next timeout */
if (((netif->dhcp->t0_timeout - dhcp->lease_used) / 2) >= ((60 + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS))
{
netif->dhcp->t2_rebind_time = ((netif->dhcp->t0_timeout - dhcp->lease_used) / 2);
}
} }
} }
@ -559,8 +558,8 @@ dhcp_handle_ack(struct netif *netif)
/* remember given rebind period */ /* remember given rebind period */
dhcp->offered_t2_rebind = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_T2); dhcp->offered_t2_rebind = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_T2);
} else { } else {
/* calculate safe periods for rebinding */ /* calculate safe periods for rebinding (offered_t0_lease * 0.875 -> 87.5%)*/
dhcp->offered_t2_rebind = dhcp->offered_t0_lease; dhcp->offered_t2_rebind = (dhcp->offered_t0_lease * 7U) / 8U;
} }
/* (y)our internet address */ /* (y)our internet address */
@ -966,6 +965,23 @@ dhcp_bind(struct netif *netif)
LWIP_ERROR("dhcp_bind: dhcp != NULL", (dhcp != NULL), return;); 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)); 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? */ /* temporary DHCP lease? */
if (dhcp->offered_t1_renew != 0xffffffffUL) { if (dhcp->offered_t1_renew != 0xffffffffUL) {
/* set renewal period timer */ /* set renewal period timer */
@ -979,6 +995,7 @@ dhcp_bind(struct netif *netif)
dhcp->t1_timeout = 1; 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)); 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 */ /* set renewal period timer */
if (dhcp->offered_t2_rebind != 0xffffffffUL) { if (dhcp->offered_t2_rebind != 0xffffffffUL) {
@ -992,6 +1009,7 @@ dhcp_bind(struct netif *netif)
dhcp->t2_timeout = 1; 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)); 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. */ /* If we have sub 1 minute lease, t2 and t1 will kick in at the same time. */

View File

@ -49,6 +49,10 @@ struct dhcp
u16_t request_timeout; /* #ticks with period DHCP_FINE_TIMER_SECS for request timeout */ 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 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 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 server_ip_addr; /* dhcp server address that offered this lease */
ip_addr_t offered_ip_addr; ip_addr_t offered_ip_addr;
ip_addr_t offered_sn_mask; ip_addr_t offered_sn_mask;
@ -56,7 +60,7 @@ struct dhcp
u32_t offered_t0_lease; /* lease period (in seconds) */ u32_t offered_t0_lease; /* lease period (in seconds) */
u32_t offered_t1_renew; /* recommended renew time (usually 50% of lease period) */ u32_t offered_t1_renew; /* recommended renew time (usually 50% of lease period) */
u32_t offered_t2_rebind; /* recommended rebind time (usually 66% of lease period) */ u32_t offered_t2_rebind; /* recommended rebind time (usually 87.5 of lease period) */
#if LWIP_DHCP_BOOTP_FILE #if LWIP_DHCP_BOOTP_FILE
ip_addr_t offered_si_addr; ip_addr_t offered_si_addr;
char boot_file_name[DHCP_FILE_LEN]; char boot_file_name[DHCP_FILE_LEN];
@ -161,9 +165,9 @@ void dhcp_fine_tmr(void);
#define DHCP_REBINDING 4 #define DHCP_REBINDING 4
#define DHCP_RENEWING 5 #define DHCP_RENEWING 5
#define DHCP_SELECTING 6 #define DHCP_SELECTING 6
/* not yet implemented #define DHCP_INFORMING 7*/ #define DHCP_INFORMING 7
#define DHCP_CHECKING 8 #define DHCP_CHECKING 8
/* not yet implemented #define DHCP_PERMANENT 9*/ #define DHCP_PERMANENT 9
#define DHCP_BOUND 10 #define DHCP_BOUND 10
/** not yet implemented #define DHCP_RELEASING 11 */ /** not yet implemented #define DHCP_RELEASING 11 */
#define DHCP_BACKING_OFF 12 #define DHCP_BACKING_OFF 12