Fixed bug #48551 (autoip_supplied_address() does not work when address is first assigned); fixed AutoIP timeouts

This commit is contained in:
goldsimon 2016-07-20 08:28:16 +02:00
parent 98d58ffd59
commit e8ffac852e
2 changed files with 46 additions and 55 deletions

View File

@ -162,18 +162,19 @@ autoip_restart(struct netif *netif)
static void static void
autoip_handle_arp_conflict(struct netif *netif) autoip_handle_arp_conflict(struct netif *netif)
{ {
/* Somehow detect if we are defending or retreating */ /* RFC3927, 2.5 "Conflict Detection and Defense" allows two options where
unsigned char defend = 1; /* tbd */ a) means retreat on the first conflict and
b) allows to keep an already configured address when having only one
conflict in 10 seconds
We use option b) since it helps to improve the chance that one of the two
conflicting hosts may be able to retain its address. */
if (defend) {
if (netif->autoip->lastconflict > 0) { if (netif->autoip->lastconflict > 0) {
/* retreat, there was a conflicting ARP in the last /* retreat, there was a conflicting ARP in the last DEFEND_INTERVAL seconds */
* DEFEND_INTERVAL seconds
*/
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("autoip_handle_arp_conflict(): we are defending, but in DEFEND_INTERVAL, retreating\n")); ("autoip_handle_arp_conflict(): we are defending, but in DEFEND_INTERVAL, retreating\n"));
/* @todo: close all TCP sessions */ /* Active TCP sessions are aborted when removing the ip addresss */
autoip_restart(netif); autoip_restart(netif);
} else { } else {
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
@ -181,12 +182,6 @@ autoip_handle_arp_conflict(struct netif *netif)
autoip_arp_announce(netif); autoip_arp_announce(netif);
netif->autoip->lastconflict = DEFEND_INTERVAL * AUTOIP_TICKS_PER_SECOND; netif->autoip->lastconflict = DEFEND_INTERVAL * AUTOIP_TICKS_PER_SECOND;
} }
} else {
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("autoip_handle_arp_conflict(): we do not defend, retreating\n"));
/* @todo: close all TCP sessions */
autoip_restart(netif);
}
} }
/** /**
@ -399,14 +394,20 @@ autoip_tmr(void)
("autoip_tmr() AutoIP-State: %"U16_F", ttw=%"U16_F"\n", ("autoip_tmr() AutoIP-State: %"U16_F", ttw=%"U16_F"\n",
(u16_t)(netif->autoip->state), netif->autoip->ttw)); (u16_t)(netif->autoip->state), netif->autoip->ttw));
switch(netif->autoip->state) {
case AUTOIP_STATE_PROBING:
if (netif->autoip->ttw > 0) { if (netif->autoip->ttw > 0) {
netif->autoip->ttw--; netif->autoip->ttw--;
} else { }
switch(netif->autoip->state) {
case AUTOIP_STATE_PROBING:
if (netif->autoip->ttw == 0) {
if (netif->autoip->sent_num >= PROBE_NUM) { if (netif->autoip->sent_num >= PROBE_NUM) {
/* Switch to ANNOUNCING: now we can bind to an IP address and use it */
netif->autoip->state = AUTOIP_STATE_ANNOUNCING; netif->autoip->state = AUTOIP_STATE_ANNOUNCING;
netif->autoip->sent_num = 0; autoip_bind(netif);
/* autoip_bind() calls netif_set_addr(): this triggers a gratuitous ARP
which counts as an announcement */
netif->autoip->sent_num = 1;
netif->autoip->ttw = ANNOUNCE_WAIT * AUTOIP_TICKS_PER_SECOND; netif->autoip->ttw = ANNOUNCE_WAIT * AUTOIP_TICKS_PER_SECOND;
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("autoip_tmr(): changing state to ANNOUNCING: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", ("autoip_tmr(): changing state to ANNOUNCING: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
@ -414,34 +415,25 @@ autoip_tmr(void)
ip4_addr3_16(&netif->autoip->llipaddr), ip4_addr4_16(&netif->autoip->llipaddr))); ip4_addr3_16(&netif->autoip->llipaddr), ip4_addr4_16(&netif->autoip->llipaddr)));
} else { } else {
autoip_arp_probe(netif); autoip_arp_probe(netif);
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_tmr() PROBING Sent Probe\n"));
("autoip_tmr() PROBING Sent Probe\n"));
netif->autoip->sent_num++; netif->autoip->sent_num++;
if (netif->autoip->sent_num == PROBE_NUM) {
/* calculate time to wait to for announce */
netif->autoip->ttw = ANNOUNCE_WAIT * AUTOIP_TICKS_PER_SECOND;
} else {
/* calculate time to wait to next probe */ /* calculate time to wait to next probe */
netif->autoip->ttw = (u16_t)((LWIP_AUTOIP_RAND(netif) % netif->autoip->ttw = (u16_t)((LWIP_AUTOIP_RAND(netif) %
((PROBE_MAX - PROBE_MIN) * AUTOIP_TICKS_PER_SECOND) ) + ((PROBE_MAX - PROBE_MIN) * AUTOIP_TICKS_PER_SECOND) ) +
PROBE_MIN * AUTOIP_TICKS_PER_SECOND); PROBE_MIN * AUTOIP_TICKS_PER_SECOND);
} }
} }
}
break; break;
case AUTOIP_STATE_ANNOUNCING: case AUTOIP_STATE_ANNOUNCING:
if (netif->autoip->ttw > 0) { if (netif->autoip->ttw == 0) {
netif->autoip->ttw--;
} else {
if (netif->autoip->sent_num == 0) {
/* We are here the first time, so we waited ANNOUNCE_WAIT seconds
* Now we can bind to an IP address and use it.
*
* autoip_bind calls netif_set_addr. This triggers a gratuitous ARP
* which counts as an announcement.
*/
autoip_bind(netif);
} else {
autoip_arp_announce(netif); autoip_arp_announce(netif);
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_tmr() ANNOUNCING Sent Announce\n"));
("autoip_tmr() ANNOUNCING Sent Announce\n"));
}
netif->autoip->ttw = ANNOUNCE_INTERVAL * AUTOIP_TICKS_PER_SECOND; netif->autoip->ttw = ANNOUNCE_INTERVAL * AUTOIP_TICKS_PER_SECOND;
netif->autoip->sent_num++; netif->autoip->sent_num++;
@ -493,9 +485,7 @@ autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr)
IPADDR2_COPY(&sipaddr, &hdr->sipaddr); IPADDR2_COPY(&sipaddr, &hdr->sipaddr);
IPADDR2_COPY(&dipaddr, &hdr->dipaddr); IPADDR2_COPY(&dipaddr, &hdr->dipaddr);
if ((netif->autoip->state == AUTOIP_STATE_PROBING) || if (netif->autoip->state == AUTOIP_STATE_PROBING) {
((netif->autoip->state == AUTOIP_STATE_ANNOUNCING) &&
(netif->autoip->sent_num == 0))) {
/* RFC 3927 Section 2.2.1: /* RFC 3927 Section 2.2.1:
* from beginning to after ANNOUNCE_WAIT * from beginning to after ANNOUNCE_WAIT
* seconds we have a conflict if * seconds we have a conflict if
@ -527,14 +517,15 @@ autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr)
/** check if AutoIP supplied netif->ip_addr /** check if AutoIP supplied netif->ip_addr
* *
* @param netif the netif to check * @param netif the netif to check
* @return 1 if AutoIP supplied netif->ip_addr (state BOUND), * @return 1 if AutoIP supplied netif->ip_addr (state BOUND or ANNOUNCING),
* 0 otherwise * 0 otherwise
*/ */
u8_t u8_t
autoip_supplied_address(const struct netif *netif) autoip_supplied_address(const struct netif *netif)
{ {
if ((netif != NULL) && (netif->autoip != NULL)) { if ((netif != NULL) && (netif->autoip != NULL)) {
if (netif->autoip->state == AUTOIP_STATE_BOUND) { if ((netif->autoip->state == AUTOIP_STATE_BOUND) ||
(netif->autoip->state == AUTOIP_STATE_ANNOUNCING)) {
return 1; return 1;
} }
} }

View File

@ -782,10 +782,10 @@
/** /**
* LWIP_DHCP_AUTOIP_COOP_TRIES: Set to the number of DHCP DISCOVER probes * LWIP_DHCP_AUTOIP_COOP_TRIES: Set to the number of DHCP DISCOVER probes
* that should be sent before falling back on AUTOIP. This can be set * that should be sent before falling back on AUTOIP (the DHCP client keeps
* as low as 1 to get an AutoIP address very quickly, but you should * running in this case). This can be set as low as 1 to get an AutoIP address
* be prepared to handle a changing IP address when DHCP overrides * very quickly, but you should be prepared to handle a changing IP address
* AutoIP. * when DHCP overrides AutoIP.
*/ */
#ifndef LWIP_DHCP_AUTOIP_COOP_TRIES #ifndef LWIP_DHCP_AUTOIP_COOP_TRIES
#define LWIP_DHCP_AUTOIP_COOP_TRIES 9 #define LWIP_DHCP_AUTOIP_COOP_TRIES 9