From d3635c5eef74b530469a982a773242cb132ac637 Mon Sep 17 00:00:00 2001 From: goldsimon Date: Fri, 12 Feb 2010 15:33:02 +0000 Subject: [PATCH] patch #6865 (SO_REUSEADDR for TCP): if tcp_pcb.flags has TF_REUSEADDR set, allow binding to endpoint in TIME_WAIT --- CHANGELOG | 4 ++++ src/core/tcp.c | 14 +++++++++----- src/include/lwip/tcp.h | 1 + 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 0c453597..5f83e7cb 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -19,6 +19,10 @@ HISTORY ++ New features: + 2010-02-12: Simon Goldschmidt/Jeff Barber + * tcp.c/h: patch #6865 (SO_REUSEADDR for TCP): if tcp_pcb.flags has + TF_REUSEADDR set, allow binding to endpoint in TIME_WAIT + 2010-02-12: Simon Goldschmidt * sys layer: task #10139 (Prefer statically allocated memory): converted mbox and semaphore functions to take pointers to sys_mbox_t/sys_sem_t; diff --git a/src/core/tcp.c b/src/core/tcp.c index 2a44e3ae..c9796eb6 100644 --- a/src/core/tcp.c +++ b/src/core/tcp.c @@ -317,12 +317,16 @@ tcp_bind(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port) } } } - /* @todo: until SO_REUSEADDR is implemented (see task #6995 on savannah), + /* Unless the REUSEADDR flag is set, * 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 ((pcb->flags & TF_REUSEADDR) == 0) { + for(cpcb = tcp_tw_pcbs; cpcb != NULL; cpcb = cpcb->next) { + if (cpcb->local_port == port) { + if (ip_addr_isany(&(cpcb->local_ip)) || + ip_addr_isany(ipaddr) || + ip_addr_cmp(&(cpcb->local_ip), ipaddr)) { + return ERR_USE; + } } } } diff --git a/src/include/lwip/tcp.h b/src/include/lwip/tcp.h index 8c27354e..6ec3065a 100644 --- a/src/include/lwip/tcp.h +++ b/src/include/lwip/tcp.h @@ -370,6 +370,7 @@ struct tcp_pcb { #define TF_ACK_NOW ((u8_t)0x02U) /* Immediate ACK. */ #define TF_INFR ((u8_t)0x04U) /* In fast recovery. */ #define TF_TIMESTAMP ((u8_t)0x08U) /* Timestamp option enabled */ +#define TF_REUSEADDR ((u8_t)0x10U) /* Bind to endpoint in TIME_WAIT */ #define TF_FIN ((u8_t)0x20U) /* Connection was closed locally (FIN segment enqueued). */ #define TF_NODELAY ((u8_t)0x40U) /* Disable Nagle algorithm */ #define TF_NAGLEMEMERR ((u8_t)0x80U) /* nagle enabled, memerr, try to output to prevent delayed ACK to happen */