102 |
u8_t hdrlen; |
u8_t hdrlen; |
103 |
err_t err; |
err_t err; |
104 |
|
|
105 |
|
#ifdef SO_REUSE |
106 |
|
struct tcp_pcb *pcb_temp; |
107 |
|
int reuse = 0; |
108 |
|
int reuse_port = 0; |
109 |
|
#endif /* SO_REUSE */ |
110 |
|
|
111 |
PERF_START; |
PERF_START; |
112 |
|
|
179 |
/* Demultiplex an incoming segment. First, we check if it is destined |
/* Demultiplex an incoming segment. First, we check if it is destined |
180 |
for an active connection. */ |
for an active connection. */ |
181 |
prev = NULL; |
prev = NULL; |
182 |
|
|
183 |
|
#ifdef SO_REUSE |
184 |
|
pcb_temp = tcp_active_pcbs; |
185 |
|
|
186 |
|
again_1: |
187 |
|
|
188 |
|
/* Iterate through the TCP pcb list for a fully matching pcb */ |
189 |
|
for(pcb = pcb_temp; pcb != NULL; pcb = pcb->next) { |
190 |
|
#else /* SO_REUSE */ |
191 |
for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { |
for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { |
192 |
|
#endif /* SO_REUSE */ |
193 |
LWIP_ASSERT("tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED); |
LWIP_ASSERT("tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED); |
194 |
LWIP_ASSERT("tcp_input: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT); |
LWIP_ASSERT("tcp_input: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT); |
195 |
LWIP_ASSERT("tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN); |
LWIP_ASSERT("tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN); |
198 |
ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src)) && |
ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src)) && |
199 |
ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest))) { |
ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest))) { |
200 |
|
|
201 |
|
#ifdef SO_REUSE |
202 |
|
if(pcb->so_options & SOF_REUSEPORT) { |
203 |
|
if(reuse) { |
204 |
|
/* We processed one PCB already */ |
205 |
|
LWIP_DEBUGF(TCP_INPUT_DEBUG,("tcp_input: second or later PCB and SOF_REUSEPORT set.\n")); |
206 |
|
} else { |
207 |
|
/* First PCB with this address */ |
208 |
|
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: first PCB and SOF_REUSEPORT set.\n")); |
209 |
|
reuse = 1; |
210 |
|
} |
211 |
|
|
212 |
|
reuse_port = 1; |
213 |
|
p->ref++; |
214 |
|
|
215 |
|
/* We want to search on next socket after receiving */ |
216 |
|
pcb_temp = pcb->next; |
217 |
|
|
218 |
|
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: reference counter on PBUF set to %i\n", p->ref)); |
219 |
|
} else { |
220 |
|
if(reuse) { |
221 |
|
/* We processed one PCB already */ |
222 |
|
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: second or later PCB but SOF_REUSEPORT not set !\n")); |
223 |
|
} |
224 |
|
} |
225 |
|
#endif /* SO_REUSE */ |
226 |
|
|
227 |
/* Move this PCB to the front of the list so that subsequent |
/* Move this PCB to the front of the list so that subsequent |
228 |
lookups will be faster (we exploit locality in TCP segment |
lookups will be faster (we exploit locality in TCP segment |
229 |
arrivals). */ |
arrivals). */ |
368 |
tcp_debug_print_state(pcb->state); |
tcp_debug_print_state(pcb->state); |
369 |
#endif /* TCP_DEBUG */ |
#endif /* TCP_DEBUG */ |
370 |
#endif /* TCP_INPUT_DEBUG */ |
#endif /* TCP_INPUT_DEBUG */ |
371 |
|
#ifdef SO_REUSE |
372 |
|
/* First socket should receive now */ |
373 |
|
if(reuse_port) { |
374 |
|
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: searching next PCB.\n")); |
375 |
|
reuse_port = 0; |
376 |
|
|
377 |
|
/* We are searching connected sockets */ |
378 |
|
goto again_1; |
379 |
|
} |
380 |
|
#endif /* SO_REUSE */ |
381 |
|
|
382 |
} else { |
} else { |
383 |
|
#ifdef SO_REUSE |
384 |
|
if(reuse) { |
385 |
|
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: freeing PBUF with reference counter set to %i\n", p->ref)); |
386 |
|
pbuf_free(p); |
387 |
|
goto end; |
388 |
|
} |
389 |
|
#endif /* SO_REUSE */ |
390 |
/* If no matching PCB was found, send a TCP RST (reset) to the |
/* If no matching PCB was found, send a TCP RST (reset) to the |
391 |
sender. */ |
sender. */ |
392 |
LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_input: no PCB match found, resetting.\n")); |
LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_input: no PCB match found, resetting.\n")); |
401 |
} |
} |
402 |
pbuf_free(p); |
pbuf_free(p); |
403 |
} |
} |
404 |
|
#ifdef SO_REUSE |
405 |
|
end: |
406 |
|
#endif /* SO_REUSE */ |
407 |
LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane()); |
LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane()); |
408 |
PERF_STOP("tcp_input"); |
PERF_STOP("tcp_input"); |
409 |
} |
} |