diff --git a/CHANGELOG b/CHANGELOG index bd48550b..62340256 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -405,6 +405,10 @@ HISTORY ++ Bug fixes: + 2007-09-20 Simon Goldschmidt + * tcp.c: Fixed bug #21080 (tcp_bind without check pcbs in TIME_WAIT state) + by checking tcp_tw_pcbs also + 2007-09-19 Simon Goldschmidt * icmp.c: Fixed bug #21107 (didn't reset IP TTL in ICMP echo replies) diff --git a/src/core/tcp.c b/src/core/tcp.c index ae14bb1c..a7ce7394 100644 --- a/src/core/tcp.c +++ b/src/core/tcp.c @@ -279,6 +279,7 @@ tcp_bind(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port) port = tcp_new_port(); } /* Check if the address already is in use. */ + /* Check the listen pcbs. */ for(cpcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; cpcb != NULL; cpcb = cpcb->next) { if (cpcb->local_port == port) { @@ -289,6 +290,7 @@ tcp_bind(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port) } } } + /* Check the connected pcbs. */ for(cpcb = tcp_active_pcbs; cpcb != NULL; cpcb = cpcb->next) { if (cpcb->local_port == port) { @@ -299,6 +301,7 @@ tcp_bind(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port) } } } + /* Check the bound, not yet connected pcbs. */ for(cpcb = tcp_bound_pcbs; cpcb != NULL; cpcb = cpcb->next) { if (cpcb->local_port == port) { if (ip_addr_isany(&(cpcb->local_ip)) || @@ -308,6 +311,15 @@ tcp_bind(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port) } } } + /* @todo: until SO_REUSEADDR is implemented (see task #6995 on savannah), + * we have to check the pcbs in TIME-WAIT state, also: */ + for(cpcb = tcp_tw_pcbs; cpcb != NULL; cpcb = cpcb->next) { + if (cpcb->local_port == port) { + if (ip_addr_cmp(&(cpcb->local_ip), ipaddr)) { + return ERR_USE; + } + } + } if (!ip_addr_isany(ipaddr)) { pcb->local_ip = *ipaddr;