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,30 +162,25 @@ autoip_restart(struct netif *netif)
static void
autoip_handle_arp_conflict(struct netif *netif)
{
/* Somehow detect if we are defending or retreating */
unsigned char defend = 1; /* tbd */
/* RFC3927, 2.5 "Conflict Detection and Defense" allows two options where
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) {
/* retreat, there was a conflicting ARP in the last
* DEFEND_INTERVAL seconds
*/
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("autoip_handle_arp_conflict(): we are defending, but in DEFEND_INTERVAL, retreating\n"));
if (netif->autoip->lastconflict > 0) {
/* retreat, there was a conflicting ARP in the last DEFEND_INTERVAL seconds */
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("autoip_handle_arp_conflict(): we are defending, but in DEFEND_INTERVAL, retreating\n"));
/* @todo: close all TCP sessions */
autoip_restart(netif);
} else {
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("autoip_handle_arp_conflict(): we are defend, send ARP Announce\n"));
autoip_arp_announce(netif);
netif->autoip->lastconflict = DEFEND_INTERVAL * AUTOIP_TICKS_PER_SECOND;
}
/* Active TCP sessions are aborted when removing the ip addresss */
autoip_restart(netif);
} 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);
("autoip_handle_arp_conflict(): we are defend, send ARP Announce\n"));
autoip_arp_announce(netif);
netif->autoip->lastconflict = DEFEND_INTERVAL * AUTOIP_TICKS_PER_SECOND;
}
}
@ -399,14 +394,20 @@ autoip_tmr(void)
("autoip_tmr() AutoIP-State: %"U16_F", ttw=%"U16_F"\n",
(u16_t)(netif->autoip->state), netif->autoip->ttw));
if (netif->autoip->ttw > 0) {
netif->autoip->ttw--;
}
switch(netif->autoip->state) {
case AUTOIP_STATE_PROBING:
if (netif->autoip->ttw > 0) {
netif->autoip->ttw--;
} else {
if (netif->autoip->ttw == 0) {
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->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;
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",
@ -414,34 +415,25 @@ autoip_tmr(void)
ip4_addr3_16(&netif->autoip->llipaddr), ip4_addr4_16(&netif->autoip->llipaddr)));
} else {
autoip_arp_probe(netif);
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
("autoip_tmr() PROBING Sent Probe\n"));
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_tmr() PROBING Sent Probe\n"));
netif->autoip->sent_num++;
/* calculate time to wait to next probe */
netif->autoip->ttw = (u16_t)((LWIP_AUTOIP_RAND(netif) %
((PROBE_MAX - PROBE_MIN) * AUTOIP_TICKS_PER_SECOND) ) +
PROBE_MIN * AUTOIP_TICKS_PER_SECOND);
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 */
netif->autoip->ttw = (u16_t)((LWIP_AUTOIP_RAND(netif) %
((PROBE_MAX - PROBE_MIN) * AUTOIP_TICKS_PER_SECOND) ) +
PROBE_MIN * AUTOIP_TICKS_PER_SECOND);
}
}
}
break;
case AUTOIP_STATE_ANNOUNCING:
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);
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
("autoip_tmr() ANNOUNCING Sent Announce\n"));
}
if (netif->autoip->ttw == 0) {
autoip_arp_announce(netif);
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_tmr() ANNOUNCING Sent Announce\n"));
netif->autoip->ttw = ANNOUNCE_INTERVAL * AUTOIP_TICKS_PER_SECOND;
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(&dipaddr, &hdr->dipaddr);
if ((netif->autoip->state == AUTOIP_STATE_PROBING) ||
((netif->autoip->state == AUTOIP_STATE_ANNOUNCING) &&
(netif->autoip->sent_num == 0))) {
if (netif->autoip->state == AUTOIP_STATE_PROBING) {
/* RFC 3927 Section 2.2.1:
* from beginning to after ANNOUNCE_WAIT
* 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
*
* @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
*/
u8_t
autoip_supplied_address(const struct netif *netif)
{
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;
}
}

View File

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