SO_REUSE: tcp_input: correctly handle multiple pcbs listening on the same port (but different address): first search for a specific address an only pass to ANY if no specific address has been found listening

This commit is contained in:
goldsimon 2010-05-15 16:45:43 +00:00
parent 7e5b0a9eb6
commit a945bf07af

View File

@ -93,6 +93,10 @@ tcp_input(struct pbuf *p, struct netif *inp)
{ {
struct tcp_pcb *pcb, *prev; struct tcp_pcb *pcb, *prev;
struct tcp_pcb_listen *lpcb; struct tcp_pcb_listen *lpcb;
#if SO_REUSE
struct tcp_pcb *lpcb_prev = NULL;
struct tcp_pcb_listen *lpcb_any = NULL;
#endif /* SO_REUSE */
u8_t hdrlen; u8_t hdrlen;
err_t err; err_t err;
@ -222,9 +226,35 @@ tcp_input(struct pbuf *p, struct netif *inp)
are LISTENing for incoming connections. */ are LISTENing for incoming connections. */
prev = NULL; prev = NULL;
for(lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { for(lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
if ((ip_addr_isany(&(lpcb->local_ip)) || if (lpcb->local_port == tcphdr->dest) {
ip_addr_cmp(&(lpcb->local_ip), &(iphdr->dest))) && #if SO_REUSE
lpcb->local_port == tcphdr->dest) { if (ip_addr_cmp(&(lpcb->local_ip), &(iphdr->dest))) {
/* found an exact match */
break;
} else if(ip_addr_isany(&(lpcb->local_ip))) {
/* found an ANY-match */
lpcb_any = lpcb;
lpcb_prev = prev;
}
#else /* SO_REUSE */
if (ip_addr_cmp(&(lpcb->local_ip), &(iphdr->dest)) ||
ip_addr_isany(&(lpcb->local_ip))) {
/* found a match */
break;
}
#endif /* SO_REUSE */
}
prev = (struct tcp_pcb *)lpcb;
}
#if SO_REUSE
/* first try specific local IP */
if (lpcb == NULL) {
/* only pass to ANY if no specific local IP has been found */
lpcb = lpcb_any;
prev = lpcb_prev;
}
#endif /* SO_REUSE */
if (lpcb != NULL) {
/* Move this PCB to the front of the list so that subsequent /* Move this PCB to the front of the list so that subsequent
lookups will be faster (we exploit locality in TCP segment lookups will be faster (we exploit locality in TCP segment
arrivals). */ arrivals). */
@ -241,8 +271,6 @@ tcp_input(struct pbuf *p, struct netif *inp)
pbuf_free(p); pbuf_free(p);
return; return;
} }
prev = (struct tcp_pcb *)lpcb;
}
} }
#if TCP_INPUT_DEBUG #if TCP_INPUT_DEBUG