xref: /nrf52832-nimble/rt-thread/components/net/lwip-2.0.2/src/core/tcp_in.c (revision 104654410c56c573564690304ae786df310c91fc)
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 <[email protected]>
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/priv/tcp_priv.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/ip6.h"
57 #include "lwip/ip6_addr.h"
58 #if LWIP_ND6_TCP_REACHABILITY_HINTS
59 #include "lwip/nd6.h"
60 #endif /* LWIP_ND6_TCP_REACHABILITY_HINTS */
61 
62 /** Initial CWND calculation as defined RFC 2581 */
63 #define LWIP_TCP_CALC_INITIAL_CWND(mss) LWIP_MIN((4U * (mss)), LWIP_MAX((2U * (mss)), 4380U));
64 
65 /* These variables are global to all functions involved in the input
66    processing of TCP segments. They are set by the tcp_input()
67    function. */
68 static struct tcp_seg inseg;
69 static struct tcp_hdr *tcphdr;
70 static u16_t tcphdr_optlen;
71 static u16_t tcphdr_opt1len;
72 static u8_t* tcphdr_opt2;
73 static u16_t tcp_optidx;
74 static u32_t seqno, ackno;
75 static tcpwnd_size_t recv_acked;
76 static u16_t tcplen;
77 static u8_t flags;
78 
79 static u8_t recv_flags;
80 static struct pbuf *recv_data;
81 
82 struct tcp_pcb *tcp_input_pcb;
83 
84 /* Forward declarations. */
85 static err_t tcp_process(struct tcp_pcb *pcb);
86 static void tcp_receive(struct tcp_pcb *pcb);
87 static void tcp_parseopt(struct tcp_pcb *pcb);
88 
89 static void tcp_listen_input(struct tcp_pcb_listen *pcb);
90 static void tcp_timewait_input(struct tcp_pcb *pcb);
91 
92 /**
93  * The initial input processing of TCP. It verifies the TCP header, demultiplexes
94  * the segment between the PCBs and passes it on to tcp_process(), which implements
95  * the TCP finite state machine. This function is called by the IP layer (in
96  * ip_input()).
97  *
98  * @param p received TCP segment to process (p->payload pointing to the TCP header)
99  * @param inp network interface on which this segment was received
100  */
101 void
tcp_input(struct pbuf * p,struct netif * inp)102 tcp_input(struct pbuf *p, struct netif *inp)
103 {
104   struct tcp_pcb *pcb, *prev;
105   struct tcp_pcb_listen *lpcb;
106 #if SO_REUSE
107   struct tcp_pcb *lpcb_prev = NULL;
108   struct tcp_pcb_listen *lpcb_any = NULL;
109 #endif /* SO_REUSE */
110   u8_t hdrlen_bytes;
111   err_t err;
112 
113   LWIP_UNUSED_ARG(inp);
114 
115   PERF_START;
116 
117   TCP_STATS_INC(tcp.recv);
118   MIB2_STATS_INC(mib2.tcpinsegs);
119 
120   tcphdr = (struct tcp_hdr *)p->payload;
121 
122 #if TCP_INPUT_DEBUG
123   tcp_debug_print(tcphdr);
124 #endif
125 
126   /* Check that TCP header fits in payload */
127   if (p->len < TCP_HLEN) {
128     /* drop short packets */
129     LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet (%"U16_F" bytes) discarded\n", p->tot_len));
130     TCP_STATS_INC(tcp.lenerr);
131     goto dropped;
132   }
133 
134   /* Don't even process incoming broadcasts/multicasts. */
135   if (ip_addr_isbroadcast(ip_current_dest_addr(), ip_current_netif()) ||
136       ip_addr_ismulticast(ip_current_dest_addr())) {
137     TCP_STATS_INC(tcp.proterr);
138     goto dropped;
139   }
140 
141 #if CHECKSUM_CHECK_TCP
142   IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_TCP) {
143     /* Verify TCP checksum. */
144     u16_t chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len,
145                                ip_current_src_addr(), ip_current_dest_addr());
146     if (chksum != 0) {
147         LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packet discarded due to failing checksum 0x%04"X16_F"\n",
148           chksum));
149       tcp_debug_print(tcphdr);
150       TCP_STATS_INC(tcp.chkerr);
151       goto dropped;
152     }
153   }
154 #endif /* CHECKSUM_CHECK_TCP */
155 
156   /* sanity-check header length */
157   hdrlen_bytes = TCPH_HDRLEN(tcphdr) * 4;
158   if ((hdrlen_bytes < TCP_HLEN) || (hdrlen_bytes > p->tot_len)) {
159     LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: invalid header length (%"U16_F")\n", (u16_t)hdrlen_bytes));
160     TCP_STATS_INC(tcp.lenerr);
161     goto dropped;
162   }
163 
164   /* Move the payload pointer in the pbuf so that it points to the
165      TCP data instead of the TCP header. */
166   tcphdr_optlen = hdrlen_bytes - TCP_HLEN;
167   tcphdr_opt2 = NULL;
168   if (p->len >= hdrlen_bytes) {
169     /* all options are in the first pbuf */
170     tcphdr_opt1len = tcphdr_optlen;
171     pbuf_header(p, -(s16_t)hdrlen_bytes); /* cannot fail */
172   } else {
173     u16_t opt2len;
174     /* TCP header fits into first pbuf, options don't - data is in the next pbuf */
175     /* there must be a next pbuf, due to hdrlen_bytes sanity check above */
176     LWIP_ASSERT("p->next != NULL", p->next != NULL);
177 
178     /* advance over the TCP header (cannot fail) */
179     pbuf_header(p, -TCP_HLEN);
180 
181     /* determine how long the first and second parts of the options are */
182     tcphdr_opt1len = p->len;
183     opt2len = tcphdr_optlen - tcphdr_opt1len;
184 
185     /* options continue in the next pbuf: set p to zero length and hide the
186         options in the next pbuf (adjusting p->tot_len) */
187     pbuf_header(p, -(s16_t)tcphdr_opt1len);
188 
189     /* check that the options fit in the second pbuf */
190     if (opt2len > p->next->len) {
191       /* drop short packets */
192       LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: options overflow second pbuf (%"U16_F" bytes)\n", p->next->len));
193       TCP_STATS_INC(tcp.lenerr);
194       goto dropped;
195     }
196 
197     /* remember the pointer to the second part of the options */
198     tcphdr_opt2 = (u8_t*)p->next->payload;
199 
200     /* advance p->next to point after the options, and manually
201         adjust p->tot_len to keep it consistent with the changed p->next */
202     pbuf_header(p->next, -(s16_t)opt2len);
203     p->tot_len -= opt2len;
204 
205     LWIP_ASSERT("p->len == 0", p->len == 0);
206     LWIP_ASSERT("p->tot_len == p->next->tot_len", p->tot_len == p->next->tot_len);
207   }
208 
209   /* Convert fields in TCP header to host byte order. */
210   tcphdr->src = lwip_ntohs(tcphdr->src);
211   tcphdr->dest = lwip_ntohs(tcphdr->dest);
212   seqno = tcphdr->seqno = lwip_ntohl(tcphdr->seqno);
213   ackno = tcphdr->ackno = lwip_ntohl(tcphdr->ackno);
214   tcphdr->wnd = lwip_ntohs(tcphdr->wnd);
215 
216   flags = TCPH_FLAGS(tcphdr);
217   tcplen = p->tot_len + ((flags & (TCP_FIN | TCP_SYN)) ? 1 : 0);
218 
219   /* Demultiplex an incoming segment. First, we check if it is destined
220      for an active connection. */
221   prev = NULL;
222 
223   for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
224     LWIP_ASSERT("tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED);
225     LWIP_ASSERT("tcp_input: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);
226     LWIP_ASSERT("tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN);
227     if (pcb->remote_port == tcphdr->src &&
228         pcb->local_port == tcphdr->dest &&
229         ip_addr_cmp(&pcb->remote_ip, ip_current_src_addr()) &&
230         ip_addr_cmp(&pcb->local_ip, ip_current_dest_addr())) {
231       /* Move this PCB to the front of the list so that subsequent
232          lookups will be faster (we exploit locality in TCP segment
233          arrivals). */
234       LWIP_ASSERT("tcp_input: pcb->next != pcb (before cache)", pcb->next != pcb);
235       if (prev != NULL) {
236         prev->next = pcb->next;
237         pcb->next = tcp_active_pcbs;
238         tcp_active_pcbs = pcb;
239       } else {
240         TCP_STATS_INC(tcp.cachehit);
241       }
242       LWIP_ASSERT("tcp_input: pcb->next != pcb (after cache)", pcb->next != pcb);
243       break;
244     }
245     prev = pcb;
246   }
247 
248   if (pcb == NULL) {
249     /* If it did not go to an active connection, we check the connections
250        in the TIME-WAIT state. */
251     for (pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
252       LWIP_ASSERT("tcp_input: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
253       if (pcb->remote_port == tcphdr->src &&
254           pcb->local_port == tcphdr->dest &&
255           ip_addr_cmp(&pcb->remote_ip, ip_current_src_addr()) &&
256           ip_addr_cmp(&pcb->local_ip, ip_current_dest_addr())) {
257         /* We don't really care enough to move this PCB to the front
258            of the list since we are not very likely to receive that
259            many segments for connections in TIME-WAIT. */
260         LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for TIME_WAITing connection.\n"));
261         tcp_timewait_input(pcb);
262         pbuf_free(p);
263         return;
264       }
265     }
266 
267     /* Finally, if we still did not get a match, we check all PCBs that
268        are LISTENing for incoming connections. */
269     prev = NULL;
270     for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
271       if (lpcb->local_port == tcphdr->dest) {
272         if (IP_IS_ANY_TYPE_VAL(lpcb->local_ip)) {
273           /* found an ANY TYPE (IPv4/IPv6) match */
274 #if SO_REUSE
275           lpcb_any = lpcb;
276           lpcb_prev = prev;
277 #else /* SO_REUSE */
278           break;
279 #endif /* SO_REUSE */
280         } else if (IP_ADDR_PCB_VERSION_MATCH_EXACT(lpcb, ip_current_dest_addr())) {
281           if (ip_addr_cmp(&lpcb->local_ip, ip_current_dest_addr())) {
282             /* found an exact match */
283             break;
284           } else if (ip_addr_isany(&lpcb->local_ip)) {
285             /* found an ANY-match */
286 #if SO_REUSE
287             lpcb_any = lpcb;
288             lpcb_prev = prev;
289 #else /* SO_REUSE */
290             break;
291  #endif /* SO_REUSE */
292           }
293         }
294       }
295       prev = (struct tcp_pcb *)lpcb;
296     }
297 #if SO_REUSE
298     /* first try specific local IP */
299     if (lpcb == NULL) {
300       /* only pass to ANY if no specific local IP has been found */
301       lpcb = lpcb_any;
302       prev = lpcb_prev;
303     }
304 #endif /* SO_REUSE */
305     if (lpcb != NULL) {
306       /* Move this PCB to the front of the list so that subsequent
307          lookups will be faster (we exploit locality in TCP segment
308          arrivals). */
309       if (prev != NULL) {
310         ((struct tcp_pcb_listen *)prev)->next = lpcb->next;
311               /* our successor is the remainder of the listening list */
312         lpcb->next = tcp_listen_pcbs.listen_pcbs;
313               /* put this listening pcb at the head of the listening list */
314         tcp_listen_pcbs.listen_pcbs = lpcb;
315       } else {
316         TCP_STATS_INC(tcp.cachehit);
317       }
318 
319       LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for LISTENing connection.\n"));
320       tcp_listen_input(lpcb);
321       pbuf_free(p);
322       return;
323     }
324   }
325 
326 #if TCP_INPUT_DEBUG
327   LWIP_DEBUGF(TCP_INPUT_DEBUG, ("+-+-+-+-+-+-+-+-+-+-+-+-+-+- tcp_input: flags "));
328   tcp_debug_print_flags(TCPH_FLAGS(tcphdr));
329   LWIP_DEBUGF(TCP_INPUT_DEBUG, ("-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n"));
330 #endif /* TCP_INPUT_DEBUG */
331 
332 
333   if (pcb != NULL) {
334     /* The incoming segment belongs to a connection. */
335 #if TCP_INPUT_DEBUG
336     tcp_debug_print_state(pcb->state);
337 #endif /* TCP_INPUT_DEBUG */
338 
339     /* Set up a tcp_seg structure. */
340     inseg.next = NULL;
341     inseg.len = p->tot_len;
342     inseg.p = p;
343     inseg.tcphdr = tcphdr;
344 
345     recv_data = NULL;
346     recv_flags = 0;
347     recv_acked = 0;
348 
349     if (flags & TCP_PSH) {
350       p->flags |= PBUF_FLAG_PUSH;
351     }
352 
353     /* If there is data which was previously "refused" by upper layer */
354     if (pcb->refused_data != NULL) {
355       if ((tcp_process_refused_data(pcb) == ERR_ABRT) ||
356         ((pcb->refused_data != NULL) && (tcplen > 0))) {
357         /* pcb has been aborted or refused data is still refused and the new
358            segment contains data */
359         if (pcb->rcv_ann_wnd == 0) {
360           /* this is a zero-window probe, we respond to it with current RCV.NXT
361           and drop the data segment */
362           tcp_send_empty_ack(pcb);
363         }
364         TCP_STATS_INC(tcp.drop);
365         MIB2_STATS_INC(mib2.tcpinerrs);
366         goto aborted;
367       }
368     }
369     tcp_input_pcb = pcb;
370     err = tcp_process(pcb);
371     /* A return value of ERR_ABRT means that tcp_abort() was called
372        and that the pcb has been freed. If so, we don't do anything. */
373     if (err != ERR_ABRT) {
374       if (recv_flags & TF_RESET) {
375         /* TF_RESET means that the connection was reset by the other
376            end. We then call the error callback to inform the
377            application that the connection is dead before we
378            deallocate the PCB. */
379         TCP_EVENT_ERR(pcb->state, pcb->errf, pcb->callback_arg, ERR_RST);
380         tcp_pcb_remove(&tcp_active_pcbs, pcb);
381         memp_free(MEMP_TCP_PCB, pcb);
382       } else {
383         err = ERR_OK;
384         /* If the application has registered a "sent" function to be
385            called when new send buffer space is available, we call it
386            now. */
387         if (recv_acked > 0) {
388           u16_t acked16;
389 #if LWIP_WND_SCALE
390           /* recv_acked is u32_t but the sent callback only takes a u16_t,
391              so we might have to call it multiple times. */
392           u32_t acked = recv_acked;
393           while (acked > 0) {
394             acked16 = (u16_t)LWIP_MIN(acked, 0xffffu);
395             acked -= acked16;
396 #else
397           {
398             acked16 = recv_acked;
399 #endif
400             TCP_EVENT_SENT(pcb, (u16_t)acked16, err);
401             if (err == ERR_ABRT) {
402               goto aborted;
403             }
404           }
405           recv_acked = 0;
406         }
407         if (recv_flags & TF_CLOSED) {
408           /* The connection has been closed and we will deallocate the
409              PCB. */
410           if (!(pcb->flags & TF_RXCLOSED)) {
411             /* Connection closed although the application has only shut down the
412                tx side: call the PCB's err callback and indicate the closure to
413                ensure the application doesn't continue using the PCB. */
414             TCP_EVENT_ERR(pcb->state, pcb->errf, pcb->callback_arg, ERR_CLSD);
415           }
416           tcp_pcb_remove(&tcp_active_pcbs, pcb);
417           memp_free(MEMP_TCP_PCB, pcb);
418           goto aborted;
419         }
420 #if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
421         while (recv_data != NULL) {
422           struct pbuf *rest = NULL;
423           pbuf_split_64k(recv_data, &rest);
424 #else /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
425         if (recv_data != NULL) {
426 #endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
427 
428           LWIP_ASSERT("pcb->refused_data == NULL", pcb->refused_data == NULL);
429           if (pcb->flags & TF_RXCLOSED) {
430             /* received data although already closed -> abort (send RST) to
431                notify the remote host that not all data has been processed */
432             pbuf_free(recv_data);
433 #if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
434             if (rest != NULL) {
435               pbuf_free(rest);
436             }
437 #endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
438             tcp_abort(pcb);
439             goto aborted;
440           }
441 
442           /* Notify application that data has been received. */
443           TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err);
444           if (err == ERR_ABRT) {
445 #if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
446             if (rest != NULL) {
447               pbuf_free(rest);
448             }
449 #endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
450             goto aborted;
451           }
452 
453           /* If the upper layer can't receive this data, store it */
454           if (err != ERR_OK) {
455 #if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
456             if (rest != NULL) {
457               pbuf_cat(recv_data, rest);
458             }
459 #endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
460             pcb->refused_data = recv_data;
461             LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: keep incoming packet, because pcb is \"full\"\n"));
462 #if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
463             break;
464           } else {
465             /* Upper layer received the data, go on with the rest if > 64K */
466             recv_data = rest;
467 #endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
468           }
469         }
470 
471         /* If a FIN segment was received, we call the callback
472            function with a NULL buffer to indicate EOF. */
473         if (recv_flags & TF_GOT_FIN) {
474           if (pcb->refused_data != NULL) {
475             /* Delay this if we have refused data. */
476             pcb->refused_data->flags |= PBUF_FLAG_TCP_FIN;
477           } else {
478             /* correct rcv_wnd as the application won't call tcp_recved()
479                for the FIN's seqno */
480             if (pcb->rcv_wnd != TCP_WND_MAX(pcb)) {
481               pcb->rcv_wnd++;
482             }
483             TCP_EVENT_CLOSED(pcb, err);
484             if (err == ERR_ABRT) {
485               goto aborted;
486             }
487           }
488         }
489 
490         tcp_input_pcb = NULL;
491         /* Try to send something out. */
492         tcp_output(pcb);
493 #if TCP_INPUT_DEBUG
494 #if TCP_DEBUG
495         tcp_debug_print_state(pcb->state);
496 #endif /* TCP_DEBUG */
497 #endif /* TCP_INPUT_DEBUG */
498       }
499     }
500     /* Jump target if pcb has been aborted in a callback (by calling tcp_abort()).
501        Below this line, 'pcb' may not be dereferenced! */
502 aborted:
503     tcp_input_pcb = NULL;
504     recv_data = NULL;
505 
506     /* give up our reference to inseg.p */
507     if (inseg.p != NULL)
508     {
509       pbuf_free(inseg.p);
510       inseg.p = NULL;
511     }
512   } else {
513 
514     /* If no matching PCB was found, send a TCP RST (reset) to the
515        sender. */
516     LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_input: no PCB match found, resetting.\n"));
517     if (!(TCPH_FLAGS(tcphdr) & TCP_RST)) {
518       TCP_STATS_INC(tcp.proterr);
519       TCP_STATS_INC(tcp.drop);
520       tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(),
521         ip_current_src_addr(), tcphdr->dest, tcphdr->src);
522     }
523     pbuf_free(p);
524   }
525 
526   LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane());
527   PERF_STOP("tcp_input");
528   return;
529 dropped:
530   TCP_STATS_INC(tcp.drop);
531   MIB2_STATS_INC(mib2.tcpinerrs);
532   pbuf_free(p);
533 }
534 
535 /**
536  * Called by tcp_input() when a segment arrives for a listening
537  * connection (from tcp_input()).
538  *
539  * @param pcb the tcp_pcb_listen for which a segment arrived
540  *
541  * @note the segment which arrived is saved in global variables, therefore only the pcb
542  *       involved is passed as a parameter to this function
543  */
544 static void
545 tcp_listen_input(struct tcp_pcb_listen *pcb)
546 {
547   struct tcp_pcb *npcb;
548   u32_t iss;
549   err_t rc;
550 
551   if (flags & TCP_RST) {
552     /* An incoming RST should be ignored. Return. */
553     return;
554   }
555 
556   /* In the LISTEN state, we check for incoming SYN segments,
557      creates a new PCB, and responds with a SYN|ACK. */
558   if (flags & TCP_ACK) {
559     /* For incoming segments with the ACK flag set, respond with a
560        RST. */
561     LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_listen_input: ACK in LISTEN, sending reset\n"));
562     tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(),
563       ip_current_src_addr(), tcphdr->dest, tcphdr->src);
564   } else if (flags & TCP_SYN) {
565     LWIP_DEBUGF(TCP_DEBUG, ("TCP connection request %"U16_F" -> %"U16_F".\n", tcphdr->src, tcphdr->dest));
566 #if TCP_LISTEN_BACKLOG
567     if (pcb->accepts_pending >= pcb->backlog) {
568       LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: listen backlog exceeded for port %"U16_F"\n", tcphdr->dest));
569       return;
570     }
571 #endif /* TCP_LISTEN_BACKLOG */
572     npcb = tcp_alloc(pcb->prio);
573     /* If a new PCB could not be created (probably due to lack of memory),
574        we don't do anything, but rely on the sender will retransmit the
575        SYN at a time when we have more memory available. */
576     if (npcb == NULL) {
577       err_t err;
578       LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: could not allocate PCB\n"));
579       TCP_STATS_INC(tcp.memerr);
580       TCP_EVENT_ACCEPT(pcb, NULL, pcb->callback_arg, ERR_MEM, err);
581       LWIP_UNUSED_ARG(err); /* err not useful here */
582       return;
583     }
584 #if TCP_LISTEN_BACKLOG
585     pcb->accepts_pending++;
586     npcb->flags |= TF_BACKLOGPEND;
587 #endif /* TCP_LISTEN_BACKLOG */
588     /* Set up the new PCB. */
589     ip_addr_copy(npcb->local_ip, *ip_current_dest_addr());
590     ip_addr_copy(npcb->remote_ip, *ip_current_src_addr());
591     npcb->local_port = pcb->local_port;
592     npcb->remote_port = tcphdr->src;
593     npcb->state = SYN_RCVD;
594     npcb->rcv_nxt = seqno + 1;
595     npcb->rcv_ann_right_edge = npcb->rcv_nxt;
596     iss = tcp_next_iss(npcb);
597     npcb->snd_wl2 = iss;
598     npcb->snd_nxt = iss;
599     npcb->lastack = iss;
600     npcb->snd_lbb = iss;
601     npcb->snd_wl1 = seqno - 1;/* initialise to seqno-1 to force window update */
602     npcb->callback_arg = pcb->callback_arg;
603 #if LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG
604     npcb->listener = pcb;
605 #endif /* LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG */
606     /* inherit socket options */
607     npcb->so_options = pcb->so_options & SOF_INHERITED;
608     /* Register the new PCB so that we can begin receiving segments
609        for it. */
610     TCP_REG_ACTIVE(npcb);
611 
612     /* Parse any options in the SYN. */
613     tcp_parseopt(npcb);
614     npcb->snd_wnd = tcphdr->wnd;
615     npcb->snd_wnd_max = npcb->snd_wnd;
616 
617 #if TCP_CALCULATE_EFF_SEND_MSS
618     npcb->mss = tcp_eff_send_mss(npcb->mss, &npcb->local_ip, &npcb->remote_ip);
619 #endif /* TCP_CALCULATE_EFF_SEND_MSS */
620 
621     MIB2_STATS_INC(mib2.tcppassiveopens);
622 
623     /* Send a SYN|ACK together with the MSS option. */
624     rc = tcp_enqueue_flags(npcb, TCP_SYN | TCP_ACK);
625     if (rc != ERR_OK) {
626       tcp_abandon(npcb, 0);
627       return;
628     }
629     tcp_output(npcb);
630   }
631   return;
632 }
633 
634 /**
635  * Called by tcp_input() when a segment arrives for a connection in
636  * TIME_WAIT.
637  *
638  * @param pcb the tcp_pcb for which a segment arrived
639  *
640  * @note the segment which arrived is saved in global variables, therefore only the pcb
641  *       involved is passed as a parameter to this function
642  */
643 static void
644 tcp_timewait_input(struct tcp_pcb *pcb)
645 {
646   /* RFC 1337: in TIME_WAIT, ignore RST and ACK FINs + any 'acceptable' segments */
647   /* RFC 793 3.9 Event Processing - Segment Arrives:
648    * - first check sequence number - we skip that one in TIME_WAIT (always
649    *   acceptable since we only send ACKs)
650    * - second check the RST bit (... return) */
651   if (flags & TCP_RST) {
652     return;
653   }
654   /* - fourth, check the SYN bit, */
655   if (flags & TCP_SYN) {
656     /* If an incoming segment is not acceptable, an acknowledgment
657        should be sent in reply */
658     if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd)) {
659       /* If the SYN is in the window it is an error, send a reset */
660       tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(),
661         ip_current_src_addr(), tcphdr->dest, tcphdr->src);
662       return;
663     }
664   } else if (flags & TCP_FIN) {
665     /* - eighth, check the FIN bit: Remain in the TIME-WAIT state.
666          Restart the 2 MSL time-wait timeout.*/
667     pcb->tmr = tcp_ticks;
668   }
669 
670   if ((tcplen > 0)) {
671     /* Acknowledge data, FIN or out-of-window SYN */
672     pcb->flags |= TF_ACK_NOW;
673     tcp_output(pcb);
674   }
675   return;
676 }
677 
678 /**
679  * Implements the TCP state machine. Called by tcp_input. In some
680  * states tcp_receive() is called to receive data. The tcp_seg
681  * argument will be freed by the caller (tcp_input()) unless the
682  * recv_data pointer in the pcb is set.
683  *
684  * @param pcb the tcp_pcb for which a segment arrived
685  *
686  * @note the segment which arrived is saved in global variables, therefore only the pcb
687  *       involved is passed as a parameter to this function
688  */
689 static err_t
690 tcp_process(struct tcp_pcb *pcb)
691 {
692   struct tcp_seg *rseg;
693   u8_t acceptable = 0;
694   err_t err;
695 
696   err = ERR_OK;
697 
698   /* Process incoming RST segments. */
699   if (flags & TCP_RST) {
700     /* First, determine if the reset is acceptable. */
701     if (pcb->state == SYN_SENT) {
702       /* "In the SYN-SENT state (a RST received in response to an initial SYN),
703           the RST is acceptable if the ACK field acknowledges the SYN." */
704       if (ackno == pcb->snd_nxt) {
705         acceptable = 1;
706       }
707     } else {
708       /* "In all states except SYN-SENT, all reset (RST) segments are validated
709           by checking their SEQ-fields." */
710       if (seqno == pcb->rcv_nxt) {
711         acceptable = 1;
712       } else  if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt,
713                                   pcb->rcv_nxt + pcb->rcv_wnd)) {
714         /* If the sequence number is inside the window, we only send an ACK
715            and wait for a re-send with matching sequence number.
716            This violates RFC 793, but is required to protection against
717            CVE-2004-0230 (RST spoofing attack). */
718         tcp_ack_now(pcb);
719       }
720     }
721 
722     if (acceptable) {
723       LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: Connection RESET\n"));
724       LWIP_ASSERT("tcp_input: pcb->state != CLOSED", pcb->state != CLOSED);
725       recv_flags |= TF_RESET;
726       pcb->flags &= ~TF_ACK_DELAY;
727       return ERR_RST;
728     } else {
729       LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n",
730        seqno, pcb->rcv_nxt));
731       LWIP_DEBUGF(TCP_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n",
732        seqno, pcb->rcv_nxt));
733       return ERR_OK;
734     }
735   }
736 
737   if ((flags & TCP_SYN) && (pcb->state != SYN_SENT && pcb->state != SYN_RCVD)) {
738     /* Cope with new connection attempt after remote end crashed */
739     tcp_ack_now(pcb);
740     return ERR_OK;
741   }
742 
743   if ((pcb->flags & TF_RXCLOSED) == 0) {
744     /* Update the PCB (in)activity timer unless rx is closed (see tcp_shutdown) */
745     pcb->tmr = tcp_ticks;
746   }
747   pcb->keep_cnt_sent = 0;
748 
749   tcp_parseopt(pcb);
750 
751   /* Do different things depending on the TCP state. */
752   switch (pcb->state) {
753   case SYN_SENT:
754     LWIP_DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %"U32_F" pcb->snd_nxt %"U32_F" unacked %"U32_F"\n", ackno,
755      pcb->snd_nxt, lwip_ntohl(pcb->unacked->tcphdr->seqno)));
756     /* received SYN ACK with expected sequence number? */
757     if ((flags & TCP_ACK) && (flags & TCP_SYN)
758         && (ackno == pcb->lastack + 1)) {
759       pcb->rcv_nxt = seqno + 1;
760       pcb->rcv_ann_right_edge = pcb->rcv_nxt;
761       pcb->lastack = ackno;
762       pcb->snd_wnd = tcphdr->wnd;
763       pcb->snd_wnd_max = pcb->snd_wnd;
764       pcb->snd_wl1 = seqno - 1; /* initialise to seqno - 1 to force window update */
765       pcb->state = ESTABLISHED;
766 
767 #if TCP_CALCULATE_EFF_SEND_MSS
768       pcb->mss = tcp_eff_send_mss(pcb->mss, &pcb->local_ip, &pcb->remote_ip);
769 #endif /* TCP_CALCULATE_EFF_SEND_MSS */
770 
771       pcb->cwnd = LWIP_TCP_CALC_INITIAL_CWND(pcb->mss);
772       LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_process (SENT): cwnd %"TCPWNDSIZE_F
773                                    " ssthresh %"TCPWNDSIZE_F"\n",
774                                    pcb->cwnd, pcb->ssthresh));
775       LWIP_ASSERT("pcb->snd_queuelen > 0", (pcb->snd_queuelen > 0));
776       --pcb->snd_queuelen;
777       LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_process: SYN-SENT --queuelen %"TCPWNDSIZE_F"\n", (tcpwnd_size_t)pcb->snd_queuelen));
778       rseg = pcb->unacked;
779       if (rseg == NULL) {
780         /* might happen if tcp_output fails in tcp_rexmit_rto()
781            in which case the segment is on the unsent list */
782         rseg = pcb->unsent;
783         LWIP_ASSERT("no segment to free", rseg != NULL);
784         pcb->unsent = rseg->next;
785       } else {
786         pcb->unacked = rseg->next;
787       }
788       tcp_seg_free(rseg);
789 
790       /* If there's nothing left to acknowledge, stop the retransmit
791          timer, otherwise reset it to start again */
792       if (pcb->unacked == NULL) {
793         pcb->rtime = -1;
794       } else {
795         pcb->rtime = 0;
796         pcb->nrtx = 0;
797       }
798 
799       /* Call the user specified function to call when successfully
800        * connected. */
801       TCP_EVENT_CONNECTED(pcb, ERR_OK, err);
802       if (err == ERR_ABRT) {
803         return ERR_ABRT;
804       }
805       tcp_ack_now(pcb);
806     }
807     /* received ACK? possibly a half-open connection */
808     else if (flags & TCP_ACK) {
809       /* send a RST to bring the other side in a non-synchronized state. */
810       tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(),
811         ip_current_src_addr(), tcphdr->dest, tcphdr->src);
812       /* Resend SYN immediately (don't wait for rto timeout) to establish
813         connection faster, but do not send more SYNs than we otherwise would
814         have, or we might get caught in a loop on loopback interfaces. */
815       if (pcb->nrtx < TCP_SYNMAXRTX) {
816         pcb->rtime = 0;
817         tcp_rexmit_rto(pcb);
818       }
819     }
820     break;
821   case SYN_RCVD:
822     if (flags & TCP_ACK) {
823       /* expected ACK number? */
824       if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)) {
825         pcb->state = ESTABLISHED;
826         LWIP_DEBUGF(TCP_DEBUG, ("TCP connection established %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
827 #if LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG
828 #if LWIP_CALLBACK_API
829         LWIP_ASSERT("pcb->listener->accept != NULL",
830           (pcb->listener == NULL) || (pcb->listener->accept != NULL));
831 #endif
832         if (pcb->listener == NULL) {
833           /* listen pcb might be closed by now */
834           err = ERR_VAL;
835         } else
836 #endif /* LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG */
837         {
838           tcp_backlog_accepted(pcb);
839           /* Call the accept function. */
840           TCP_EVENT_ACCEPT(pcb->listener, pcb, pcb->callback_arg, ERR_OK, err);
841         }
842         if (err != ERR_OK) {
843           /* If the accept function returns with an error, we abort
844            * the connection. */
845           /* Already aborted? */
846           if (err != ERR_ABRT) {
847             tcp_abort(pcb);
848           }
849           return ERR_ABRT;
850         }
851         /* If there was any data contained within this ACK,
852          * we'd better pass it on to the application as well. */
853         tcp_receive(pcb);
854 
855         /* Prevent ACK for SYN to generate a sent event */
856         if (recv_acked != 0) {
857           recv_acked--;
858         }
859 
860         pcb->cwnd = LWIP_TCP_CALC_INITIAL_CWND(pcb->mss);
861         LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_process (SYN_RCVD): cwnd %"TCPWNDSIZE_F
862                                      " ssthresh %"TCPWNDSIZE_F"\n",
863                                      pcb->cwnd, pcb->ssthresh));
864 
865         if (recv_flags & TF_GOT_FIN) {
866           tcp_ack_now(pcb);
867           pcb->state = CLOSE_WAIT;
868         }
869       } else {
870         /* incorrect ACK number, send RST */
871         tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(),
872           ip_current_src_addr(), tcphdr->dest, tcphdr->src);
873       }
874     } else if ((flags & TCP_SYN) && (seqno == pcb->rcv_nxt - 1)) {
875       /* Looks like another copy of the SYN - retransmit our SYN-ACK */
876       tcp_rexmit(pcb);
877     }
878     break;
879   case CLOSE_WAIT:
880     /* FALLTHROUGH */
881   case ESTABLISHED:
882     tcp_receive(pcb);
883     if (recv_flags & TF_GOT_FIN) { /* passive close */
884       tcp_ack_now(pcb);
885       pcb->state = CLOSE_WAIT;
886     }
887     break;
888   case FIN_WAIT_1:
889     tcp_receive(pcb);
890     if (recv_flags & TF_GOT_FIN) {
891       if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt) &&
892           pcb->unsent == NULL) {
893         LWIP_DEBUGF(TCP_DEBUG,
894           ("TCP connection closed: FIN_WAIT_1 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
895         tcp_ack_now(pcb);
896         tcp_pcb_purge(pcb);
897         TCP_RMV_ACTIVE(pcb);
898         pcb->state = TIME_WAIT;
899         TCP_REG(&tcp_tw_pcbs, pcb);
900       } else {
901         tcp_ack_now(pcb);
902         pcb->state = CLOSING;
903       }
904     } else if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt) &&
905                pcb->unsent == NULL) {
906       pcb->state = FIN_WAIT_2;
907     }
908     break;
909   case FIN_WAIT_2:
910     tcp_receive(pcb);
911     if (recv_flags & TF_GOT_FIN) {
912       LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: FIN_WAIT_2 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
913       tcp_ack_now(pcb);
914       tcp_pcb_purge(pcb);
915       TCP_RMV_ACTIVE(pcb);
916       pcb->state = TIME_WAIT;
917       TCP_REG(&tcp_tw_pcbs, pcb);
918     }
919     break;
920   case CLOSING:
921     tcp_receive(pcb);
922     if ((flags & TCP_ACK) && ackno == pcb->snd_nxt && pcb->unsent == NULL) {
923       LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: CLOSING %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
924       tcp_pcb_purge(pcb);
925       TCP_RMV_ACTIVE(pcb);
926       pcb->state = TIME_WAIT;
927       TCP_REG(&tcp_tw_pcbs, pcb);
928     }
929     break;
930   case LAST_ACK:
931     tcp_receive(pcb);
932     if ((flags & TCP_ACK) && ackno == pcb->snd_nxt && pcb->unsent == NULL) {
933       LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: LAST_ACK %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
934       /* bugfix #21699: don't set pcb->state to CLOSED here or we risk leaking segments */
935       recv_flags |= TF_CLOSED;
936     }
937     break;
938   default:
939     break;
940   }
941   return ERR_OK;
942 }
943 
944 #if TCP_QUEUE_OOSEQ
945 /**
946  * Insert segment into the list (segments covered with new one will be deleted)
947  *
948  * Called from tcp_receive()
949  */
950 static void
951 tcp_oos_insert_segment(struct tcp_seg *cseg, struct tcp_seg *next)
952 {
953   struct tcp_seg *old_seg;
954 
955   if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) {
956     /* received segment overlaps all following segments */
957     tcp_segs_free(next);
958     next = NULL;
959   } else {
960     /* delete some following segments
961        oos queue may have segments with FIN flag */
962     while (next &&
963            TCP_SEQ_GEQ((seqno + cseg->len),
964                       (next->tcphdr->seqno + next->len))) {
965       /* cseg with FIN already processed */
966       if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) {
967         TCPH_SET_FLAG(cseg->tcphdr, TCP_FIN);
968       }
969       old_seg = next;
970       next = next->next;
971       tcp_seg_free(old_seg);
972     }
973     if (next &&
974         TCP_SEQ_GT(seqno + cseg->len, next->tcphdr->seqno)) {
975       /* We need to trim the incoming segment. */
976       cseg->len = (u16_t)(next->tcphdr->seqno - seqno);
977       pbuf_realloc(cseg->p, cseg->len);
978     }
979   }
980   cseg->next = next;
981 }
982 #endif /* TCP_QUEUE_OOSEQ */
983 
984 /**
985  * Called by tcp_process. Checks if the given segment is an ACK for outstanding
986  * data, and if so frees the memory of the buffered data. Next, it places the
987  * segment on any of the receive queues (pcb->recved or pcb->ooseq). If the segment
988  * is buffered, the pbuf is referenced by pbuf_ref so that it will not be freed until
989  * it has been removed from the buffer.
990  *
991  * If the incoming segment constitutes an ACK for a segment that was used for RTT
992  * estimation, the RTT is estimated here as well.
993  *
994  * Called from tcp_process().
995  */
996 static void
997 tcp_receive(struct tcp_pcb *pcb)
998 {
999   struct tcp_seg *next;
1000 #if TCP_QUEUE_OOSEQ
1001   struct tcp_seg *prev, *cseg;
1002 #endif /* TCP_QUEUE_OOSEQ */
1003   s32_t off;
1004   s16_t m;
1005   u32_t right_wnd_edge;
1006   u16_t new_tot_len;
1007   int found_dupack = 0;
1008 #if TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS
1009   u32_t ooseq_blen;
1010   u16_t ooseq_qlen;
1011 #endif /* TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS */
1012 
1013   LWIP_ASSERT("tcp_receive: wrong state", pcb->state >= ESTABLISHED);
1014 
1015   if (flags & TCP_ACK) {
1016     right_wnd_edge = pcb->snd_wnd + pcb->snd_wl2;
1017 
1018     /* Update window. */
1019     if (TCP_SEQ_LT(pcb->snd_wl1, seqno) ||
1020        (pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) ||
1021        (pcb->snd_wl2 == ackno && (u32_t)SND_WND_SCALE(pcb, tcphdr->wnd) > pcb->snd_wnd)) {
1022       pcb->snd_wnd = SND_WND_SCALE(pcb, tcphdr->wnd);
1023       /* keep track of the biggest window announced by the remote host to calculate
1024          the maximum segment size */
1025       if (pcb->snd_wnd_max < pcb->snd_wnd) {
1026         pcb->snd_wnd_max = pcb->snd_wnd;
1027       }
1028       pcb->snd_wl1 = seqno;
1029       pcb->snd_wl2 = ackno;
1030       if (pcb->snd_wnd == 0) {
1031         if (pcb->persist_backoff == 0) {
1032           /* start persist timer */
1033           pcb->persist_cnt = 0;
1034           pcb->persist_backoff = 1;
1035         }
1036       } else if (pcb->persist_backoff > 0) {
1037         /* stop persist timer */
1038           pcb->persist_backoff = 0;
1039       }
1040       LWIP_DEBUGF(TCP_WND_DEBUG, ("tcp_receive: window update %"TCPWNDSIZE_F"\n", pcb->snd_wnd));
1041 #if TCP_WND_DEBUG
1042     } else {
1043       if (pcb->snd_wnd != (tcpwnd_size_t)SND_WND_SCALE(pcb, tcphdr->wnd)) {
1044         LWIP_DEBUGF(TCP_WND_DEBUG,
1045                     ("tcp_receive: no window update lastack %"U32_F" ackno %"
1046                      U32_F" wl1 %"U32_F" seqno %"U32_F" wl2 %"U32_F"\n",
1047                      pcb->lastack, ackno, pcb->snd_wl1, seqno, pcb->snd_wl2));
1048       }
1049 #endif /* TCP_WND_DEBUG */
1050     }
1051 
1052     /* (From Stevens TCP/IP Illustrated Vol II, p970.) Its only a
1053      * duplicate ack if:
1054      * 1) It doesn't ACK new data
1055      * 2) length of received packet is zero (i.e. no payload)
1056      * 3) the advertised window hasn't changed
1057      * 4) There is outstanding unacknowledged data (retransmission timer running)
1058      * 5) The ACK is == biggest ACK sequence number so far seen (snd_una)
1059      *
1060      * If it passes all five, should process as a dupack:
1061      * a) dupacks < 3: do nothing
1062      * b) dupacks == 3: fast retransmit
1063      * c) dupacks > 3: increase cwnd
1064      *
1065      * If it only passes 1-3, should reset dupack counter (and add to
1066      * stats, which we don't do in lwIP)
1067      *
1068      * If it only passes 1, should reset dupack counter
1069      *
1070      */
1071 
1072     /* Clause 1 */
1073     if (TCP_SEQ_LEQ(ackno, pcb->lastack)) {
1074       /* Clause 2 */
1075       if (tcplen == 0) {
1076         /* Clause 3 */
1077         if (pcb->snd_wl2 + pcb->snd_wnd == right_wnd_edge) {
1078           /* Clause 4 */
1079           if (pcb->rtime >= 0) {
1080             /* Clause 5 */
1081             if (pcb->lastack == ackno) {
1082               found_dupack = 1;
1083               if ((u8_t)(pcb->dupacks + 1) > pcb->dupacks) {
1084                 ++pcb->dupacks;
1085               }
1086               if (pcb->dupacks > 3) {
1087                 /* Inflate the congestion window, but not if it means that
1088                    the value overflows. */
1089                 if ((tcpwnd_size_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {
1090                   pcb->cwnd += pcb->mss;
1091                 }
1092               } else if (pcb->dupacks == 3) {
1093                 /* Do fast retransmit */
1094                 tcp_rexmit_fast(pcb);
1095               }
1096             }
1097           }
1098         }
1099       }
1100       /* If Clause (1) or more is true, but not a duplicate ack, reset
1101        * count of consecutive duplicate acks */
1102       if (!found_dupack) {
1103         pcb->dupacks = 0;
1104       }
1105     } else if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)) {
1106       /* We come here when the ACK acknowledges new data. */
1107 
1108       /* Reset the "IN Fast Retransmit" flag, since we are no longer
1109          in fast retransmit. Also reset the congestion window to the
1110          slow start threshold. */
1111       if (pcb->flags & TF_INFR) {
1112         pcb->flags &= ~TF_INFR;
1113         pcb->cwnd = pcb->ssthresh;
1114       }
1115 
1116       /* Reset the number of retransmissions. */
1117       pcb->nrtx = 0;
1118 
1119       /* Reset the retransmission time-out. */
1120       pcb->rto = (pcb->sa >> 3) + pcb->sv;
1121 
1122       /* Reset the fast retransmit variables. */
1123       pcb->dupacks = 0;
1124       pcb->lastack = ackno;
1125 
1126       /* Update the congestion control variables (cwnd and
1127          ssthresh). */
1128       if (pcb->state >= ESTABLISHED) {
1129         if (pcb->cwnd < pcb->ssthresh) {
1130           if ((tcpwnd_size_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {
1131             pcb->cwnd += pcb->mss;
1132           }
1133           LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: slow start cwnd %"TCPWNDSIZE_F"\n", pcb->cwnd));
1134         } else {
1135           tcpwnd_size_t new_cwnd = (pcb->cwnd + pcb->mss * pcb->mss / pcb->cwnd);
1136           if (new_cwnd > pcb->cwnd) {
1137             pcb->cwnd = new_cwnd;
1138           }
1139           LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: congestion avoidance cwnd %"TCPWNDSIZE_F"\n", pcb->cwnd));
1140         }
1141       }
1142       LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: ACK for %"U32_F", unacked->seqno %"U32_F":%"U32_F"\n",
1143                                     ackno,
1144                                     pcb->unacked != NULL?
1145                                     lwip_ntohl(pcb->unacked->tcphdr->seqno): 0,
1146                                     pcb->unacked != NULL?
1147                                     lwip_ntohl(pcb->unacked->tcphdr->seqno) + TCP_TCPLEN(pcb->unacked): 0));
1148 
1149       /* Remove segment from the unacknowledged list if the incoming
1150          ACK acknowledges them. */
1151       while (pcb->unacked != NULL &&
1152              TCP_SEQ_LEQ(lwip_ntohl(pcb->unacked->tcphdr->seqno) +
1153                          TCP_TCPLEN(pcb->unacked), ackno)) {
1154         LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unacked\n",
1155                                       lwip_ntohl(pcb->unacked->tcphdr->seqno),
1156                                       lwip_ntohl(pcb->unacked->tcphdr->seqno) +
1157                                       TCP_TCPLEN(pcb->unacked)));
1158 
1159         next = pcb->unacked;
1160         pcb->unacked = pcb->unacked->next;
1161 
1162         LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"TCPWNDSIZE_F" ... ", (tcpwnd_size_t)pcb->snd_queuelen));
1163         LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p)));
1164 
1165         pcb->snd_queuelen -= pbuf_clen(next->p);
1166         recv_acked += next->len;
1167         tcp_seg_free(next);
1168 
1169         LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"TCPWNDSIZE_F" (after freeing unacked)\n", (tcpwnd_size_t)pcb->snd_queuelen));
1170         if (pcb->snd_queuelen != 0) {
1171           LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL ||
1172                       pcb->unsent != NULL);
1173         }
1174       }
1175 
1176       /* If there's nothing left to acknowledge, stop the retransmit
1177          timer, otherwise reset it to start again */
1178       if (pcb->unacked == NULL) {
1179         pcb->rtime = -1;
1180       } else {
1181         pcb->rtime = 0;
1182       }
1183 
1184       pcb->polltmr = 0;
1185 
1186 #if LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS
1187       if (ip_current_is_v6()) {
1188         /* Inform neighbor reachability of forward progress. */
1189         nd6_reachability_hint(ip6_current_src_addr());
1190       }
1191 #endif /* LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS*/
1192     } else {
1193       /* Out of sequence ACK, didn't really ack anything */
1194       tcp_send_empty_ack(pcb);
1195     }
1196 
1197     /* We go through the ->unsent list to see if any of the segments
1198        on the list are acknowledged by the ACK. This may seem
1199        strange since an "unsent" segment shouldn't be acked. The
1200        rationale is that lwIP puts all outstanding segments on the
1201        ->unsent list after a retransmission, so these segments may
1202        in fact have been sent once. */
1203     while (pcb->unsent != NULL &&
1204            TCP_SEQ_BETWEEN(ackno, lwip_ntohl(pcb->unsent->tcphdr->seqno) +
1205                            TCP_TCPLEN(pcb->unsent), pcb->snd_nxt)) {
1206       LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unsent\n",
1207                                     lwip_ntohl(pcb->unsent->tcphdr->seqno), lwip_ntohl(pcb->unsent->tcphdr->seqno) +
1208                                     TCP_TCPLEN(pcb->unsent)));
1209 
1210       next = pcb->unsent;
1211       pcb->unsent = pcb->unsent->next;
1212 #if TCP_OVERSIZE
1213       if (pcb->unsent == NULL) {
1214         pcb->unsent_oversize = 0;
1215       }
1216 #endif /* TCP_OVERSIZE */
1217       LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"TCPWNDSIZE_F" ... ", (tcpwnd_size_t)pcb->snd_queuelen));
1218       LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p)));
1219       /* Prevent ACK for FIN to generate a sent event */
1220       pcb->snd_queuelen -= pbuf_clen(next->p);
1221       recv_acked += next->len;
1222       tcp_seg_free(next);
1223       LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"TCPWNDSIZE_F" (after freeing unsent)\n", (tcpwnd_size_t)pcb->snd_queuelen));
1224       if (pcb->snd_queuelen != 0) {
1225         LWIP_ASSERT("tcp_receive: valid queue length",
1226           pcb->unacked != NULL || pcb->unsent != NULL);
1227       }
1228     }
1229     pcb->snd_buf += recv_acked;
1230     /* End of ACK for new data processing. */
1231 
1232     LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: pcb->rttest %"U32_F" rtseq %"U32_F" ackno %"U32_F"\n",
1233                                 pcb->rttest, pcb->rtseq, ackno));
1234 
1235     /* RTT estimation calculations. This is done by checking if the
1236        incoming segment acknowledges the segment we use to take a
1237        round-trip time measurement. */
1238     if (pcb->rttest && TCP_SEQ_LT(pcb->rtseq, ackno)) {
1239       /* diff between this shouldn't exceed 32K since this are tcp timer ticks
1240          and a round-trip shouldn't be that long... */
1241       m = (s16_t)(tcp_ticks - pcb->rttest);
1242 
1243       LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: experienced rtt %"U16_F" ticks (%"U16_F" msec).\n",
1244                                   m, (u16_t)(m * TCP_SLOW_INTERVAL)));
1245 
1246       /* This is taken directly from VJs original code in his paper */
1247       m = m - (pcb->sa >> 3);
1248       pcb->sa += m;
1249       if (m < 0) {
1250         m = -m;
1251       }
1252       m = m - (pcb->sv >> 2);
1253       pcb->sv += m;
1254       pcb->rto = (pcb->sa >> 3) + pcb->sv;
1255 
1256       LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: RTO %"U16_F" (%"U16_F" milliseconds)\n",
1257                                   pcb->rto, (u16_t)(pcb->rto * TCP_SLOW_INTERVAL)));
1258 
1259       pcb->rttest = 0;
1260     }
1261   }
1262 
1263   /* If the incoming segment contains data, we must process it
1264      further unless the pcb already received a FIN.
1265      (RFC 793, chapter 3.9, "SEGMENT ARRIVES" in states CLOSE-WAIT, CLOSING,
1266      LAST-ACK and TIME-WAIT: "Ignore the segment text.") */
1267   if ((tcplen > 0) && (pcb->state < CLOSE_WAIT)) {
1268     /* This code basically does three things:
1269 
1270     +) If the incoming segment contains data that is the next
1271     in-sequence data, this data is passed to the application. This
1272     might involve trimming the first edge of the data. The rcv_nxt
1273     variable and the advertised window are adjusted.
1274 
1275     +) If the incoming segment has data that is above the next
1276     sequence number expected (->rcv_nxt), the segment is placed on
1277     the ->ooseq queue. This is done by finding the appropriate
1278     place in the ->ooseq queue (which is ordered by sequence
1279     number) and trim the segment in both ends if needed. An
1280     immediate ACK is sent to indicate that we received an
1281     out-of-sequence segment.
1282 
1283     +) Finally, we check if the first segment on the ->ooseq queue
1284     now is in sequence (i.e., if rcv_nxt >= ooseq->seqno). If
1285     rcv_nxt > ooseq->seqno, we must trim the first edge of the
1286     segment on ->ooseq before we adjust rcv_nxt. The data in the
1287     segments that are now on sequence are chained onto the
1288     incoming segment so that we only need to call the application
1289     once.
1290     */
1291 
1292     /* First, we check if we must trim the first edge. We have to do
1293        this if the sequence number of the incoming segment is less
1294        than rcv_nxt, and the sequence number plus the length of the
1295        segment is larger than rcv_nxt. */
1296     /*    if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)) {
1297           if (TCP_SEQ_LT(pcb->rcv_nxt, seqno + tcplen)) {*/
1298     if (TCP_SEQ_BETWEEN(pcb->rcv_nxt, seqno + 1, seqno + tcplen - 1)) {
1299       /* Trimming the first edge is done by pushing the payload
1300          pointer in the pbuf downwards. This is somewhat tricky since
1301          we do not want to discard the full contents of the pbuf up to
1302          the new starting point of the data since we have to keep the
1303          TCP header which is present in the first pbuf in the chain.
1304 
1305          What is done is really quite a nasty hack: the first pbuf in
1306          the pbuf chain is pointed to by inseg.p. Since we need to be
1307          able to deallocate the whole pbuf, we cannot change this
1308          inseg.p pointer to point to any of the later pbufs in the
1309          chain. Instead, we point the ->payload pointer in the first
1310          pbuf to data in one of the later pbufs. We also set the
1311          inseg.data pointer to point to the right place. This way, the
1312          ->p pointer will still point to the first pbuf, but the
1313          ->p->payload pointer will point to data in another pbuf.
1314 
1315          After we are done with adjusting the pbuf pointers we must
1316          adjust the ->data pointer in the seg and the segment
1317          length.*/
1318 
1319       struct pbuf *p = inseg.p;
1320       off = pcb->rcv_nxt - seqno;
1321       LWIP_ASSERT("inseg.p != NULL", inseg.p);
1322       LWIP_ASSERT("insane offset!", (off < 0x7fff));
1323       if (inseg.p->len < off) {
1324         LWIP_ASSERT("pbuf too short!", (((s32_t)inseg.p->tot_len) >= off));
1325         new_tot_len = (u16_t)(inseg.p->tot_len - off);
1326         while (p->len < off) {
1327           off -= p->len;
1328           /* KJM following line changed (with addition of new_tot_len var)
1329              to fix bug #9076
1330              inseg.p->tot_len -= p->len; */
1331           p->tot_len = new_tot_len;
1332           p->len = 0;
1333           p = p->next;
1334         }
1335         if (pbuf_header(p, (s16_t)-off)) {
1336           /* Do we need to cope with this failing?  Assert for now */
1337           LWIP_ASSERT("pbuf_header failed", 0);
1338         }
1339       } else {
1340         if (pbuf_header(inseg.p, (s16_t)-off)) {
1341           /* Do we need to cope with this failing?  Assert for now */
1342           LWIP_ASSERT("pbuf_header failed", 0);
1343         }
1344       }
1345       inseg.len -= (u16_t)(pcb->rcv_nxt - seqno);
1346       inseg.tcphdr->seqno = seqno = pcb->rcv_nxt;
1347     }
1348     else {
1349       if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)) {
1350         /* the whole segment is < rcv_nxt */
1351         /* must be a duplicate of a packet that has already been correctly handled */
1352 
1353         LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: duplicate seqno %"U32_F"\n", seqno));
1354         tcp_ack_now(pcb);
1355       }
1356     }
1357 
1358     /* The sequence number must be within the window (above rcv_nxt
1359        and below rcv_nxt + rcv_wnd) in order to be further
1360        processed. */
1361     if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt,
1362                         pcb->rcv_nxt + pcb->rcv_wnd - 1)) {
1363       if (pcb->rcv_nxt == seqno) {
1364         /* The incoming segment is the next in sequence. We check if
1365            we have to trim the end of the segment and update rcv_nxt
1366            and pass the data to the application. */
1367         tcplen = TCP_TCPLEN(&inseg);
1368 
1369         if (tcplen > pcb->rcv_wnd) {
1370           LWIP_DEBUGF(TCP_INPUT_DEBUG,
1371                       ("tcp_receive: other end overran receive window"
1372                        "seqno %"U32_F" len %"U16_F" right edge %"U32_F"\n",
1373                        seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd));
1374           if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
1375             /* Must remove the FIN from the header as we're trimming
1376              * that byte of sequence-space from the packet */
1377             TCPH_FLAGS_SET(inseg.tcphdr, TCPH_FLAGS(inseg.tcphdr) & ~(unsigned int)TCP_FIN);
1378           }
1379           /* Adjust length of segment to fit in the window. */
1380           TCPWND_CHECK16(pcb->rcv_wnd);
1381           inseg.len = (u16_t)pcb->rcv_wnd;
1382           if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) {
1383             inseg.len -= 1;
1384           }
1385           pbuf_realloc(inseg.p, inseg.len);
1386           tcplen = TCP_TCPLEN(&inseg);
1387           LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n",
1388                       (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd));
1389         }
1390 #if TCP_QUEUE_OOSEQ
1391         /* Received in-sequence data, adjust ooseq data if:
1392            - FIN has been received or
1393            - inseq overlaps with ooseq */
1394         if (pcb->ooseq != NULL) {
1395           if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
1396             LWIP_DEBUGF(TCP_INPUT_DEBUG,
1397                         ("tcp_receive: received in-order FIN, binning ooseq queue\n"));
1398             /* Received in-order FIN means anything that was received
1399              * out of order must now have been received in-order, so
1400              * bin the ooseq queue */
1401             while (pcb->ooseq != NULL) {
1402               struct tcp_seg *old_ooseq = pcb->ooseq;
1403               pcb->ooseq = pcb->ooseq->next;
1404               tcp_seg_free(old_ooseq);
1405             }
1406           } else {
1407             next = pcb->ooseq;
1408             /* Remove all segments on ooseq that are covered by inseg already.
1409              * FIN is copied from ooseq to inseg if present. */
1410             while (next &&
1411                    TCP_SEQ_GEQ(seqno + tcplen,
1412                                next->tcphdr->seqno + next->len)) {
1413               /* inseg cannot have FIN here (already processed above) */
1414               if ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0 &&
1415                   (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) == 0) {
1416                 TCPH_SET_FLAG(inseg.tcphdr, TCP_FIN);
1417                 tcplen = TCP_TCPLEN(&inseg);
1418               }
1419               prev = next;
1420               next = next->next;
1421               tcp_seg_free(prev);
1422             }
1423             /* Now trim right side of inseg if it overlaps with the first
1424              * segment on ooseq */
1425             if (next &&
1426                 TCP_SEQ_GT(seqno + tcplen,
1427                            next->tcphdr->seqno)) {
1428               /* inseg cannot have FIN here (already processed above) */
1429               inseg.len = (u16_t)(next->tcphdr->seqno - seqno);
1430               if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) {
1431                 inseg.len -= 1;
1432               }
1433               pbuf_realloc(inseg.p, inseg.len);
1434               tcplen = TCP_TCPLEN(&inseg);
1435               LWIP_ASSERT("tcp_receive: segment not trimmed correctly to ooseq queue\n",
1436                           (seqno + tcplen) == next->tcphdr->seqno);
1437             }
1438             pcb->ooseq = next;
1439           }
1440         }
1441 #endif /* TCP_QUEUE_OOSEQ */
1442 
1443         pcb->rcv_nxt = seqno + tcplen;
1444 
1445         /* Update the receiver's (our) window. */
1446         LWIP_ASSERT("tcp_receive: tcplen > rcv_wnd\n", pcb->rcv_wnd >= tcplen);
1447         pcb->rcv_wnd -= tcplen;
1448 
1449         tcp_update_rcv_ann_wnd(pcb);
1450 
1451         /* If there is data in the segment, we make preparations to
1452            pass this up to the application. The ->recv_data variable
1453            is used for holding the pbuf that goes to the
1454            application. The code for reassembling out-of-sequence data
1455            chains its data on this pbuf as well.
1456 
1457            If the segment was a FIN, we set the TF_GOT_FIN flag that will
1458            be used to indicate to the application that the remote side has
1459            closed its end of the connection. */
1460         if (inseg.p->tot_len > 0) {
1461           recv_data = inseg.p;
1462           /* Since this pbuf now is the responsibility of the
1463              application, we delete our reference to it so that we won't
1464              (mistakingly) deallocate it. */
1465           inseg.p = NULL;
1466         }
1467         if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
1468           LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN.\n"));
1469           recv_flags |= TF_GOT_FIN;
1470         }
1471 
1472 #if TCP_QUEUE_OOSEQ
1473         /* We now check if we have segments on the ->ooseq queue that
1474            are now in sequence. */
1475         while (pcb->ooseq != NULL &&
1476                pcb->ooseq->tcphdr->seqno == pcb->rcv_nxt) {
1477 
1478           cseg = pcb->ooseq;
1479           seqno = pcb->ooseq->tcphdr->seqno;
1480 
1481           pcb->rcv_nxt += TCP_TCPLEN(cseg);
1482           LWIP_ASSERT("tcp_receive: ooseq tcplen > rcv_wnd\n",
1483                       pcb->rcv_wnd >= TCP_TCPLEN(cseg));
1484           pcb->rcv_wnd -= TCP_TCPLEN(cseg);
1485 
1486           tcp_update_rcv_ann_wnd(pcb);
1487 
1488           if (cseg->p->tot_len > 0) {
1489             /* Chain this pbuf onto the pbuf that we will pass to
1490                the application. */
1491             /* With window scaling, this can overflow recv_data->tot_len, but
1492                that's not a problem since we explicitly fix that before passing
1493                recv_data to the application. */
1494             if (recv_data) {
1495               pbuf_cat(recv_data, cseg->p);
1496             } else {
1497               recv_data = cseg->p;
1498             }
1499             cseg->p = NULL;
1500           }
1501           if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) {
1502             LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN.\n"));
1503             recv_flags |= TF_GOT_FIN;
1504             if (pcb->state == ESTABLISHED) { /* force passive close or we can move to active close */
1505               pcb->state = CLOSE_WAIT;
1506             }
1507           }
1508 
1509           pcb->ooseq = cseg->next;
1510           tcp_seg_free(cseg);
1511         }
1512 #endif /* TCP_QUEUE_OOSEQ */
1513 
1514 
1515         /* Acknowledge the segment(s). */
1516         tcp_ack(pcb);
1517 
1518 #if LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS
1519         if (ip_current_is_v6()) {
1520           /* Inform neighbor reachability of forward progress. */
1521           nd6_reachability_hint(ip6_current_src_addr());
1522         }
1523 #endif /* LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS*/
1524 
1525       } else {
1526         /* We get here if the incoming segment is out-of-sequence. */
1527         tcp_send_empty_ack(pcb);
1528 #if TCP_QUEUE_OOSEQ
1529         /* We queue the segment on the ->ooseq queue. */
1530         if (pcb->ooseq == NULL) {
1531           pcb->ooseq = tcp_seg_copy(&inseg);
1532         } else {
1533           /* If the queue is not empty, we walk through the queue and
1534              try to find a place where the sequence number of the
1535              incoming segment is between the sequence numbers of the
1536              previous and the next segment on the ->ooseq queue. That is
1537              the place where we put the incoming segment. If needed, we
1538              trim the second edges of the previous and the incoming
1539              segment so that it will fit into the sequence.
1540 
1541              If the incoming segment has the same sequence number as a
1542              segment on the ->ooseq queue, we discard the segment that
1543              contains less data. */
1544 
1545           prev = NULL;
1546           for (next = pcb->ooseq; next != NULL; next = next->next) {
1547             if (seqno == next->tcphdr->seqno) {
1548               /* The sequence number of the incoming segment is the
1549                  same as the sequence number of the segment on
1550                  ->ooseq. We check the lengths to see which one to
1551                  discard. */
1552               if (inseg.len > next->len) {
1553                 /* The incoming segment is larger than the old
1554                    segment. We replace some segments with the new
1555                    one. */
1556                 cseg = tcp_seg_copy(&inseg);
1557                 if (cseg != NULL) {
1558                   if (prev != NULL) {
1559                     prev->next = cseg;
1560                   } else {
1561                     pcb->ooseq = cseg;
1562                   }
1563                   tcp_oos_insert_segment(cseg, next);
1564                 }
1565                 break;
1566               } else {
1567                 /* Either the lengths are the same or the incoming
1568                    segment was smaller than the old one; in either
1569                    case, we ditch the incoming segment. */
1570                 break;
1571               }
1572             } else {
1573               if (prev == NULL) {
1574                 if (TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {
1575                   /* The sequence number of the incoming segment is lower
1576                      than the sequence number of the first segment on the
1577                      queue. We put the incoming segment first on the
1578                      queue. */
1579                   cseg = tcp_seg_copy(&inseg);
1580                   if (cseg != NULL) {
1581                     pcb->ooseq = cseg;
1582                     tcp_oos_insert_segment(cseg, next);
1583                   }
1584                   break;
1585                 }
1586               } else {
1587                 /*if (TCP_SEQ_LT(prev->tcphdr->seqno, seqno) &&
1588                   TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {*/
1589                 if (TCP_SEQ_BETWEEN(seqno, prev->tcphdr->seqno+1, next->tcphdr->seqno-1)) {
1590                   /* The sequence number of the incoming segment is in
1591                      between the sequence numbers of the previous and
1592                      the next segment on ->ooseq. We trim trim the previous
1593                      segment, delete next segments that included in received segment
1594                      and trim received, if needed. */
1595                   cseg = tcp_seg_copy(&inseg);
1596                   if (cseg != NULL) {
1597                     if (TCP_SEQ_GT(prev->tcphdr->seqno + prev->len, seqno)) {
1598                       /* We need to trim the prev segment. */
1599                       prev->len = (u16_t)(seqno - prev->tcphdr->seqno);
1600                       pbuf_realloc(prev->p, prev->len);
1601                     }
1602                     prev->next = cseg;
1603                     tcp_oos_insert_segment(cseg, next);
1604                   }
1605                   break;
1606                 }
1607               }
1608               /* If the "next" segment is the last segment on the
1609                  ooseq queue, we add the incoming segment to the end
1610                  of the list. */
1611               if (next->next == NULL &&
1612                   TCP_SEQ_GT(seqno, next->tcphdr->seqno)) {
1613                 if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) {
1614                   /* segment "next" already contains all data */
1615                   break;
1616                 }
1617                 next->next = tcp_seg_copy(&inseg);
1618                 if (next->next != NULL) {
1619                   if (TCP_SEQ_GT(next->tcphdr->seqno + next->len, seqno)) {
1620                     /* We need to trim the last segment. */
1621                     next->len = (u16_t)(seqno - next->tcphdr->seqno);
1622                     pbuf_realloc(next->p, next->len);
1623                   }
1624                   /* check if the remote side overruns our receive window */
1625                   if (TCP_SEQ_GT((u32_t)tcplen + seqno, pcb->rcv_nxt + (u32_t)pcb->rcv_wnd)) {
1626                     LWIP_DEBUGF(TCP_INPUT_DEBUG,
1627                                 ("tcp_receive: other end overran receive window"
1628                                  "seqno %"U32_F" len %"U16_F" right edge %"U32_F"\n",
1629                                  seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd));
1630                     if (TCPH_FLAGS(next->next->tcphdr) & TCP_FIN) {
1631                       /* Must remove the FIN from the header as we're trimming
1632                        * that byte of sequence-space from the packet */
1633                       TCPH_FLAGS_SET(next->next->tcphdr, TCPH_FLAGS(next->next->tcphdr) & ~TCP_FIN);
1634                     }
1635                     /* Adjust length of segment to fit in the window. */
1636                     next->next->len = (u16_t)(pcb->rcv_nxt + pcb->rcv_wnd - seqno);
1637                     pbuf_realloc(next->next->p, next->next->len);
1638                     tcplen = TCP_TCPLEN(next->next);
1639                     LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n",
1640                                 (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd));
1641                   }
1642                 }
1643                 break;
1644               }
1645             }
1646             prev = next;
1647           }
1648         }
1649 #if TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS
1650         /* Check that the data on ooseq doesn't exceed one of the limits
1651            and throw away everything above that limit. */
1652         ooseq_blen = 0;
1653         ooseq_qlen = 0;
1654         prev = NULL;
1655         for (next = pcb->ooseq; next != NULL; prev = next, next = next->next) {
1656           struct pbuf *p = next->p;
1657           ooseq_blen += p->tot_len;
1658           ooseq_qlen += pbuf_clen(p);
1659           if ((ooseq_blen > TCP_OOSEQ_MAX_BYTES) ||
1660               (ooseq_qlen > TCP_OOSEQ_MAX_PBUFS)) {
1661              /* too much ooseq data, dump this and everything after it */
1662              tcp_segs_free(next);
1663              if (prev == NULL) {
1664                /* first ooseq segment is too much, dump the whole queue */
1665                pcb->ooseq = NULL;
1666              } else {
1667                /* just dump 'next' and everything after it */
1668                prev->next = NULL;
1669              }
1670              break;
1671           }
1672         }
1673 #endif /* TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS */
1674 #endif /* TCP_QUEUE_OOSEQ */
1675       }
1676     } else {
1677       /* The incoming segment is not within the window. */
1678       tcp_send_empty_ack(pcb);
1679     }
1680   } else {
1681     /* Segments with length 0 is taken care of here. Segments that
1682        fall out of the window are ACKed. */
1683     if (!TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd - 1)) {
1684       tcp_ack_now(pcb);
1685     }
1686   }
1687 }
1688 
1689 static u8_t
1690 tcp_getoptbyte(void)
1691 {
1692   if ((tcphdr_opt2 == NULL) || (tcp_optidx < tcphdr_opt1len)) {
1693     u8_t* opts = (u8_t *)tcphdr + TCP_HLEN;
1694     return opts[tcp_optidx++];
1695   } else {
1696     u8_t idx = (u8_t)(tcp_optidx++ - tcphdr_opt1len);
1697     return tcphdr_opt2[idx];
1698   }
1699 }
1700 
1701 /**
1702  * Parses the options contained in the incoming segment.
1703  *
1704  * Called from tcp_listen_input() and tcp_process().
1705  * Currently, only the MSS option is supported!
1706  *
1707  * @param pcb the tcp_pcb for which a segment arrived
1708  */
1709 static void
1710 tcp_parseopt(struct tcp_pcb *pcb)
1711 {
1712   u8_t data;
1713   u16_t mss;
1714 #if LWIP_TCP_TIMESTAMPS
1715   u32_t tsval;
1716 #endif
1717 
1718   /* Parse the TCP MSS option, if present. */
1719   if (tcphdr_optlen != 0) {
1720     for (tcp_optidx = 0; tcp_optidx < tcphdr_optlen; ) {
1721       u8_t opt = tcp_getoptbyte();
1722       switch (opt) {
1723       case LWIP_TCP_OPT_EOL:
1724         /* End of options. */
1725         LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: EOL\n"));
1726         return;
1727       case LWIP_TCP_OPT_NOP:
1728         /* NOP option. */
1729         LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: NOP\n"));
1730         break;
1731       case LWIP_TCP_OPT_MSS:
1732         LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: MSS\n"));
1733         if (tcp_getoptbyte() != LWIP_TCP_OPT_LEN_MSS || (tcp_optidx - 2 + LWIP_TCP_OPT_LEN_MSS) > tcphdr_optlen) {
1734           /* Bad length */
1735           LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
1736           return;
1737         }
1738         /* An MSS option with the right option length. */
1739         mss = (tcp_getoptbyte() << 8);
1740         mss |= tcp_getoptbyte();
1741         /* Limit the mss to the configured TCP_MSS and prevent division by zero */
1742         pcb->mss = ((mss > TCP_MSS) || (mss == 0)) ? TCP_MSS : mss;
1743         break;
1744 #if LWIP_WND_SCALE
1745       case LWIP_TCP_OPT_WS:
1746         LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: WND_SCALE\n"));
1747         if (tcp_getoptbyte() != LWIP_TCP_OPT_LEN_WS || (tcp_optidx - 2 + LWIP_TCP_OPT_LEN_WS) > tcphdr_optlen) {
1748           /* Bad length */
1749           LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
1750           return;
1751         }
1752         /* If syn was received with wnd scale option,
1753            activate wnd scale opt, but only if this is not a retransmission */
1754         if ((flags & TCP_SYN) && !(pcb->flags & TF_WND_SCALE)) {
1755           /* An WND_SCALE option with the right option length. */
1756           data = tcp_getoptbyte();
1757           pcb->snd_scale = data;
1758           if (pcb->snd_scale > 14U) {
1759             pcb->snd_scale = 14U;
1760           }
1761           pcb->rcv_scale = TCP_RCV_SCALE;
1762           pcb->flags |= TF_WND_SCALE;
1763           /* window scaling is enabled, we can use the full receive window */
1764           LWIP_ASSERT("window not at default value", pcb->rcv_wnd == TCPWND_MIN16(TCP_WND));
1765           LWIP_ASSERT("window not at default value", pcb->rcv_ann_wnd == TCPWND_MIN16(TCP_WND));
1766           pcb->rcv_wnd = pcb->rcv_ann_wnd = TCP_WND;
1767         }
1768         break;
1769 #endif
1770 #if LWIP_TCP_TIMESTAMPS
1771       case LWIP_TCP_OPT_TS:
1772         LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: TS\n"));
1773         if (tcp_getoptbyte() != LWIP_TCP_OPT_LEN_TS || (tcp_optidx - 2 + LWIP_TCP_OPT_LEN_TS) > tcphdr_optlen) {
1774           /* Bad length */
1775           LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
1776           return;
1777         }
1778         /* TCP timestamp option with valid length */
1779         tsval = tcp_getoptbyte();
1780         tsval |= (tcp_getoptbyte() << 8);
1781         tsval |= (tcp_getoptbyte() << 16);
1782         tsval |= (tcp_getoptbyte() << 24);
1783         if (flags & TCP_SYN) {
1784           pcb->ts_recent = lwip_ntohl(tsval);
1785           /* Enable sending timestamps in every segment now that we know
1786              the remote host supports it. */
1787           pcb->flags |= TF_TIMESTAMP;
1788         } else if (TCP_SEQ_BETWEEN(pcb->ts_lastacksent, seqno, seqno+tcplen)) {
1789           pcb->ts_recent = lwip_ntohl(tsval);
1790         }
1791         /* Advance to next option (6 bytes already read) */
1792         tcp_optidx += LWIP_TCP_OPT_LEN_TS - 6;
1793         break;
1794 #endif
1795       default:
1796         LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: other\n"));
1797         data = tcp_getoptbyte();
1798         if (data < 2) {
1799           LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
1800           /* If the length field is zero, the options are malformed
1801              and we don't process them further. */
1802           return;
1803         }
1804         /* All other options have a length field, so that we easily
1805            can skip past them. */
1806         tcp_optidx += data - 2;
1807       }
1808     }
1809   }
1810 }
1811 
1812 void
1813 tcp_trigger_input_pcb_close(void)
1814 {
1815   recv_flags |= TF_CLOSED;
1816 }
1817 
1818 #endif /* LWIP_TCP */
1819