[TCPIP]
[reactos.git] / reactos / lib / drivers / lwip / src / core / tcp_in.c
1 /**
2 * @file
3 * Transmission Control Protocol, incoming traffic
4 *
5 * The input processing functions of the TCP layer.
6 *
7 * These functions are generally called in the order (ip_input() ->)
8 * tcp_input() -> * tcp_process() -> tcp_receive() (-> application).
9 *
10 */
11
12 /*
13 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
14 * All rights reserved.
15 *
16 * Redistribution and use in source and binary forms, with or without modification,
17 * are permitted provided that the following conditions are met:
18 *
19 * 1. Redistributions of source code must retain the above copyright notice,
20 * this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright notice,
22 * this list of conditions and the following disclaimer in the documentation
23 * and/or other materials provided with the distribution.
24 * 3. The name of the author may not be used to endorse or promote products
25 * derived from this software without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
28 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
29 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
30 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
32 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
35 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
36 * OF SUCH DAMAGE.
37 *
38 * This file is part of the lwIP TCP/IP stack.
39 *
40 * Author: Adam Dunkels <adam@sics.se>
41 *
42 */
43
44 #include "lwip/opt.h"
45
46 #if LWIP_TCP /* don't build if not configured for use in lwipopts.h */
47
48 #include "lwip/tcp_impl.h"
49 #include "lwip/def.h"
50 #include "lwip/ip_addr.h"
51 #include "lwip/netif.h"
52 #include "lwip/mem.h"
53 #include "lwip/memp.h"
54 #include "lwip/inet_chksum.h"
55 #include "lwip/stats.h"
56 #include "lwip/snmp.h"
57 #include "arch/perf.h"
58
59 /* These variables are global to all functions involved in the input
60 processing of TCP segments. They are set by the tcp_input()
61 function. */
62 static struct tcp_seg inseg;
63 static struct tcp_hdr *tcphdr;
64 static struct ip_hdr *iphdr;
65 static u32_t seqno, ackno;
66 static u8_t flags;
67 static u16_t tcplen;
68
69 static u8_t recv_flags;
70 static struct pbuf *recv_data;
71
72 struct tcp_pcb *tcp_input_pcb;
73
74 /* Forward declarations. */
75 static err_t tcp_process(struct tcp_pcb *pcb);
76 static void tcp_receive(struct tcp_pcb *pcb);
77 static void tcp_parseopt(struct tcp_pcb *pcb);
78
79 static err_t tcp_listen_input(struct tcp_pcb_listen *pcb);
80 static err_t tcp_timewait_input(struct tcp_pcb *pcb);
81
82 static const char * const tcp_state_str[] = {
83 "CLOSED",
84 "LISTEN",
85 "SYN_SENT",
86 "SYN_RCVD",
87 "ESTABLISHED",
88 "FIN_WAIT_1",
89 "FIN_WAIT_2",
90 "CLOSE_WAIT",
91 "CLOSING",
92 "LAST_ACK",
93 "TIME_WAIT"
94 };
95
96 /**
97 * The initial input processing of TCP. It verifies the TCP header, demultiplexes
98 * the segment between the PCBs and passes it on to tcp_process(), which implements
99 * the TCP finite state machine. This function is called by the IP layer (in
100 * ip_input()).
101 *
102 * @param p received TCP segment to process (p->payload pointing to the IP header)
103 * @param inp network interface on which this segment was received
104 */
105 void
106 tcp_input(struct pbuf *p, struct netif *inp)
107 {
108 struct tcp_pcb *pcb, *prev;
109 struct tcp_pcb_listen *lpcb;
110 #if SO_REUSE
111 struct tcp_pcb *lpcb_prev = NULL;
112 struct tcp_pcb_listen *lpcb_any = NULL;
113 #endif /* SO_REUSE */
114 u8_t hdrlen;
115 err_t err;
116
117 PERF_START;
118
119 TCP_STATS_INC(tcp.recv);
120 snmp_inc_tcpinsegs();
121
122 iphdr = (struct ip_hdr *)p->payload;
123 tcphdr = (struct tcp_hdr *)((u8_t *)p->payload + IPH_HL(iphdr) * 4);
124
125 #if TCP_INPUT_DEBUG
126 tcp_debug_print(tcphdr);
127 #endif
128
129 /* remove header from payload */
130 if (pbuf_header(p, -((s16_t)(IPH_HL(iphdr) * 4))) || (p->tot_len < sizeof(struct tcp_hdr))) {
131 /* drop short packets */
132 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet (%"U16_F" bytes) discarded\n", p->tot_len));
133 TCP_STATS_INC(tcp.lenerr);
134 TCP_STATS_INC(tcp.drop);
135 snmp_inc_tcpinerrs();
136 pbuf_free(p);
137 return;
138 }
139
140 /* Don't even process incoming broadcasts/multicasts. */
141 if (ip_addr_isbroadcast(&current_iphdr_dest, inp) ||
142 ip_addr_ismulticast(&current_iphdr_dest)) {
143 TCP_STATS_INC(tcp.proterr);
144 TCP_STATS_INC(tcp.drop);
145 snmp_inc_tcpinerrs();
146 pbuf_free(p);
147 return;
148 }
149
150 #if CHECKSUM_CHECK_TCP
151 /* Verify TCP checksum. */
152 if (inet_chksum_pseudo(p, ip_current_src_addr(), ip_current_dest_addr(),
153 IP_PROTO_TCP, p->tot_len) != 0) {
154 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packet discarded due to failing checksum 0x%04"X16_F"\n",
155 inet_chksum_pseudo(p, ip_current_src_addr(), ip_current_dest_addr(),
156 IP_PROTO_TCP, p->tot_len)));
157 #if TCP_DEBUG
158 tcp_debug_print(tcphdr);
159 #endif /* TCP_DEBUG */
160 TCP_STATS_INC(tcp.chkerr);
161 TCP_STATS_INC(tcp.drop);
162 snmp_inc_tcpinerrs();
163 pbuf_free(p);
164 return;
165 }
166 #endif
167
168 /* Move the payload pointer in the pbuf so that it points to the
169 TCP data instead of the TCP header. */
170 hdrlen = TCPH_HDRLEN(tcphdr);
171 if(pbuf_header(p, -(hdrlen * 4))){
172 /* drop short packets */
173 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet\n"));
174 TCP_STATS_INC(tcp.lenerr);
175 TCP_STATS_INC(tcp.drop);
176 snmp_inc_tcpinerrs();
177 pbuf_free(p);
178 return;
179 }
180
181 /* Convert fields in TCP header to host byte order. */
182 tcphdr->src = ntohs(tcphdr->src);
183 tcphdr->dest = ntohs(tcphdr->dest);
184 seqno = tcphdr->seqno = ntohl(tcphdr->seqno);
185 ackno = tcphdr->ackno = ntohl(tcphdr->ackno);
186 tcphdr->wnd = ntohs(tcphdr->wnd);
187
188 flags = TCPH_FLAGS(tcphdr);
189 tcplen = p->tot_len + ((flags & (TCP_FIN | TCP_SYN)) ? 1 : 0);
190
191 /* Demultiplex an incoming segment. First, we check if it is destined
192 for an active connection. */
193 prev = NULL;
194
195
196 for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
197 LWIP_ASSERT("tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED);
198 LWIP_ASSERT("tcp_input: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);
199 LWIP_ASSERT("tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN);
200 if (pcb->remote_port == tcphdr->src &&
201 pcb->local_port == tcphdr->dest &&
202 ip_addr_cmp(&(pcb->remote_ip), &current_iphdr_src) &&
203 ip_addr_cmp(&(pcb->local_ip), &current_iphdr_dest)) {
204
205 /* Move this PCB to the front of the list so that subsequent
206 lookups will be faster (we exploit locality in TCP segment
207 arrivals). */
208 LWIP_ASSERT("tcp_input: pcb->next != pcb (before cache)", pcb->next != pcb);
209 if (prev != NULL) {
210 prev->next = pcb->next;
211 pcb->next = tcp_active_pcbs;
212 tcp_active_pcbs = pcb;
213 }
214 LWIP_ASSERT("tcp_input: pcb->next != pcb (after cache)", pcb->next != pcb);
215 break;
216 }
217 prev = pcb;
218 }
219
220 if (pcb == NULL) {
221 /* If it did not go to an active connection, we check the connections
222 in the TIME-WAIT state. */
223 for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
224 LWIP_ASSERT("tcp_input: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
225 if (pcb->remote_port == tcphdr->src &&
226 pcb->local_port == tcphdr->dest &&
227 ip_addr_cmp(&(pcb->remote_ip), &current_iphdr_src) &&
228 ip_addr_cmp(&(pcb->local_ip), &current_iphdr_dest)) {
229 /* We don't really care enough to move this PCB to the front
230 of the list since we are not very likely to receive that
231 many segments for connections in TIME-WAIT. */
232 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for TIME_WAITing connection.\n"));
233 tcp_timewait_input(pcb);
234 pbuf_free(p);
235 return;
236 }
237 }
238
239 /* Finally, if we still did not get a match, we check all PCBs that
240 are LISTENing for incoming connections. */
241 prev = NULL;
242 for(lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
243 if (lpcb->local_port == tcphdr->dest) {
244 #if SO_REUSE
245 if (ip_addr_cmp(&(lpcb->local_ip), &current_iphdr_dest)) {
246 /* found an exact match */
247 break;
248 } else if(ip_addr_isany(&(lpcb->local_ip))) {
249 /* found an ANY-match */
250 lpcb_any = lpcb;
251 lpcb_prev = prev;
252 }
253 #else /* SO_REUSE */
254 if (ip_addr_cmp(&(lpcb->local_ip), &current_iphdr_dest) ||
255 ip_addr_isany(&(lpcb->local_ip))) {
256 /* found a match */
257 break;
258 }
259 #endif /* SO_REUSE */
260 }
261 prev = (struct tcp_pcb *)lpcb;
262 }
263 #if SO_REUSE
264 /* first try specific local IP */
265 if (lpcb == NULL) {
266 /* only pass to ANY if no specific local IP has been found */
267 lpcb = lpcb_any;
268 prev = lpcb_prev;
269 }
270 #endif /* SO_REUSE */
271 if (lpcb != NULL) {
272 /* Move this PCB to the front of the list so that subsequent
273 lookups will be faster (we exploit locality in TCP segment
274 arrivals). */
275 if (prev != NULL) {
276 ((struct tcp_pcb_listen *)prev)->next = lpcb->next;
277 /* our successor is the remainder of the listening list */
278 lpcb->next = tcp_listen_pcbs.listen_pcbs;
279 /* put this listening pcb at the head of the listening list */
280 tcp_listen_pcbs.listen_pcbs = lpcb;
281 }
282
283 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for LISTENing connection.\n"));
284 tcp_listen_input(lpcb);
285 pbuf_free(p);
286 return;
287 }
288 }
289
290 #if TCP_INPUT_DEBUG
291 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("+-+-+-+-+-+-+-+-+-+-+-+-+-+- tcp_input: flags "));
292 tcp_debug_print_flags(TCPH_FLAGS(tcphdr));
293 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n"));
294 #endif /* TCP_INPUT_DEBUG */
295
296
297 if (pcb != NULL) {
298 /* The incoming segment belongs to a connection. */
299 #if TCP_INPUT_DEBUG
300 #if TCP_DEBUG
301 tcp_debug_print_state(pcb->state);
302 #endif /* TCP_DEBUG */
303 #endif /* TCP_INPUT_DEBUG */
304
305 /* Set up a tcp_seg structure. */
306 inseg.next = NULL;
307 inseg.len = p->tot_len;
308 inseg.p = p;
309 inseg.tcphdr = tcphdr;
310
311 recv_data = NULL;
312 recv_flags = 0;
313
314 /* If there is data which was previously "refused" by upper layer */
315 if (pcb->refused_data != NULL) {
316 /* Notify again application with data previously received. */
317 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: notify kept packet\n"));
318 TCP_EVENT_RECV(pcb, pcb->refused_data, ERR_OK, err);
319 if (err == ERR_OK) {
320 pcb->refused_data = NULL;
321 } else if ((err == ERR_ABRT) || (tcplen > 0)) {
322 /* if err == ERR_ABRT, 'pcb' is already deallocated */
323 /* Drop incoming packets because pcb is "full" (only if the incoming
324 segment contains data). */
325 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: drop incoming packets, because pcb is \"full\"\n"));
326 TCP_STATS_INC(tcp.drop);
327 snmp_inc_tcpinerrs();
328 pbuf_free(p);
329 return;
330 }
331 }
332 tcp_input_pcb = pcb;
333 err = tcp_process(pcb);
334 /* A return value of ERR_ABRT means that tcp_abort() was called
335 and that the pcb has been freed. If so, we don't do anything. */
336 if (err != ERR_ABRT) {
337 if (recv_flags & TF_RESET) {
338 /* TF_RESET means that the connection was reset by the other
339 end. We then call the error callback to inform the
340 application that the connection is dead before we
341 deallocate the PCB. */
342 TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_RST);
343 tcp_pcb_remove(&tcp_active_pcbs, pcb);
344 memp_free(MEMP_TCP_PCB, pcb);
345 } else if (recv_flags & TF_CLOSED) {
346 /* The connection has been closed and we will deallocate the
347 PCB. */
348 TCP_EVENT_CLOSED(pcb, err);
349 if (err == ERR_ABRT) {
350 goto aborted;
351 }
352 tcp_pcb_remove(&tcp_active_pcbs, pcb);
353 memp_free(MEMP_TCP_PCB, pcb);
354 } else {
355 err = ERR_OK;
356 /* If the application has registered a "sent" function to be
357 called when new send buffer space is available, we call it
358 now. */
359 if (pcb->acked > 0) {
360 TCP_EVENT_SENT(pcb, pcb->acked, err);
361 if (err == ERR_ABRT) {
362 goto aborted;
363 }
364 }
365
366 if (recv_data != NULL) {
367 LWIP_ASSERT("pcb->refused_data == NULL", pcb->refused_data == NULL);
368 if (pcb->flags & TF_RXCLOSED) {
369 /* received data although already closed -> abort (send RST) to
370 notify the remote host that not all data has been processed */
371 pbuf_free(recv_data);
372 tcp_abort(pcb);
373 goto aborted;
374 }
375 if (flags & TCP_PSH) {
376 recv_data->flags |= PBUF_FLAG_PUSH;
377 }
378
379 /* Notify application that data has been received. */
380 TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err);
381 if (err == ERR_ABRT) {
382 goto aborted;
383 }
384
385 /* If the upper layer can't receive this data, store it */
386 if (err != ERR_OK) {
387 pcb->refused_data = recv_data;
388 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: keep incoming packet, because pcb is \"full\"\n"));
389 }
390 }
391
392 /* If a FIN segment was received, we call the callback
393 function with a NULL buffer to indicate EOF. */
394 if (recv_flags & TF_GOT_FIN) {
395 /* correct rcv_wnd as the application won't call tcp_recved()
396 for the FIN's seqno */
397 if (pcb->rcv_wnd != TCP_WND) {
398 pcb->rcv_wnd++;
399 }
400 TCP_EVENT_CLOSED(pcb, err);
401 if (err == ERR_ABRT) {
402 goto aborted;
403 }
404 }
405
406 tcp_input_pcb = NULL;
407 /* Try to send something out. */
408 tcp_output(pcb);
409 #if TCP_INPUT_DEBUG
410 #if TCP_DEBUG
411 tcp_debug_print_state(pcb->state);
412 #endif /* TCP_DEBUG */
413 #endif /* TCP_INPUT_DEBUG */
414 }
415 }
416 /* Jump target if pcb has been aborted in a callback (by calling tcp_abort()).
417 Below this line, 'pcb' may not be dereferenced! */
418 aborted:
419 tcp_input_pcb = NULL;
420 recv_data = NULL;
421
422 /* give up our reference to inseg.p */
423 if (inseg.p != NULL)
424 {
425 pbuf_free(inseg.p);
426 inseg.p = NULL;
427 }
428 } else {
429
430 /* If no matching PCB was found, send a TCP RST (reset) to the
431 sender. */
432 LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_input: no PCB match found, resetting.\n"));
433 if (!(TCPH_FLAGS(tcphdr) & TCP_RST)) {
434 TCP_STATS_INC(tcp.proterr);
435 TCP_STATS_INC(tcp.drop);
436 tcp_rst(ackno, seqno + tcplen,
437 ip_current_dest_addr(), ip_current_src_addr(),
438 tcphdr->dest, tcphdr->src);
439 }
440 pbuf_free(p);
441 }
442
443 LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane());
444 PERF_STOP("tcp_input");
445 }
446
447 /**
448 * Called by tcp_input() when a segment arrives for a listening
449 * connection (from tcp_input()).
450 *
451 * @param pcb the tcp_pcb_listen for which a segment arrived
452 * @return ERR_OK if the segment was processed
453 * another err_t on error
454 *
455 * @note the return value is not (yet?) used in tcp_input()
456 * @note the segment which arrived is saved in global variables, therefore only the pcb
457 * involved is passed as a parameter to this function
458 */
459 static err_t
460 tcp_listen_input(struct tcp_pcb_listen *pcb)
461 {
462 struct tcp_pcb *npcb;
463 err_t rc;
464
465 /* In the LISTEN state, we check for incoming SYN segments,
466 creates a new PCB, and responds with a SYN|ACK. */
467 if (flags & TCP_ACK) {
468 /* For incoming segments with the ACK flag set, respond with a
469 RST. */
470 LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_listen_input: ACK in LISTEN, sending reset\n"));
471 tcp_rst(ackno + 1, seqno + tcplen,
472 ip_current_dest_addr(), ip_current_src_addr(),
473 tcphdr->dest, tcphdr->src);
474 } else if (flags & TCP_SYN) {
475 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection request %"U16_F" -> %"U16_F".\n", tcphdr->src, tcphdr->dest));
476 #if TCP_LISTEN_BACKLOG
477 if (pcb->accepts_pending >= pcb->backlog) {
478 LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: listen backlog exceeded for port %"U16_F"\n", tcphdr->dest));
479 return ERR_ABRT;
480 }
481 #endif /* TCP_LISTEN_BACKLOG */
482 npcb = tcp_alloc(pcb->prio);
483 /* If a new PCB could not be created (probably due to lack of memory),
484 we don't do anything, but rely on the sender will retransmit the
485 SYN at a time when we have more memory available. */
486 if (npcb == NULL) {
487 LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: could not allocate PCB\n"));
488 TCP_STATS_INC(tcp.memerr);
489 return ERR_MEM;
490 }
491 #if TCP_LISTEN_BACKLOG
492 pcb->accepts_pending++;
493 #endif /* TCP_LISTEN_BACKLOG */
494 /* Set up the new PCB. */
495 ip_addr_copy(npcb->local_ip, current_iphdr_dest);
496 npcb->local_port = pcb->local_port;
497 ip_addr_copy(npcb->remote_ip, current_iphdr_src);
498 npcb->remote_port = tcphdr->src;
499 npcb->state = SYN_RCVD;
500 npcb->rcv_nxt = seqno + 1;
501 npcb->rcv_ann_right_edge = npcb->rcv_nxt;
502 npcb->snd_wnd = tcphdr->wnd;
503 npcb->ssthresh = npcb->snd_wnd;
504 npcb->snd_wl1 = seqno - 1;/* initialise to seqno-1 to force window update */
505 npcb->callback_arg = pcb->callback_arg;
506 #if LWIP_CALLBACK_API
507 npcb->accept = pcb->accept;
508 #endif /* LWIP_CALLBACK_API */
509 /* inherit socket options */
510 npcb->so_options = pcb->so_options & SOF_INHERITED;
511 /* Register the new PCB so that we can begin receiving segments
512 for it. */
513 TCP_REG(&tcp_active_pcbs, npcb);
514
515 /* Parse any options in the SYN. */
516 tcp_parseopt(npcb);
517 #if TCP_CALCULATE_EFF_SEND_MSS
518 npcb->mss = tcp_eff_send_mss(npcb->mss, &(npcb->remote_ip));
519 #endif /* TCP_CALCULATE_EFF_SEND_MSS */
520
521 snmp_inc_tcppassiveopens();
522
523 /* Send a SYN|ACK together with the MSS option. */
524 rc = tcp_enqueue_flags(npcb, TCP_SYN | TCP_ACK);
525 if (rc != ERR_OK) {
526 tcp_abandon(npcb, 0);
527 return rc;
528 }
529 return tcp_output(npcb);
530 }
531 return ERR_OK;
532 }
533
534 /**
535 * Called by tcp_input() when a segment arrives for a connection in
536 * TIME_WAIT.
537 *
538 * @param pcb the tcp_pcb for which a segment arrived
539 *
540 * @note the segment which arrived is saved in global variables, therefore only the pcb
541 * involved is passed as a parameter to this function
542 */
543 static err_t
544 tcp_timewait_input(struct tcp_pcb *pcb)
545 {
546 /* RFC 1337: in TIME_WAIT, ignore RST and ACK FINs + any 'acceptable' segments */
547 /* RFC 793 3.9 Event Processing - Segment Arrives:
548 * - first check sequence number - we skip that one in TIME_WAIT (always
549 * acceptable since we only send ACKs)
550 * - second check the RST bit (... return) */
551 if (flags & TCP_RST) {
552 return ERR_OK;
553 }
554 /* - fourth, check the SYN bit, */
555 if (flags & TCP_SYN) {
556 /* If an incoming segment is not acceptable, an acknowledgment
557 should be sent in reply */
558 if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt+pcb->rcv_wnd)) {
559 /* If the SYN is in the window it is an error, send a reset */
560 tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(),
561 tcphdr->dest, tcphdr->src);
562 return ERR_OK;
563 }
564 } else if (flags & TCP_FIN) {
565 /* - eighth, check the FIN bit: Remain in the TIME-WAIT state.
566 Restart the 2 MSL time-wait timeout.*/
567 pcb->tmr = tcp_ticks;
568 }
569
570 if ((tcplen > 0)) {
571 /* Acknowledge data, FIN or out-of-window SYN */
572 pcb->flags |= TF_ACK_NOW;
573 return tcp_output(pcb);
574 }
575 return ERR_OK;
576 }
577
578 /**
579 * Implements the TCP state machine. Called by tcp_input. In some
580 * states tcp_receive() is called to receive data. The tcp_seg
581 * argument will be freed by the caller (tcp_input()) unless the
582 * recv_data pointer in the pcb is set.
583 *
584 * @param pcb the tcp_pcb for which a segment arrived
585 *
586 * @note the segment which arrived is saved in global variables, therefore only the pcb
587 * involved is passed as a parameter to this function
588 */
589 static err_t
590 tcp_process(struct tcp_pcb *pcb)
591 {
592 struct tcp_seg *rseg;
593 u8_t acceptable = 0;
594 err_t err;
595
596 err = ERR_OK;
597
598 /* Process incoming RST segments. */
599 if (flags & TCP_RST) {
600 /* First, determine if the reset is acceptable. */
601 if (pcb->state == SYN_SENT) {
602 if (ackno == pcb->snd_nxt) {
603 acceptable = 1;
604 }
605 } else {
606 if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt,
607 pcb->rcv_nxt+pcb->rcv_wnd)) {
608 acceptable = 1;
609 }
610 }
611
612 if (acceptable) {
613 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: Connection RESET\n"));
614 LWIP_ASSERT("tcp_input: pcb->state != CLOSED", pcb->state != CLOSED);
615 recv_flags |= TF_RESET;
616 pcb->flags &= ~TF_ACK_DELAY;
617 return ERR_RST;
618 } else {
619 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n",
620 seqno, pcb->rcv_nxt));
621 LWIP_DEBUGF(TCP_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n",
622 seqno, pcb->rcv_nxt));
623 return ERR_OK;
624 }
625 }
626
627 if ((flags & TCP_SYN) && (pcb->state != SYN_SENT && pcb->state != SYN_RCVD)) {
628 /* Cope with new connection attempt after remote end crashed */
629 tcp_ack_now(pcb);
630 return ERR_OK;
631 }
632
633 if ((pcb->flags & TF_RXCLOSED) == 0) {
634 /* Update the PCB (in)activity timer unless rx is closed (see tcp_shutdown) */
635 pcb->tmr = tcp_ticks;
636 }
637 pcb->keep_cnt_sent = 0;
638
639 tcp_parseopt(pcb);
640
641 /* Do different things depending on the TCP state. */
642 switch (pcb->state) {
643 case SYN_SENT:
644 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %"U32_F" pcb->snd_nxt %"U32_F" unacked %"U32_F"\n", ackno,
645 pcb->snd_nxt, ntohl(pcb->unacked->tcphdr->seqno)));
646 /* received SYN ACK with expected sequence number? */
647 if ((flags & TCP_ACK) && (flags & TCP_SYN)
648 && ackno == ntohl(pcb->unacked->tcphdr->seqno) + 1) {
649 pcb->snd_buf++;
650 pcb->rcv_nxt = seqno + 1;
651 pcb->rcv_ann_right_edge = pcb->rcv_nxt;
652 pcb->lastack = ackno;
653 pcb->snd_wnd = tcphdr->wnd;
654 pcb->snd_wl1 = seqno - 1; /* initialise to seqno - 1 to force window update */
655 pcb->state = ESTABLISHED;
656
657 #if TCP_CALCULATE_EFF_SEND_MSS
658 pcb->mss = tcp_eff_send_mss(pcb->mss, &(pcb->remote_ip));
659 #endif /* TCP_CALCULATE_EFF_SEND_MSS */
660
661 /* Set ssthresh again after changing pcb->mss (already set in tcp_connect
662 * but for the default value of pcb->mss) */
663 pcb->ssthresh = pcb->mss * 10;
664
665 pcb->cwnd = ((pcb->cwnd == 1) ? (pcb->mss * 2) : pcb->mss);
666 LWIP_ASSERT("pcb->snd_queuelen > 0", (pcb->snd_queuelen > 0));
667 --pcb->snd_queuelen;
668 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_process: SYN-SENT --queuelen %"U16_F"\n", (u16_t)pcb->snd_queuelen));
669 rseg = pcb->unacked;
670 pcb->unacked = rseg->next;
671
672 /* If there's nothing left to acknowledge, stop the retransmit
673 timer, otherwise reset it to start again */
674 if(pcb->unacked == NULL)
675 pcb->rtime = -1;
676 else {
677 pcb->rtime = 0;
678 pcb->nrtx = 0;
679 }
680
681 tcp_seg_free(rseg);
682
683 /* Call the user specified function to call when sucessfully
684 * connected. */
685 TCP_EVENT_CONNECTED(pcb, ERR_OK, err);
686 if (err == ERR_ABRT) {
687 return ERR_ABRT;
688 }
689 tcp_ack_now(pcb);
690 }
691 /* received ACK? possibly a half-open connection */
692 else if (flags & TCP_ACK) {
693 /* send a RST to bring the other side in a non-synchronized state. */
694 tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(),
695 tcphdr->dest, tcphdr->src);
696 }
697 break;
698 case SYN_RCVD:
699 if (flags & TCP_ACK) {
700 /* expected ACK number? */
701 if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)) {
702 u16_t old_cwnd;
703 pcb->state = ESTABLISHED;
704 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection established %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
705 #if LWIP_CALLBACK_API
706 LWIP_ASSERT("pcb->accept != NULL", pcb->accept != NULL);
707 #endif
708 /* Call the accept function. */
709 TCP_EVENT_ACCEPT(pcb, ERR_OK, err);
710 if (err != ERR_OK) {
711 /* If the accept function returns with an error, we abort
712 * the connection. */
713 /* Already aborted? */
714 if (err != ERR_ABRT) {
715 tcp_abort(pcb);
716 }
717 return ERR_ABRT;
718 }
719 old_cwnd = pcb->cwnd;
720 /* If there was any data contained within this ACK,
721 * we'd better pass it on to the application as well. */
722 tcp_receive(pcb);
723
724 /* Prevent ACK for SYN to generate a sent event */
725 if (pcb->acked != 0) {
726 pcb->acked--;
727 }
728
729 pcb->cwnd = ((old_cwnd == 1) ? (pcb->mss * 2) : pcb->mss);
730
731 if (recv_flags & TF_GOT_FIN) {
732 tcp_ack_now(pcb);
733 pcb->state = CLOSE_WAIT;
734 }
735 } else {
736 /* incorrect ACK number, send RST */
737 tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(),
738 tcphdr->dest, tcphdr->src);
739 }
740 } else if ((flags & TCP_SYN) && (seqno == pcb->rcv_nxt - 1)) {
741 /* Looks like another copy of the SYN - retransmit our SYN-ACK */
742 tcp_rexmit(pcb);
743 }
744 break;
745 case CLOSE_WAIT:
746 /* FALLTHROUGH */
747 case ESTABLISHED:
748 tcp_receive(pcb);
749 if (recv_flags & TF_GOT_FIN) { /* passive close */
750 tcp_ack_now(pcb);
751 pcb->state = CLOSE_WAIT;
752 }
753 break;
754 case FIN_WAIT_1:
755 tcp_receive(pcb);
756 if (recv_flags & TF_GOT_FIN) {
757 if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) {
758 LWIP_DEBUGF(TCP_DEBUG,
759 ("TCP connection closed: FIN_WAIT_1 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
760 tcp_ack_now(pcb);
761 tcp_pcb_purge(pcb);
762 TCP_RMV(&tcp_active_pcbs, pcb);
763 pcb->state = TIME_WAIT;
764 TCP_REG(&tcp_tw_pcbs, pcb);
765 } else {
766 tcp_ack_now(pcb);
767 pcb->state = CLOSING;
768 }
769 } else if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) {
770 pcb->state = FIN_WAIT_2;
771 }
772 break;
773 case FIN_WAIT_2:
774 tcp_receive(pcb);
775 if (recv_flags & TF_GOT_FIN) {
776 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: FIN_WAIT_2 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
777 tcp_ack_now(pcb);
778 tcp_pcb_purge(pcb);
779 TCP_RMV(&tcp_active_pcbs, pcb);
780 pcb->state = TIME_WAIT;
781 TCP_REG(&tcp_tw_pcbs, pcb);
782 }
783 break;
784 case CLOSING:
785 tcp_receive(pcb);
786 if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
787 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: CLOSING %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
788 tcp_pcb_purge(pcb);
789 TCP_RMV(&tcp_active_pcbs, pcb);
790 pcb->state = TIME_WAIT;
791 TCP_REG(&tcp_tw_pcbs, pcb);
792 }
793 break;
794 case LAST_ACK:
795 tcp_receive(pcb);
796 if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
797 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: LAST_ACK %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
798 /* bugfix #21699: don't set pcb->state to CLOSED here or we risk leaking segments */
799 recv_flags |= TF_CLOSED;
800 }
801 break;
802 default:
803 break;
804 }
805 return ERR_OK;
806 }
807
808 #if TCP_QUEUE_OOSEQ
809 /**
810 * Insert segment into the list (segments covered with new one will be deleted)
811 *
812 * Called from tcp_receive()
813 */
814 static void
815 tcp_oos_insert_segment(struct tcp_seg *cseg, struct tcp_seg *next)
816 {
817 struct tcp_seg *old_seg;
818
819 if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) {
820 /* received segment overlaps all following segments */
821 tcp_segs_free(next);
822 next = NULL;
823 }
824 else {
825 /* delete some following segments
826 oos queue may have segments with FIN flag */
827 while (next &&
828 TCP_SEQ_GEQ((seqno + cseg->len),
829 (next->tcphdr->seqno + next->len))) {
830 /* cseg with FIN already processed */
831 if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) {
832 TCPH_SET_FLAG(cseg->tcphdr, TCP_FIN);
833 }
834 old_seg = next;
835 next = next->next;
836 tcp_seg_free(old_seg);
837 }
838 if (next &&
839 TCP_SEQ_GT(seqno + cseg->len, next->tcphdr->seqno)) {
840 /* We need to trim the incoming segment. */
841 cseg->len = (u16_t)(next->tcphdr->seqno - seqno);
842 pbuf_realloc(cseg->p, cseg->len);
843 }
844 }
845 cseg->next = next;
846 }
847 #endif /* TCP_QUEUE_OOSEQ */
848
849 /**
850 * Called by tcp_process. Checks if the given segment is an ACK for outstanding
851 * data, and if so frees the memory of the buffered data. Next, is places the
852 * segment on any of the receive queues (pcb->recved or pcb->ooseq). If the segment
853 * is buffered, the pbuf is referenced by pbuf_ref so that it will not be freed until
854 * i it has been removed from the buffer.
855 *
856 * If the incoming segment constitutes an ACK for a segment that was used for RTT
857 * estimation, the RTT is estimated here as well.
858 *
859 * Called from tcp_process().
860 */
861 static void
862 tcp_receive(struct tcp_pcb *pcb)
863 {
864 struct tcp_seg *next;
865 #if TCP_QUEUE_OOSEQ
866 struct tcp_seg *prev, *cseg;
867 #endif /* TCP_QUEUE_OOSEQ */
868 struct pbuf *p;
869 s32_t off;
870 s16_t m;
871 u32_t right_wnd_edge;
872 u16_t new_tot_len;
873 int found_dupack = 0;
874
875 if (flags & TCP_ACK) {
876 right_wnd_edge = pcb->snd_wnd + pcb->snd_wl2;
877
878 /* Update window. */
879 if (TCP_SEQ_LT(pcb->snd_wl1, seqno) ||
880 (pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) ||
881 (pcb->snd_wl2 == ackno && tcphdr->wnd > pcb->snd_wnd)) {
882 pcb->snd_wnd = tcphdr->wnd;
883 pcb->snd_wl1 = seqno;
884 pcb->snd_wl2 = ackno;
885 if (pcb->snd_wnd > 0 && pcb->persist_backoff > 0) {
886 pcb->persist_backoff = 0;
887 }
888 LWIP_DEBUGF(TCP_WND_DEBUG, ("tcp_receive: window update %"U16_F"\n", pcb->snd_wnd));
889 #if TCP_WND_DEBUG
890 } else {
891 if (pcb->snd_wnd != tcphdr->wnd) {
892 LWIP_DEBUGF(TCP_WND_DEBUG,
893 ("tcp_receive: no window update lastack %"U32_F" ackno %"
894 U32_F" wl1 %"U32_F" seqno %"U32_F" wl2 %"U32_F"\n",
895 pcb->lastack, ackno, pcb->snd_wl1, seqno, pcb->snd_wl2));
896 }
897 #endif /* TCP_WND_DEBUG */
898 }
899
900 /* (From Stevens TCP/IP Illustrated Vol II, p970.) Its only a
901 * duplicate ack if:
902 * 1) It doesn't ACK new data
903 * 2) length of received packet is zero (i.e. no payload)
904 * 3) the advertised window hasn't changed
905 * 4) There is outstanding unacknowledged data (retransmission timer running)
906 * 5) The ACK is == biggest ACK sequence number so far seen (snd_una)
907 *
908 * If it passes all five, should process as a dupack:
909 * a) dupacks < 3: do nothing
910 * b) dupacks == 3: fast retransmit
911 * c) dupacks > 3: increase cwnd
912 *
913 * If it only passes 1-3, should reset dupack counter (and add to
914 * stats, which we don't do in lwIP)
915 *
916 * If it only passes 1, should reset dupack counter
917 *
918 */
919
920 /* Clause 1 */
921 if (TCP_SEQ_LEQ(ackno, pcb->lastack)) {
922 pcb->acked = 0;
923 /* Clause 2 */
924 if (tcplen == 0) {
925 /* Clause 3 */
926 if (pcb->snd_wl2 + pcb->snd_wnd == right_wnd_edge){
927 /* Clause 4 */
928 if (pcb->rtime >= 0) {
929 /* Clause 5 */
930 if (pcb->lastack == ackno) {
931 found_dupack = 1;
932 if (pcb->dupacks + 1 > pcb->dupacks)
933 ++pcb->dupacks;
934 if (pcb->dupacks > 3) {
935 /* Inflate the congestion window, but not if it means that
936 the value overflows. */
937 if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {
938 pcb->cwnd += pcb->mss;
939 }
940 } else if (pcb->dupacks == 3) {
941 /* Do fast retransmit */
942 tcp_rexmit_fast(pcb);
943 }
944 }
945 }
946 }
947 }
948 /* If Clause (1) or more is true, but not a duplicate ack, reset
949 * count of consecutive duplicate acks */
950 if (!found_dupack) {
951 pcb->dupacks = 0;
952 }
953 } else if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)){
954 /* We come here when the ACK acknowledges new data. */
955
956 /* Reset the "IN Fast Retransmit" flag, since we are no longer
957 in fast retransmit. Also reset the congestion window to the
958 slow start threshold. */
959 if (pcb->flags & TF_INFR) {
960 pcb->flags &= ~TF_INFR;
961 pcb->cwnd = pcb->ssthresh;
962 }
963
964 /* Reset the number of retransmissions. */
965 pcb->nrtx = 0;
966
967 /* Reset the retransmission time-out. */
968 pcb->rto = (pcb->sa >> 3) + pcb->sv;
969
970 /* Update the send buffer space. Diff between the two can never exceed 64K? */
971 pcb->acked = (u16_t)(ackno - pcb->lastack);
972
973 pcb->snd_buf += pcb->acked;
974
975 /* Reset the fast retransmit variables. */
976 pcb->dupacks = 0;
977 pcb->lastack = ackno;
978
979 /* Update the congestion control variables (cwnd and
980 ssthresh). */
981 if (pcb->state >= ESTABLISHED) {
982 if (pcb->cwnd < pcb->ssthresh) {
983 if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {
984 pcb->cwnd += pcb->mss;
985 }
986 LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: slow start cwnd %"U16_F"\n", pcb->cwnd));
987 } else {
988 u16_t new_cwnd = (pcb->cwnd + pcb->mss * pcb->mss / pcb->cwnd);
989 if (new_cwnd > pcb->cwnd) {
990 pcb->cwnd = new_cwnd;
991 }
992 LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: congestion avoidance cwnd %"U16_F"\n", pcb->cwnd));
993 }
994 }
995 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: ACK for %"U32_F", unacked->seqno %"U32_F":%"U32_F"\n",
996 ackno,
997 pcb->unacked != NULL?
998 ntohl(pcb->unacked->tcphdr->seqno): 0,
999 pcb->unacked != NULL?
1000 ntohl(pcb->unacked->tcphdr->seqno) + TCP_TCPLEN(pcb->unacked): 0));
1001
1002 /* Remove segment from the unacknowledged list if the incoming
1003 ACK acknowlegdes them. */
1004 while (pcb->unacked != NULL &&
1005 TCP_SEQ_LEQ(ntohl(pcb->unacked->tcphdr->seqno) +
1006 TCP_TCPLEN(pcb->unacked), ackno)) {
1007 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unacked\n",
1008 ntohl(pcb->unacked->tcphdr->seqno),
1009 ntohl(pcb->unacked->tcphdr->seqno) +
1010 TCP_TCPLEN(pcb->unacked)));
1011
1012 next = pcb->unacked;
1013 pcb->unacked = pcb->unacked->next;
1014
1015 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen));
1016 LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p)));
1017 /* Prevent ACK for FIN to generate a sent event */
1018 if ((pcb->acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) {
1019 pcb->acked--;
1020 }
1021
1022 pcb->snd_queuelen -= pbuf_clen(next->p);
1023 tcp_seg_free(next);
1024
1025 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U16_F" (after freeing unacked)\n", (u16_t)pcb->snd_queuelen));
1026 if (pcb->snd_queuelen != 0) {
1027 LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL ||
1028 pcb->unsent != NULL);
1029 }
1030 }
1031
1032 /* If there's nothing left to acknowledge, stop the retransmit
1033 timer, otherwise reset it to start again */
1034 if(pcb->unacked == NULL)
1035 pcb->rtime = -1;
1036 else
1037 pcb->rtime = 0;
1038
1039 pcb->polltmr = 0;
1040 } else {
1041 /* Fix bug bug #21582: out of sequence ACK, didn't really ack anything */
1042 pcb->acked = 0;
1043 }
1044
1045 /* We go through the ->unsent list to see if any of the segments
1046 on the list are acknowledged by the ACK. This may seem
1047 strange since an "unsent" segment shouldn't be acked. The
1048 rationale is that lwIP puts all outstanding segments on the
1049 ->unsent list after a retransmission, so these segments may
1050 in fact have been sent once. */
1051 while (pcb->unsent != NULL &&
1052 TCP_SEQ_BETWEEN(ackno, ntohl(pcb->unsent->tcphdr->seqno) +
1053 TCP_TCPLEN(pcb->unsent), pcb->snd_nxt)) {
1054 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unsent\n",
1055 ntohl(pcb->unsent->tcphdr->seqno), ntohl(pcb->unsent->tcphdr->seqno) +
1056 TCP_TCPLEN(pcb->unsent)));
1057
1058 next = pcb->unsent;
1059 pcb->unsent = pcb->unsent->next;
1060 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen));
1061 LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p)));
1062 /* Prevent ACK for FIN to generate a sent event */
1063 if ((pcb->acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) {
1064 pcb->acked--;
1065 }
1066 pcb->snd_queuelen -= pbuf_clen(next->p);
1067 tcp_seg_free(next);
1068 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U16_F" (after freeing unsent)\n", (u16_t)pcb->snd_queuelen));
1069 if (pcb->snd_queuelen != 0) {
1070 LWIP_ASSERT("tcp_receive: valid queue length",
1071 pcb->unacked != NULL || pcb->unsent != NULL);
1072 }
1073 }
1074 /* End of ACK for new data processing. */
1075
1076 LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: pcb->rttest %"U32_F" rtseq %"U32_F" ackno %"U32_F"\n",
1077 pcb->rttest, pcb->rtseq, ackno));
1078
1079 /* RTT estimation calculations. This is done by checking if the
1080 incoming segment acknowledges the segment we use to take a
1081 round-trip time measurement. */
1082 if (pcb->rttest && TCP_SEQ_LT(pcb->rtseq, ackno)) {
1083 /* diff between this shouldn't exceed 32K since this are tcp timer ticks
1084 and a round-trip shouldn't be that long... */
1085 m = (s16_t)(tcp_ticks - pcb->rttest);
1086
1087 LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: experienced rtt %"U16_F" ticks (%"U16_F" msec).\n",
1088 m, m * TCP_SLOW_INTERVAL));
1089
1090 /* This is taken directly from VJs original code in his paper */
1091 m = m - (pcb->sa >> 3);
1092 pcb->sa += m;
1093 if (m < 0) {
1094 m = -m;
1095 }
1096 m = m - (pcb->sv >> 2);
1097 pcb->sv += m;
1098 pcb->rto = (pcb->sa >> 3) + pcb->sv;
1099
1100 LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: RTO %"U16_F" (%"U16_F" milliseconds)\n",
1101 pcb->rto, pcb->rto * TCP_SLOW_INTERVAL));
1102
1103 pcb->rttest = 0;
1104 }
1105 }
1106
1107 /* If the incoming segment contains data, we must process it
1108 further. */
1109 if (tcplen > 0) {
1110 /* This code basically does three things:
1111
1112 +) If the incoming segment contains data that is the next
1113 in-sequence data, this data is passed to the application. This
1114 might involve trimming the first edge of the data. The rcv_nxt
1115 variable and the advertised window are adjusted.
1116
1117 +) If the incoming segment has data that is above the next
1118 sequence number expected (->rcv_nxt), the segment is placed on
1119 the ->ooseq queue. This is done by finding the appropriate
1120 place in the ->ooseq queue (which is ordered by sequence
1121 number) and trim the segment in both ends if needed. An
1122 immediate ACK is sent to indicate that we received an
1123 out-of-sequence segment.
1124
1125 +) Finally, we check if the first segment on the ->ooseq queue
1126 now is in sequence (i.e., if rcv_nxt >= ooseq->seqno). If
1127 rcv_nxt > ooseq->seqno, we must trim the first edge of the
1128 segment on ->ooseq before we adjust rcv_nxt. The data in the
1129 segments that are now on sequence are chained onto the
1130 incoming segment so that we only need to call the application
1131 once.
1132 */
1133
1134 /* First, we check if we must trim the first edge. We have to do
1135 this if the sequence number of the incoming segment is less
1136 than rcv_nxt, and the sequence number plus the length of the
1137 segment is larger than rcv_nxt. */
1138 /* if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)){
1139 if (TCP_SEQ_LT(pcb->rcv_nxt, seqno + tcplen)) {*/
1140 if (TCP_SEQ_BETWEEN(pcb->rcv_nxt, seqno + 1, seqno + tcplen - 1)){
1141 /* Trimming the first edge is done by pushing the payload
1142 pointer in the pbuf downwards. This is somewhat tricky since
1143 we do not want to discard the full contents of the pbuf up to
1144 the new starting point of the data since we have to keep the
1145 TCP header which is present in the first pbuf in the chain.
1146
1147 What is done is really quite a nasty hack: the first pbuf in
1148 the pbuf chain is pointed to by inseg.p. Since we need to be
1149 able to deallocate the whole pbuf, we cannot change this
1150 inseg.p pointer to point to any of the later pbufs in the
1151 chain. Instead, we point the ->payload pointer in the first
1152 pbuf to data in one of the later pbufs. We also set the
1153 inseg.data pointer to point to the right place. This way, the
1154 ->p pointer will still point to the first pbuf, but the
1155 ->p->payload pointer will point to data in another pbuf.
1156
1157 After we are done with adjusting the pbuf pointers we must
1158 adjust the ->data pointer in the seg and the segment
1159 length.*/
1160
1161 off = pcb->rcv_nxt - seqno;
1162 p = inseg.p;
1163 LWIP_ASSERT("inseg.p != NULL", inseg.p);
1164 LWIP_ASSERT("insane offset!", (off < 0x7fff));
1165 if (inseg.p->len < off) {
1166 LWIP_ASSERT("pbuf too short!", (((s32_t)inseg.p->tot_len) >= off));
1167 new_tot_len = (u16_t)(inseg.p->tot_len - off);
1168 while (p->len < off) {
1169 off -= p->len;
1170 /* KJM following line changed (with addition of new_tot_len var)
1171 to fix bug #9076
1172 inseg.p->tot_len -= p->len; */
1173 p->tot_len = new_tot_len;
1174 p->len = 0;
1175 p = p->next;
1176 }
1177 if(pbuf_header(p, (s16_t)-off)) {
1178 /* Do we need to cope with this failing? Assert for now */
1179 LWIP_ASSERT("pbuf_header failed", 0);
1180 }
1181 } else {
1182 if(pbuf_header(inseg.p, (s16_t)-off)) {
1183 /* Do we need to cope with this failing? Assert for now */
1184 LWIP_ASSERT("pbuf_header failed", 0);
1185 }
1186 }
1187 inseg.len -= (u16_t)(pcb->rcv_nxt - seqno);
1188 inseg.tcphdr->seqno = seqno = pcb->rcv_nxt;
1189 }
1190 else {
1191 if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)){
1192 /* the whole segment is < rcv_nxt */
1193 /* must be a duplicate of a packet that has already been correctly handled */
1194
1195 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: duplicate seqno %"U32_F"\n", seqno));
1196 tcp_ack_now(pcb);
1197 }
1198 }
1199
1200 /* The sequence number must be within the window (above rcv_nxt
1201 and below rcv_nxt + rcv_wnd) in order to be further
1202 processed. */
1203 if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt,
1204 pcb->rcv_nxt + pcb->rcv_wnd - 1)){
1205 if (pcb->rcv_nxt == seqno) {
1206 /* The incoming segment is the next in sequence. We check if
1207 we have to trim the end of the segment and update rcv_nxt
1208 and pass the data to the application. */
1209 tcplen = TCP_TCPLEN(&inseg);
1210
1211 if (tcplen > pcb->rcv_wnd) {
1212 LWIP_DEBUGF(TCP_INPUT_DEBUG,
1213 ("tcp_receive: other end overran receive window"
1214 "seqno %"U32_F" len %"U16_F" right edge %"U32_F"\n",
1215 seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd));
1216 if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
1217 /* Must remove the FIN from the header as we're trimming
1218 * that byte of sequence-space from the packet */
1219 TCPH_FLAGS_SET(inseg.tcphdr, TCPH_FLAGS(inseg.tcphdr) &~ TCP_FIN);
1220 }
1221 /* Adjust length of segment to fit in the window. */
1222 inseg.len = pcb->rcv_wnd;
1223 if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) {
1224 inseg.len -= 1;
1225 }
1226 pbuf_realloc(inseg.p, inseg.len);
1227 tcplen = TCP_TCPLEN(&inseg);
1228 LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n",
1229 (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd));
1230 }
1231 #if TCP_QUEUE_OOSEQ
1232 /* Received in-sequence data, adjust ooseq data if:
1233 - FIN has been received or
1234 - inseq overlaps with ooseq */
1235 if (pcb->ooseq != NULL) {
1236 if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
1237 LWIP_DEBUGF(TCP_INPUT_DEBUG,
1238 ("tcp_receive: received in-order FIN, binning ooseq queue\n"));
1239 /* Received in-order FIN means anything that was received
1240 * out of order must now have been received in-order, so
1241 * bin the ooseq queue */
1242 while (pcb->ooseq != NULL) {
1243 struct tcp_seg *old_ooseq = pcb->ooseq;
1244 pcb->ooseq = pcb->ooseq->next;
1245 tcp_seg_free(old_ooseq);
1246 }
1247 }
1248 else {
1249 next = pcb->ooseq;
1250 /* Remove all segments on ooseq that are covered by inseg already.
1251 * FIN is copied from ooseq to inseg if present. */
1252 while (next &&
1253 TCP_SEQ_GEQ(seqno + tcplen,
1254 next->tcphdr->seqno + next->len)) {
1255 /* inseg cannot have FIN here (already processed above) */
1256 if (TCPH_FLAGS(next->tcphdr) & TCP_FIN &&
1257 (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) == 0) {
1258 TCPH_SET_FLAG(inseg.tcphdr, TCP_FIN);
1259 tcplen = TCP_TCPLEN(&inseg);
1260 }
1261 prev = next;
1262 next = next->next;
1263 tcp_seg_free(prev);
1264 }
1265 /* Now trim right side of inseg if it overlaps with the first
1266 * segment on ooseq */
1267 if (next &&
1268 TCP_SEQ_GT(seqno + tcplen,
1269 next->tcphdr->seqno)) {
1270 /* inseg cannot have FIN here (already processed above) */
1271 inseg.len = (u16_t)(next->tcphdr->seqno - seqno);
1272 if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) {
1273 inseg.len -= 1;
1274 }
1275 pbuf_realloc(inseg.p, inseg.len);
1276 tcplen = TCP_TCPLEN(&inseg);
1277 LWIP_ASSERT("tcp_receive: segment not trimmed correctly to ooseq queue\n",
1278 (seqno + tcplen) == next->tcphdr->seqno);
1279 }
1280 pcb->ooseq = next;
1281 }
1282 }
1283 #endif /* TCP_QUEUE_OOSEQ */
1284
1285 pcb->rcv_nxt = seqno + tcplen;
1286
1287 /* Update the receiver's (our) window. */
1288 LWIP_ASSERT("tcp_receive: tcplen > rcv_wnd\n", pcb->rcv_wnd >= tcplen);
1289 pcb->rcv_wnd -= tcplen;
1290
1291 tcp_update_rcv_ann_wnd(pcb);
1292
1293 /* If there is data in the segment, we make preparations to
1294 pass this up to the application. The ->recv_data variable
1295 is used for holding the pbuf that goes to the
1296 application. The code for reassembling out-of-sequence data
1297 chains its data on this pbuf as well.
1298
1299 If the segment was a FIN, we set the TF_GOT_FIN flag that will
1300 be used to indicate to the application that the remote side has
1301 closed its end of the connection. */
1302 if (inseg.p->tot_len > 0) {
1303 recv_data = inseg.p;
1304 /* Since this pbuf now is the responsibility of the
1305 application, we delete our reference to it so that we won't
1306 (mistakingly) deallocate it. */
1307 inseg.p = NULL;
1308 }
1309 if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
1310 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN.\n"));
1311 recv_flags |= TF_GOT_FIN;
1312 }
1313
1314 #if TCP_QUEUE_OOSEQ
1315 /* We now check if we have segments on the ->ooseq queue that
1316 are now in sequence. */
1317 while (pcb->ooseq != NULL &&
1318 pcb->ooseq->tcphdr->seqno == pcb->rcv_nxt) {
1319
1320 cseg = pcb->ooseq;
1321 seqno = pcb->ooseq->tcphdr->seqno;
1322
1323 pcb->rcv_nxt += TCP_TCPLEN(cseg);
1324 LWIP_ASSERT("tcp_receive: ooseq tcplen > rcv_wnd\n",
1325 pcb->rcv_wnd >= TCP_TCPLEN(cseg));
1326 pcb->rcv_wnd -= TCP_TCPLEN(cseg);
1327
1328 tcp_update_rcv_ann_wnd(pcb);
1329
1330 if (cseg->p->tot_len > 0) {
1331 /* Chain this pbuf onto the pbuf that we will pass to
1332 the application. */
1333 if (recv_data) {
1334 pbuf_cat(recv_data, cseg->p);
1335 } else {
1336 recv_data = cseg->p;
1337 }
1338 cseg->p = NULL;
1339 }
1340 if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) {
1341 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN.\n"));
1342 recv_flags |= TF_GOT_FIN;
1343 if (pcb->state == ESTABLISHED) { /* force passive close or we can move to active close */
1344 pcb->state = CLOSE_WAIT;
1345 }
1346 }
1347
1348 pcb->ooseq = cseg->next;
1349 tcp_seg_free(cseg);
1350 }
1351 #endif /* TCP_QUEUE_OOSEQ */
1352
1353
1354 /* Acknowledge the segment(s). */
1355 tcp_ack(pcb);
1356
1357 } else {
1358 /* We get here if the incoming segment is out-of-sequence. */
1359 tcp_send_empty_ack(pcb);
1360 #if TCP_QUEUE_OOSEQ
1361 /* We queue the segment on the ->ooseq queue. */
1362 if (pcb->ooseq == NULL) {
1363 pcb->ooseq = tcp_seg_copy(&inseg);
1364 } else {
1365 /* If the queue is not empty, we walk through the queue and
1366 try to find a place where the sequence number of the
1367 incoming segment is between the sequence numbers of the
1368 previous and the next segment on the ->ooseq queue. That is
1369 the place where we put the incoming segment. If needed, we
1370 trim the second edges of the previous and the incoming
1371 segment so that it will fit into the sequence.
1372
1373 If the incoming segment has the same sequence number as a
1374 segment on the ->ooseq queue, we discard the segment that
1375 contains less data. */
1376
1377 prev = NULL;
1378 for(next = pcb->ooseq; next != NULL; next = next->next) {
1379 if (seqno == next->tcphdr->seqno) {
1380 /* The sequence number of the incoming segment is the
1381 same as the sequence number of the segment on
1382 ->ooseq. We check the lengths to see which one to
1383 discard. */
1384 if (inseg.len > next->len) {
1385 /* The incoming segment is larger than the old
1386 segment. We replace some segments with the new
1387 one. */
1388 cseg = tcp_seg_copy(&inseg);
1389 if (cseg != NULL) {
1390 if (prev != NULL) {
1391 prev->next = cseg;
1392 } else {
1393 pcb->ooseq = cseg;
1394 }
1395 tcp_oos_insert_segment(cseg, next);
1396 }
1397 break;
1398 } else {
1399 /* Either the lenghts are the same or the incoming
1400 segment was smaller than the old one; in either
1401 case, we ditch the incoming segment. */
1402 break;
1403 }
1404 } else {
1405 if (prev == NULL) {
1406 if (TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {
1407 /* The sequence number of the incoming segment is lower
1408 than the sequence number of the first segment on the
1409 queue. We put the incoming segment first on the
1410 queue. */
1411 cseg = tcp_seg_copy(&inseg);
1412 if (cseg != NULL) {
1413 pcb->ooseq = cseg;
1414 tcp_oos_insert_segment(cseg, next);
1415 }
1416 break;
1417 }
1418 } else {
1419 /*if (TCP_SEQ_LT(prev->tcphdr->seqno, seqno) &&
1420 TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {*/
1421 if (TCP_SEQ_BETWEEN(seqno, prev->tcphdr->seqno+1, next->tcphdr->seqno-1)) {
1422 /* The sequence number of the incoming segment is in
1423 between the sequence numbers of the previous and
1424 the next segment on ->ooseq. We trim trim the previous
1425 segment, delete next segments that included in received segment
1426 and trim received, if needed. */
1427 cseg = tcp_seg_copy(&inseg);
1428 if (cseg != NULL) {
1429 if (TCP_SEQ_GT(prev->tcphdr->seqno + prev->len, seqno)) {
1430 /* We need to trim the prev segment. */
1431 prev->len = (u16_t)(seqno - prev->tcphdr->seqno);
1432 pbuf_realloc(prev->p, prev->len);
1433 }
1434 prev->next = cseg;
1435 tcp_oos_insert_segment(cseg, next);
1436 }
1437 break;
1438 }
1439 }
1440 /* If the "next" segment is the last segment on the
1441 ooseq queue, we add the incoming segment to the end
1442 of the list. */
1443 if (next->next == NULL &&
1444 TCP_SEQ_GT(seqno, next->tcphdr->seqno)) {
1445 if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) {
1446 /* segment "next" already contains all data */
1447 break;
1448 }
1449 next->next = tcp_seg_copy(&inseg);
1450 if (next->next != NULL) {
1451 if (TCP_SEQ_GT(next->tcphdr->seqno + next->len, seqno)) {
1452 /* We need to trim the last segment. */
1453 next->len = (u16_t)(seqno - next->tcphdr->seqno);
1454 pbuf_realloc(next->p, next->len);
1455 }
1456 /* check if the remote side overruns our receive window */
1457 if ((u32_t)tcplen + seqno > pcb->rcv_nxt + (u32_t)pcb->rcv_wnd) {
1458 LWIP_DEBUGF(TCP_INPUT_DEBUG,
1459 ("tcp_receive: other end overran receive window"
1460 "seqno %"U32_F" len %"U16_F" right edge %"U32_F"\n",
1461 seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd));
1462 if (TCPH_FLAGS(next->next->tcphdr) & TCP_FIN) {
1463 /* Must remove the FIN from the header as we're trimming
1464 * that byte of sequence-space from the packet */
1465 TCPH_FLAGS_SET(next->next->tcphdr, TCPH_FLAGS(next->next->tcphdr) &~ TCP_FIN);
1466 }
1467 /* Adjust length of segment to fit in the window. */
1468 next->next->len = pcb->rcv_nxt + pcb->rcv_wnd - seqno;
1469 pbuf_realloc(next->next->p, next->next->len);
1470 tcplen = TCP_TCPLEN(next->next);
1471 LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n",
1472 (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd));
1473 }
1474 }
1475 break;
1476 }
1477 }
1478 prev = next;
1479 }
1480 }
1481 #endif /* TCP_QUEUE_OOSEQ */
1482
1483 }
1484 } else {
1485 /* The incoming segment is not withing the window. */
1486 tcp_send_empty_ack(pcb);
1487 }
1488 } else {
1489 /* Segments with length 0 is taken care of here. Segments that
1490 fall out of the window are ACKed. */
1491 /*if (TCP_SEQ_GT(pcb->rcv_nxt, seqno) ||
1492 TCP_SEQ_GEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {*/
1493 if(!TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd-1)){
1494 tcp_ack_now(pcb);
1495 }
1496 }
1497 }
1498
1499 /**
1500 * Parses the options contained in the incoming segment.
1501 *
1502 * Called from tcp_listen_input() and tcp_process().
1503 * Currently, only the MSS option is supported!
1504 *
1505 * @param pcb the tcp_pcb for which a segment arrived
1506 */
1507 static void
1508 tcp_parseopt(struct tcp_pcb *pcb)
1509 {
1510 u16_t c, max_c;
1511 u16_t mss;
1512 u8_t *opts, opt;
1513 #if LWIP_TCP_TIMESTAMPS
1514 u32_t tsval;
1515 #endif
1516
1517 opts = (u8_t *)tcphdr + TCP_HLEN;
1518
1519 /* Parse the TCP MSS option, if present. */
1520 if(TCPH_HDRLEN(tcphdr) > 0x5) {
1521 max_c = (TCPH_HDRLEN(tcphdr) - 5) << 2;
1522 for (c = 0; c < max_c; ) {
1523 opt = opts[c];
1524 switch (opt) {
1525 case 0x00:
1526 /* End of options. */
1527 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: EOL\n"));
1528 return;
1529 case 0x01:
1530 /* NOP option. */
1531 ++c;
1532 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: NOP\n"));
1533 break;
1534 case 0x02:
1535 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: MSS\n"));
1536 if (opts[c + 1] != 0x04 || c + 0x04 > max_c) {
1537 /* Bad length */
1538 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
1539 return;
1540 }
1541 /* An MSS option with the right option length. */
1542 mss = (opts[c + 2] << 8) | opts[c + 3];
1543 /* Limit the mss to the configured TCP_MSS and prevent division by zero */
1544 pcb->mss = ((mss > TCP_MSS) || (mss == 0)) ? TCP_MSS : mss;
1545 /* Advance to next option */
1546 c += 0x04;
1547 break;
1548 #if LWIP_TCP_TIMESTAMPS
1549 case 0x08:
1550 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: TS\n"));
1551 if (opts[c + 1] != 0x0A || c + 0x0A > max_c) {
1552 /* Bad length */
1553 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
1554 return;
1555 }
1556 /* TCP timestamp option with valid length */
1557 tsval = (opts[c+2]) | (opts[c+3] << 8) |
1558 (opts[c+4] << 16) | (opts[c+5] << 24);
1559 if (flags & TCP_SYN) {
1560 pcb->ts_recent = ntohl(tsval);
1561 pcb->flags |= TF_TIMESTAMP;
1562 } else if (TCP_SEQ_BETWEEN(pcb->ts_lastacksent, seqno, seqno+tcplen)) {
1563 pcb->ts_recent = ntohl(tsval);
1564 }
1565 /* Advance to next option */
1566 c += 0x0A;
1567 break;
1568 #endif
1569 default:
1570 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: other\n"));
1571 if (opts[c + 1] == 0) {
1572 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
1573 /* If the length field is zero, the options are malformed
1574 and we don't process them further. */
1575 return;
1576 }
1577 /* All other options have a length field, so that we easily
1578 can skip past them. */
1579 c += opts[c + 1];
1580 }
1581 }
1582 }
1583 }
1584
1585 #endif /* LWIP_TCP */