xref: /minix/minix/lib/liblwip/dist/src/core/tcp_in.c (revision 9f81acbc)
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/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
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 (pcb->listener == NULL) {
829           /* listen pcb might be closed by now */
830           err = ERR_VAL;
831         } else
832 #endif /* LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG */
833         {
834 #if LWIP_CALLBACK_API
835           LWIP_ASSERT("pcb->listener->accept != NULL", pcb->listener->accept != NULL);
836 #endif
837           tcp_backlog_accepted(pcb);
838           /* Call the accept function. */
839           TCP_EVENT_ACCEPT(pcb->listener, pcb, pcb->callback_arg, ERR_OK, err);
840         }
841         if (err != ERR_OK) {
842           /* If the accept function returns with an error, we abort
843            * the connection. */
844           /* Already aborted? */
845           if (err != ERR_ABRT) {
846             tcp_abort(pcb);
847           }
848           return ERR_ABRT;
849         }
850         /* If there was any data contained within this ACK,
851          * we'd better pass it on to the application as well. */
852         tcp_receive(pcb);
853 
854         /* Prevent ACK for SYN to generate a sent event */
855         if (recv_acked != 0) {
856           recv_acked--;
857         }
858 
859         pcb->cwnd = LWIP_TCP_CALC_INITIAL_CWND(pcb->mss);
860         LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_process (SYN_RCVD): cwnd %"TCPWNDSIZE_F
861                                      " ssthresh %"TCPWNDSIZE_F"\n",
862                                      pcb->cwnd, pcb->ssthresh));
863 
864         if (recv_flags & TF_GOT_FIN) {
865           tcp_ack_now(pcb);
866           pcb->state = CLOSE_WAIT;
867         }
868       } else {
869         /* incorrect ACK number, send RST */
870         tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(),
871           ip_current_src_addr(), tcphdr->dest, tcphdr->src);
872       }
873     } else if ((flags & TCP_SYN) && (seqno == pcb->rcv_nxt - 1)) {
874       /* Looks like another copy of the SYN - retransmit our SYN-ACK */
875       tcp_rexmit(pcb);
876     }
877     break;
878   case CLOSE_WAIT:
879     /* FALLTHROUGH */
880   case ESTABLISHED:
881     tcp_receive(pcb);
882     if (recv_flags & TF_GOT_FIN) { /* passive close */
883       tcp_ack_now(pcb);
884       pcb->state = CLOSE_WAIT;
885     }
886     break;
887   case FIN_WAIT_1:
888     tcp_receive(pcb);
889     if (recv_flags & TF_GOT_FIN) {
890       if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt) &&
891           pcb->unsent == NULL) {
892         LWIP_DEBUGF(TCP_DEBUG,
893           ("TCP connection closed: FIN_WAIT_1 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
894         tcp_ack_now(pcb);
895         tcp_pcb_purge(pcb);
896         TCP_RMV_ACTIVE(pcb);
897         pcb->state = TIME_WAIT;
898         TCP_REG(&tcp_tw_pcbs, pcb);
899       } else {
900         tcp_ack_now(pcb);
901         pcb->state = CLOSING;
902       }
903     } else if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt) &&
904                pcb->unsent == NULL) {
905       pcb->state = FIN_WAIT_2;
906     }
907     break;
908   case FIN_WAIT_2:
909     tcp_receive(pcb);
910     if (recv_flags & TF_GOT_FIN) {
911       LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: FIN_WAIT_2 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
912       tcp_ack_now(pcb);
913       tcp_pcb_purge(pcb);
914       TCP_RMV_ACTIVE(pcb);
915       pcb->state = TIME_WAIT;
916       TCP_REG(&tcp_tw_pcbs, pcb);
917     }
918     break;
919   case CLOSING:
920     tcp_receive(pcb);
921     if ((flags & TCP_ACK) && ackno == pcb->snd_nxt && pcb->unsent == NULL) {
922       LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: CLOSING %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
923       tcp_pcb_purge(pcb);
924       TCP_RMV_ACTIVE(pcb);
925       pcb->state = TIME_WAIT;
926       TCP_REG(&tcp_tw_pcbs, pcb);
927     }
928     break;
929   case LAST_ACK:
930     tcp_receive(pcb);
931     if ((flags & TCP_ACK) && ackno == pcb->snd_nxt && pcb->unsent == NULL) {
932       LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: LAST_ACK %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
933       /* bugfix #21699: don't set pcb->state to CLOSED here or we risk leaking segments */
934       recv_flags |= TF_CLOSED;
935     }
936     break;
937   default:
938     break;
939   }
940   return ERR_OK;
941 }
942 
943 #if TCP_QUEUE_OOSEQ
944 /**
945  * Insert segment into the list (segments covered with new one will be deleted)
946  *
947  * Called from tcp_receive()
948  */
949 static void
950 tcp_oos_insert_segment(struct tcp_seg *cseg, struct tcp_seg *next)
951 {
952   struct tcp_seg *old_seg;
953 
954   if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) {
955     /* received segment overlaps all following segments */
956     tcp_segs_free(next);
957     next = NULL;
958   } else {
959     /* delete some following segments
960        oos queue may have segments with FIN flag */
961     while (next &&
962            TCP_SEQ_GEQ((seqno + cseg->len),
963                       (next->tcphdr->seqno + next->len))) {
964       /* cseg with FIN already processed */
965       if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) {
966         TCPH_SET_FLAG(cseg->tcphdr, TCP_FIN);
967       }
968       old_seg = next;
969       next = next->next;
970       tcp_seg_free(old_seg);
971     }
972     if (next &&
973         TCP_SEQ_GT(seqno + cseg->len, next->tcphdr->seqno)) {
974       /* We need to trim the incoming segment. */
975       cseg->len = (u16_t)(next->tcphdr->seqno - seqno);
976       pbuf_realloc(cseg->p, cseg->len);
977     }
978   }
979   cseg->next = next;
980 }
981 #endif /* TCP_QUEUE_OOSEQ */
982 
983 /**
984  * Called by tcp_process. Checks if the given segment is an ACK for outstanding
985  * data, and if so frees the memory of the buffered data. Next, it places the
986  * segment on any of the receive queues (pcb->recved or pcb->ooseq). If the segment
987  * is buffered, the pbuf is referenced by pbuf_ref so that it will not be freed until
988  * it has been removed from the buffer.
989  *
990  * If the incoming segment constitutes an ACK for a segment that was used for RTT
991  * estimation, the RTT is estimated here as well.
992  *
993  * Called from tcp_process().
994  */
995 static void
996 tcp_receive(struct tcp_pcb *pcb)
997 {
998   struct tcp_seg *next;
999 #if TCP_QUEUE_OOSEQ
1000   struct tcp_seg *prev, *cseg;
1001 #endif /* TCP_QUEUE_OOSEQ */
1002   s32_t off;
1003   s16_t m;
1004   u32_t right_wnd_edge;
1005   u16_t new_tot_len;
1006   int found_dupack = 0;
1007 #if TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS
1008   u32_t ooseq_blen;
1009   u16_t ooseq_qlen;
1010 #endif /* TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS */
1011 
1012   LWIP_ASSERT("tcp_receive: wrong state", pcb->state >= ESTABLISHED);
1013 
1014   if (flags & TCP_ACK) {
1015     right_wnd_edge = pcb->snd_wnd + pcb->snd_wl2;
1016 
1017     /* Update window. */
1018     if (TCP_SEQ_LT(pcb->snd_wl1, seqno) ||
1019        (pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) ||
1020        (pcb->snd_wl2 == ackno && (u32_t)SND_WND_SCALE(pcb, tcphdr->wnd) > pcb->snd_wnd)) {
1021       pcb->snd_wnd = SND_WND_SCALE(pcb, tcphdr->wnd);
1022       /* keep track of the biggest window announced by the remote host to calculate
1023          the maximum segment size */
1024       if (pcb->snd_wnd_max < pcb->snd_wnd) {
1025         pcb->snd_wnd_max = pcb->snd_wnd;
1026       }
1027       pcb->snd_wl1 = seqno;
1028       pcb->snd_wl2 = ackno;
1029       if (pcb->snd_wnd == 0) {
1030         if (pcb->persist_backoff == 0) {
1031           /* start persist timer */
1032           pcb->persist_cnt = 0;
1033           pcb->persist_backoff = 1;
1034         }
1035       } else if (pcb->persist_backoff > 0) {
1036         /* stop persist timer */
1037           pcb->persist_backoff = 0;
1038       }
1039       LWIP_DEBUGF(TCP_WND_DEBUG, ("tcp_receive: window update %"TCPWNDSIZE_F"\n", pcb->snd_wnd));
1040 #if TCP_WND_DEBUG
1041     } else {
1042       if (pcb->snd_wnd != (tcpwnd_size_t)SND_WND_SCALE(pcb, tcphdr->wnd)) {
1043         LWIP_DEBUGF(TCP_WND_DEBUG,
1044                     ("tcp_receive: no window update lastack %"U32_F" ackno %"
1045                      U32_F" wl1 %"U32_F" seqno %"U32_F" wl2 %"U32_F"\n",
1046                      pcb->lastack, ackno, pcb->snd_wl1, seqno, pcb->snd_wl2));
1047       }
1048 #endif /* TCP_WND_DEBUG */
1049     }
1050 
1051     /* (From Stevens TCP/IP Illustrated Vol II, p970.) Its only a
1052      * duplicate ack if:
1053      * 1) It doesn't ACK new data
1054      * 2) length of received packet is zero (i.e. no payload)
1055      * 3) the advertised window hasn't changed
1056      * 4) There is outstanding unacknowledged data (retransmission timer running)
1057      * 5) The ACK is == biggest ACK sequence number so far seen (snd_una)
1058      *
1059      * If it passes all five, should process as a dupack:
1060      * a) dupacks < 3: do nothing
1061      * b) dupacks == 3: fast retransmit
1062      * c) dupacks > 3: increase cwnd
1063      *
1064      * If it only passes 1-3, should reset dupack counter (and add to
1065      * stats, which we don't do in lwIP)
1066      *
1067      * If it only passes 1, should reset dupack counter
1068      *
1069      */
1070 
1071     /* Clause 1 */
1072     if (TCP_SEQ_LEQ(ackno, pcb->lastack)) {
1073       /* Clause 2 */
1074       if (tcplen == 0) {
1075         /* Clause 3 */
1076         if (pcb->snd_wl2 + pcb->snd_wnd == right_wnd_edge) {
1077           /* Clause 4 */
1078           if (pcb->rtime >= 0) {
1079             /* Clause 5 */
1080             if (pcb->lastack == ackno) {
1081               found_dupack = 1;
1082               if ((u8_t)(pcb->dupacks + 1) > pcb->dupacks) {
1083                 ++pcb->dupacks;
1084               }
1085               if (pcb->dupacks > 3) {
1086                 /* Inflate the congestion window, but not if it means that
1087                    the value overflows. */
1088                 if ((tcpwnd_size_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {
1089                   pcb->cwnd += pcb->mss;
1090                 }
1091               } else if (pcb->dupacks == 3) {
1092                 /* Do fast retransmit */
1093                 tcp_rexmit_fast(pcb);
1094               }
1095             }
1096           }
1097         }
1098       }
1099       /* If Clause (1) or more is true, but not a duplicate ack, reset
1100        * count of consecutive duplicate acks */
1101       if (!found_dupack) {
1102         pcb->dupacks = 0;
1103       }
1104     } else if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)) {
1105       /* We come here when the ACK acknowledges new data. */
1106 
1107       /* Reset the "IN Fast Retransmit" flag, since we are no longer
1108          in fast retransmit. Also reset the congestion window to the
1109          slow start threshold. */
1110       if (pcb->flags & TF_INFR) {
1111         pcb->flags &= ~TF_INFR;
1112         pcb->cwnd = pcb->ssthresh;
1113       }
1114 
1115       /* Reset the number of retransmissions. */
1116       pcb->nrtx = 0;
1117 
1118       /* Reset the retransmission time-out. */
1119       pcb->rto = (pcb->sa >> 3) + pcb->sv;
1120 
1121       /* Reset the fast retransmit variables. */
1122       pcb->dupacks = 0;
1123       pcb->lastack = ackno;
1124 
1125       /* Update the congestion control variables (cwnd and
1126          ssthresh). */
1127       if (pcb->state >= ESTABLISHED) {
1128         if (pcb->cwnd < pcb->ssthresh) {
1129           if ((tcpwnd_size_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {
1130             pcb->cwnd += pcb->mss;
1131           }
1132           LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: slow start cwnd %"TCPWNDSIZE_F"\n", pcb->cwnd));
1133         } else {
1134           tcpwnd_size_t new_cwnd = (pcb->cwnd + pcb->mss * pcb->mss / pcb->cwnd);
1135           if (new_cwnd > pcb->cwnd) {
1136             pcb->cwnd = new_cwnd;
1137           }
1138           LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: congestion avoidance cwnd %"TCPWNDSIZE_F"\n", pcb->cwnd));
1139         }
1140       }
1141       LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: ACK for %"U32_F", unacked->seqno %"U32_F":%"U32_F"\n",
1142                                     ackno,
1143                                     pcb->unacked != NULL?
1144                                     lwip_ntohl(pcb->unacked->tcphdr->seqno): 0,
1145                                     pcb->unacked != NULL?
1146                                     lwip_ntohl(pcb->unacked->tcphdr->seqno) + TCP_TCPLEN(pcb->unacked): 0));
1147 
1148       /* Remove segment from the unacknowledged list if the incoming
1149          ACK acknowledges them. */
1150       while (pcb->unacked != NULL &&
1151              TCP_SEQ_LEQ(lwip_ntohl(pcb->unacked->tcphdr->seqno) +
1152                          TCP_TCPLEN(pcb->unacked), ackno)) {
1153         LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unacked\n",
1154                                       lwip_ntohl(pcb->unacked->tcphdr->seqno),
1155                                       lwip_ntohl(pcb->unacked->tcphdr->seqno) +
1156                                       TCP_TCPLEN(pcb->unacked)));
1157 
1158         next = pcb->unacked;
1159         pcb->unacked = pcb->unacked->next;
1160 
1161         LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"TCPWNDSIZE_F" ... ", (tcpwnd_size_t)pcb->snd_queuelen));
1162         LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p)));
1163 
1164         pcb->snd_queuelen -= pbuf_clen(next->p);
1165         recv_acked += next->len;
1166         tcp_seg_free(next);
1167 
1168         LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"TCPWNDSIZE_F" (after freeing unacked)\n", (tcpwnd_size_t)pcb->snd_queuelen));
1169         if (pcb->snd_queuelen != 0) {
1170           LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL ||
1171                       pcb->unsent != NULL);
1172         }
1173       }
1174 
1175       /* If there's nothing left to acknowledge, stop the retransmit
1176          timer, otherwise reset it to start again */
1177       if (pcb->unacked == NULL) {
1178         pcb->rtime = -1;
1179       } else {
1180         pcb->rtime = 0;
1181       }
1182 
1183       pcb->polltmr = 0;
1184 
1185 #if LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS
1186       if (ip_current_is_v6()) {
1187         /* Inform neighbor reachability of forward progress. */
1188         nd6_reachability_hint(ip6_current_src_addr());
1189       }
1190 #endif /* LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS*/
1191     } else {
1192       /* Out of sequence ACK, didn't really ack anything */
1193       tcp_send_empty_ack(pcb);
1194     }
1195 
1196     /* We go through the ->unsent list to see if any of the segments
1197        on the list are acknowledged by the ACK. This may seem
1198        strange since an "unsent" segment shouldn't be acked. The
1199        rationale is that lwIP puts all outstanding segments on the
1200        ->unsent list after a retransmission, so these segments may
1201        in fact have been sent once. */
1202     while (pcb->unsent != NULL &&
1203            TCP_SEQ_BETWEEN(ackno, lwip_ntohl(pcb->unsent->tcphdr->seqno) +
1204                            TCP_TCPLEN(pcb->unsent), pcb->snd_nxt)) {
1205       LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unsent\n",
1206                                     lwip_ntohl(pcb->unsent->tcphdr->seqno), lwip_ntohl(pcb->unsent->tcphdr->seqno) +
1207                                     TCP_TCPLEN(pcb->unsent)));
1208 
1209       next = pcb->unsent;
1210       pcb->unsent = pcb->unsent->next;
1211 #if TCP_OVERSIZE
1212       if (pcb->unsent == NULL) {
1213         pcb->unsent_oversize = 0;
1214       }
1215 #endif /* TCP_OVERSIZE */
1216       LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"TCPWNDSIZE_F" ... ", (tcpwnd_size_t)pcb->snd_queuelen));
1217       LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p)));
1218       /* Prevent ACK for FIN to generate a sent event */
1219       pcb->snd_queuelen -= pbuf_clen(next->p);
1220       recv_acked += next->len;
1221       tcp_seg_free(next);
1222       LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"TCPWNDSIZE_F" (after freeing unsent)\n", (tcpwnd_size_t)pcb->snd_queuelen));
1223       if (pcb->snd_queuelen != 0) {
1224         LWIP_ASSERT("tcp_receive: valid queue length",
1225           pcb->unacked != NULL || pcb->unsent != NULL);
1226       }
1227     }
1228     pcb->snd_buf += recv_acked;
1229     /* End of ACK for new data processing. */
1230 
1231     LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: pcb->rttest %"U32_F" rtseq %"U32_F" ackno %"U32_F"\n",
1232                                 pcb->rttest, pcb->rtseq, ackno));
1233 
1234     /* RTT estimation calculations. This is done by checking if the
1235        incoming segment acknowledges the segment we use to take a
1236        round-trip time measurement. */
1237     if (pcb->rttest && TCP_SEQ_LT(pcb->rtseq, ackno)) {
1238       /* diff between this shouldn't exceed 32K since this are tcp timer ticks
1239          and a round-trip shouldn't be that long... */
1240       m = (s16_t)(tcp_ticks - pcb->rttest);
1241 
1242       LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: experienced rtt %"U16_F" ticks (%"U16_F" msec).\n",
1243                                   m, (u16_t)(m * TCP_SLOW_INTERVAL)));
1244 
1245       /* This is taken directly from VJs original code in his paper */
1246       m = m - (pcb->sa >> 3);
1247       pcb->sa += m;
1248       if (m < 0) {
1249         m = -m;
1250       }
1251       m = m - (pcb->sv >> 2);
1252       pcb->sv += m;
1253       pcb->rto = (pcb->sa >> 3) + pcb->sv;
1254 
1255       LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: RTO %"U16_F" (%"U16_F" milliseconds)\n",
1256                                   pcb->rto, (u16_t)(pcb->rto * TCP_SLOW_INTERVAL)));
1257 
1258       pcb->rttest = 0;
1259     }
1260   }
1261 
1262   /* If the incoming segment contains data, we must process it
1263      further unless the pcb already received a FIN.
1264      (RFC 793, chapter 3.9, "SEGMENT ARRIVES" in states CLOSE-WAIT, CLOSING,
1265      LAST-ACK and TIME-WAIT: "Ignore the segment text.") */
1266   if ((tcplen > 0) && (pcb->state < CLOSE_WAIT)) {
1267     /* This code basically does three things:
1268 
1269     +) If the incoming segment contains data that is the next
1270     in-sequence data, this data is passed to the application. This
1271     might involve trimming the first edge of the data. The rcv_nxt
1272     variable and the advertised window are adjusted.
1273 
1274     +) If the incoming segment has data that is above the next
1275     sequence number expected (->rcv_nxt), the segment is placed on
1276     the ->ooseq queue. This is done by finding the appropriate
1277     place in the ->ooseq queue (which is ordered by sequence
1278     number) and trim the segment in both ends if needed. An
1279     immediate ACK is sent to indicate that we received an
1280     out-of-sequence segment.
1281 
1282     +) Finally, we check if the first segment on the ->ooseq queue
1283     now is in sequence (i.e., if rcv_nxt >= ooseq->seqno). If
1284     rcv_nxt > ooseq->seqno, we must trim the first edge of the
1285     segment on ->ooseq before we adjust rcv_nxt. The data in the
1286     segments that are now on sequence are chained onto the
1287     incoming segment so that we only need to call the application
1288     once.
1289     */
1290 
1291     /* First, we check if we must trim the first edge. We have to do
1292        this if the sequence number of the incoming segment is less
1293        than rcv_nxt, and the sequence number plus the length of the
1294        segment is larger than rcv_nxt. */
1295     /*    if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)) {
1296           if (TCP_SEQ_LT(pcb->rcv_nxt, seqno + tcplen)) {*/
1297     if (TCP_SEQ_BETWEEN(pcb->rcv_nxt, seqno + 1, seqno + tcplen - 1)) {
1298       /* Trimming the first edge is done by pushing the payload
1299          pointer in the pbuf downwards. This is somewhat tricky since
1300          we do not want to discard the full contents of the pbuf up to
1301          the new starting point of the data since we have to keep the
1302          TCP header which is present in the first pbuf in the chain.
1303 
1304          What is done is really quite a nasty hack: the first pbuf in
1305          the pbuf chain is pointed to by inseg.p. Since we need to be
1306          able to deallocate the whole pbuf, we cannot change this
1307          inseg.p pointer to point to any of the later pbufs in the
1308          chain. Instead, we point the ->payload pointer in the first
1309          pbuf to data in one of the later pbufs. We also set the
1310          inseg.data pointer to point to the right place. This way, the
1311          ->p pointer will still point to the first pbuf, but the
1312          ->p->payload pointer will point to data in another pbuf.
1313 
1314          After we are done with adjusting the pbuf pointers we must
1315          adjust the ->data pointer in the seg and the segment
1316          length.*/
1317 
1318       struct pbuf *p = inseg.p;
1319       off = pcb->rcv_nxt - seqno;
1320       LWIP_ASSERT("inseg.p != NULL", inseg.p);
1321       LWIP_ASSERT("insane offset!", (off < 0x7fff));
1322       if (inseg.p->len < off) {
1323         LWIP_ASSERT("pbuf too short!", (((s32_t)inseg.p->tot_len) >= off));
1324         new_tot_len = (u16_t)(inseg.p->tot_len - off);
1325         while (p->len < off) {
1326           off -= p->len;
1327           /* KJM following line changed (with addition of new_tot_len var)
1328              to fix bug #9076
1329              inseg.p->tot_len -= p->len; */
1330           p->tot_len = new_tot_len;
1331           p->len = 0;
1332           p = p->next;
1333         }
1334         if (pbuf_header(p, (s16_t)-off)) {
1335           /* Do we need to cope with this failing?  Assert for now */
1336           LWIP_ASSERT("pbuf_header failed", 0);
1337         }
1338       } else {
1339         if (pbuf_header(inseg.p, (s16_t)-off)) {
1340           /* Do we need to cope with this failing?  Assert for now */
1341           LWIP_ASSERT("pbuf_header failed", 0);
1342         }
1343       }
1344       inseg.len -= (u16_t)(pcb->rcv_nxt - seqno);
1345       inseg.tcphdr->seqno = seqno = pcb->rcv_nxt;
1346     }
1347     else {
1348       if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)) {
1349         /* the whole segment is < rcv_nxt */
1350         /* must be a duplicate of a packet that has already been correctly handled */
1351 
1352         LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: duplicate seqno %"U32_F"\n", seqno));
1353         tcp_ack_now(pcb);
1354       }
1355     }
1356 
1357     /* The sequence number must be within the window (above rcv_nxt
1358        and below rcv_nxt + rcv_wnd) in order to be further
1359        processed. */
1360     if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt,
1361                         pcb->rcv_nxt + pcb->rcv_wnd - 1)) {
1362       if (pcb->rcv_nxt == seqno) {
1363         /* The incoming segment is the next in sequence. We check if
1364            we have to trim the end of the segment and update rcv_nxt
1365            and pass the data to the application. */
1366         tcplen = TCP_TCPLEN(&inseg);
1367 
1368         if (tcplen > pcb->rcv_wnd) {
1369           LWIP_DEBUGF(TCP_INPUT_DEBUG,
1370                       ("tcp_receive: other end overran receive window"
1371                        "seqno %"U32_F" len %"U16_F" right edge %"U32_F"\n",
1372                        seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd));
1373           if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
1374             /* Must remove the FIN from the header as we're trimming
1375              * that byte of sequence-space from the packet */
1376             TCPH_FLAGS_SET(inseg.tcphdr, TCPH_FLAGS(inseg.tcphdr) & ~(unsigned int)TCP_FIN);
1377           }
1378           /* Adjust length of segment to fit in the window. */
1379           TCPWND_CHECK16(pcb->rcv_wnd);
1380           inseg.len = (u16_t)pcb->rcv_wnd;
1381           if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) {
1382             inseg.len -= 1;
1383           }
1384           pbuf_realloc(inseg.p, inseg.len);
1385           tcplen = TCP_TCPLEN(&inseg);
1386           LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n",
1387                       (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd));
1388         }
1389 #if TCP_QUEUE_OOSEQ
1390         /* Received in-sequence data, adjust ooseq data if:
1391            - FIN has been received or
1392            - inseq overlaps with ooseq */
1393         if (pcb->ooseq != NULL) {
1394           if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
1395             LWIP_DEBUGF(TCP_INPUT_DEBUG,
1396                         ("tcp_receive: received in-order FIN, binning ooseq queue\n"));
1397             /* Received in-order FIN means anything that was received
1398              * out of order must now have been received in-order, so
1399              * bin the ooseq queue */
1400             while (pcb->ooseq != NULL) {
1401               struct tcp_seg *old_ooseq = pcb->ooseq;
1402               pcb->ooseq = pcb->ooseq->next;
1403               tcp_seg_free(old_ooseq);
1404             }
1405           } else {
1406             next = pcb->ooseq;
1407             /* Remove all segments on ooseq that are covered by inseg already.
1408              * FIN is copied from ooseq to inseg if present. */
1409             while (next &&
1410                    TCP_SEQ_GEQ(seqno + tcplen,
1411                                next->tcphdr->seqno + next->len)) {
1412               /* inseg cannot have FIN here (already processed above) */
1413               if ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0 &&
1414                   (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) == 0) {
1415                 TCPH_SET_FLAG(inseg.tcphdr, TCP_FIN);
1416                 tcplen = TCP_TCPLEN(&inseg);
1417               }
1418               prev = next;
1419               next = next->next;
1420               tcp_seg_free(prev);
1421             }
1422             /* Now trim right side of inseg if it overlaps with the first
1423              * segment on ooseq */
1424             if (next &&
1425                 TCP_SEQ_GT(seqno + tcplen,
1426                            next->tcphdr->seqno)) {
1427               /* inseg cannot have FIN here (already processed above) */
1428               inseg.len = (u16_t)(next->tcphdr->seqno - seqno);
1429               if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) {
1430                 inseg.len -= 1;
1431               }
1432               pbuf_realloc(inseg.p, inseg.len);
1433               tcplen = TCP_TCPLEN(&inseg);
1434               LWIP_ASSERT("tcp_receive: segment not trimmed correctly to ooseq queue\n",
1435                           (seqno + tcplen) == next->tcphdr->seqno);
1436             }
1437             pcb->ooseq = next;
1438           }
1439         }
1440 #endif /* TCP_QUEUE_OOSEQ */
1441 
1442         pcb->rcv_nxt = seqno + tcplen;
1443 
1444         /* Update the receiver's (our) window. */
1445         LWIP_ASSERT("tcp_receive: tcplen > rcv_wnd\n", pcb->rcv_wnd >= tcplen);
1446         pcb->rcv_wnd -= tcplen;
1447 
1448         tcp_update_rcv_ann_wnd(pcb);
1449 
1450         /* If there is data in the segment, we make preparations to
1451            pass this up to the application. The ->recv_data variable
1452            is used for holding the pbuf that goes to the
1453            application. The code for reassembling out-of-sequence data
1454            chains its data on this pbuf as well.
1455 
1456            If the segment was a FIN, we set the TF_GOT_FIN flag that will
1457            be used to indicate to the application that the remote side has
1458            closed its end of the connection. */
1459         if (inseg.p->tot_len > 0) {
1460           recv_data = inseg.p;
1461           /* Since this pbuf now is the responsibility of the
1462              application, we delete our reference to it so that we won't
1463              (mistakingly) deallocate it. */
1464           inseg.p = NULL;
1465         }
1466         if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
1467           LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN.\n"));
1468           recv_flags |= TF_GOT_FIN;
1469         }
1470 
1471 #if TCP_QUEUE_OOSEQ
1472         /* We now check if we have segments on the ->ooseq queue that
1473            are now in sequence. */
1474         while (pcb->ooseq != NULL &&
1475                pcb->ooseq->tcphdr->seqno == pcb->rcv_nxt) {
1476 
1477           cseg = pcb->ooseq;
1478           seqno = pcb->ooseq->tcphdr->seqno;
1479 
1480           pcb->rcv_nxt += TCP_TCPLEN(cseg);
1481           LWIP_ASSERT("tcp_receive: ooseq tcplen > rcv_wnd\n",
1482                       pcb->rcv_wnd >= TCP_TCPLEN(cseg));
1483           pcb->rcv_wnd -= TCP_TCPLEN(cseg);
1484 
1485           tcp_update_rcv_ann_wnd(pcb);
1486 
1487           if (cseg->p->tot_len > 0) {
1488             /* Chain this pbuf onto the pbuf that we will pass to
1489                the application. */
1490             /* With window scaling, this can overflow recv_data->tot_len, but
1491                that's not a problem since we explicitly fix that before passing
1492                recv_data to the application. */
1493             if (recv_data) {
1494               pbuf_cat(recv_data, cseg->p);
1495             } else {
1496               recv_data = cseg->p;
1497             }
1498             cseg->p = NULL;
1499           }
1500           if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) {
1501             LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN.\n"));
1502             recv_flags |= TF_GOT_FIN;
1503             if (pcb->state == ESTABLISHED) { /* force passive close or we can move to active close */
1504               pcb->state = CLOSE_WAIT;
1505             }
1506           }
1507 
1508           pcb->ooseq = cseg->next;
1509           tcp_seg_free(cseg);
1510         }
1511 #endif /* TCP_QUEUE_OOSEQ */
1512 
1513 
1514         /* Acknowledge the segment(s). */
1515         tcp_ack(pcb);
1516 
1517 #if LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS
1518         if (ip_current_is_v6()) {
1519           /* Inform neighbor reachability of forward progress. */
1520           nd6_reachability_hint(ip6_current_src_addr());
1521         }
1522 #endif /* LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS*/
1523 
1524       } else {
1525         /* We get here if the incoming segment is out-of-sequence. */
1526         tcp_send_empty_ack(pcb);
1527 #if TCP_QUEUE_OOSEQ
1528         /* We queue the segment on the ->ooseq queue. */
1529         if (pcb->ooseq == NULL) {
1530           pcb->ooseq = tcp_seg_copy(&inseg);
1531         } else {
1532           /* If the queue is not empty, we walk through the queue and
1533              try to find a place where the sequence number of the
1534              incoming segment is between the sequence numbers of the
1535              previous and the next segment on the ->ooseq queue. That is
1536              the place where we put the incoming segment. If needed, we
1537              trim the second edges of the previous and the incoming
1538              segment so that it will fit into the sequence.
1539 
1540              If the incoming segment has the same sequence number as a
1541              segment on the ->ooseq queue, we discard the segment that
1542              contains less data. */
1543 
1544           prev = NULL;
1545           for (next = pcb->ooseq; next != NULL; next = next->next) {
1546             if (seqno == next->tcphdr->seqno) {
1547               /* The sequence number of the incoming segment is the
1548                  same as the sequence number of the segment on
1549                  ->ooseq. We check the lengths to see which one to
1550                  discard. */
1551               if (inseg.len > next->len) {
1552                 /* The incoming segment is larger than the old
1553                    segment. We replace some segments with the new
1554                    one. */
1555                 cseg = tcp_seg_copy(&inseg);
1556                 if (cseg != NULL) {
1557                   if (prev != NULL) {
1558                     prev->next = cseg;
1559                   } else {
1560                     pcb->ooseq = cseg;
1561                   }
1562                   tcp_oos_insert_segment(cseg, next);
1563                 }
1564                 break;
1565               } else {
1566                 /* Either the lengths are the same or the incoming
1567                    segment was smaller than the old one; in either
1568                    case, we ditch the incoming segment. */
1569                 break;
1570               }
1571             } else {
1572               if (prev == NULL) {
1573                 if (TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {
1574                   /* The sequence number of the incoming segment is lower
1575                      than the sequence number of the first segment on the
1576                      queue. We put the incoming segment first on the
1577                      queue. */
1578                   cseg = tcp_seg_copy(&inseg);
1579                   if (cseg != NULL) {
1580                     pcb->ooseq = cseg;
1581                     tcp_oos_insert_segment(cseg, next);
1582                   }
1583                   break;
1584                 }
1585               } else {
1586                 /*if (TCP_SEQ_LT(prev->tcphdr->seqno, seqno) &&
1587                   TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {*/
1588                 if (TCP_SEQ_BETWEEN(seqno, prev->tcphdr->seqno+1, next->tcphdr->seqno-1)) {
1589                   /* The sequence number of the incoming segment is in
1590                      between the sequence numbers of the previous and
1591                      the next segment on ->ooseq. We trim trim the previous
1592                      segment, delete next segments that included in received segment
1593                      and trim received, if needed. */
1594                   cseg = tcp_seg_copy(&inseg);
1595                   if (cseg != NULL) {
1596                     if (TCP_SEQ_GT(prev->tcphdr->seqno + prev->len, seqno)) {
1597                       /* We need to trim the prev segment. */
1598                       prev->len = (u16_t)(seqno - prev->tcphdr->seqno);
1599                       pbuf_realloc(prev->p, prev->len);
1600                     }
1601                     prev->next = cseg;
1602                     tcp_oos_insert_segment(cseg, next);
1603                   }
1604                   break;
1605                 }
1606               }
1607               /* If the "next" segment is the last segment on the
1608                  ooseq queue, we add the incoming segment to the end
1609                  of the list. */
1610               if (next->next == NULL &&
1611                   TCP_SEQ_GT(seqno, next->tcphdr->seqno)) {
1612                 if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) {
1613                   /* segment "next" already contains all data */
1614                   break;
1615                 }
1616                 next->next = tcp_seg_copy(&inseg);
1617                 if (next->next != NULL) {
1618                   if (TCP_SEQ_GT(next->tcphdr->seqno + next->len, seqno)) {
1619                     /* We need to trim the last segment. */
1620                     next->len = (u16_t)(seqno - next->tcphdr->seqno);
1621                     pbuf_realloc(next->p, next->len);
1622                   }
1623                   /* check if the remote side overruns our receive window */
1624                   if (TCP_SEQ_GT((u32_t)tcplen + seqno, pcb->rcv_nxt + (u32_t)pcb->rcv_wnd)) {
1625                     LWIP_DEBUGF(TCP_INPUT_DEBUG,
1626                                 ("tcp_receive: other end overran receive window"
1627                                  "seqno %"U32_F" len %"U16_F" right edge %"U32_F"\n",
1628                                  seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd));
1629                     if (TCPH_FLAGS(next->next->tcphdr) & TCP_FIN) {
1630                       /* Must remove the FIN from the header as we're trimming
1631                        * that byte of sequence-space from the packet */
1632                       TCPH_FLAGS_SET(next->next->tcphdr, TCPH_FLAGS(next->next->tcphdr) & ~TCP_FIN);
1633                     }
1634                     /* Adjust length of segment to fit in the window. */
1635                     next->next->len = (u16_t)(pcb->rcv_nxt + pcb->rcv_wnd - seqno);
1636                     pbuf_realloc(next->next->p, next->next->len);
1637                     tcplen = TCP_TCPLEN(next->next);
1638                     LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n",
1639                                 (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd));
1640                   }
1641                 }
1642                 break;
1643               }
1644             }
1645             prev = next;
1646           }
1647         }
1648 #if TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS
1649         /* Check that the data on ooseq doesn't exceed one of the limits
1650            and throw away everything above that limit. */
1651         ooseq_blen = 0;
1652         ooseq_qlen = 0;
1653         prev = NULL;
1654         for (next = pcb->ooseq; next != NULL; prev = next, next = next->next) {
1655           struct pbuf *p = next->p;
1656           ooseq_blen += p->tot_len;
1657           ooseq_qlen += pbuf_clen(p);
1658           if ((ooseq_blen > TCP_OOSEQ_MAX_BYTES) ||
1659               (ooseq_qlen > TCP_OOSEQ_MAX_PBUFS)) {
1660              /* too much ooseq data, dump this and everything after it */
1661              tcp_segs_free(next);
1662              if (prev == NULL) {
1663                /* first ooseq segment is too much, dump the whole queue */
1664                pcb->ooseq = NULL;
1665              } else {
1666                /* just dump 'next' and everything after it */
1667                prev->next = NULL;
1668              }
1669              break;
1670           }
1671         }
1672 #endif /* TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS */
1673 #endif /* TCP_QUEUE_OOSEQ */
1674       }
1675     } else {
1676       /* The incoming segment is not within the window. */
1677       tcp_send_empty_ack(pcb);
1678     }
1679   } else {
1680     /* Segments with length 0 is taken care of here. Segments that
1681        fall out of the window are ACKed. */
1682     if (!TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd - 1)) {
1683       tcp_ack_now(pcb);
1684     }
1685   }
1686 }
1687 
1688 static u8_t
1689 tcp_getoptbyte(void)
1690 {
1691   if ((tcphdr_opt2 == NULL) || (tcp_optidx < tcphdr_opt1len)) {
1692     u8_t* opts = (u8_t *)tcphdr + TCP_HLEN;
1693     return opts[tcp_optidx++];
1694   } else {
1695     u8_t idx = (u8_t)(tcp_optidx++ - tcphdr_opt1len);
1696     return tcphdr_opt2[idx];
1697   }
1698 }
1699 
1700 /**
1701  * Parses the options contained in the incoming segment.
1702  *
1703  * Called from tcp_listen_input() and tcp_process().
1704  * Currently, only the MSS option is supported!
1705  *
1706  * @param pcb the tcp_pcb for which a segment arrived
1707  */
1708 static void
1709 tcp_parseopt(struct tcp_pcb *pcb)
1710 {
1711   u8_t data;
1712   u16_t mss;
1713 #if LWIP_TCP_TIMESTAMPS
1714   u32_t tsval;
1715 #endif
1716 
1717   /* Parse the TCP MSS option, if present. */
1718   if (tcphdr_optlen != 0) {
1719     for (tcp_optidx = 0; tcp_optidx < tcphdr_optlen; ) {
1720       u8_t opt = tcp_getoptbyte();
1721       switch (opt) {
1722       case LWIP_TCP_OPT_EOL:
1723         /* End of options. */
1724         LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: EOL\n"));
1725         return;
1726       case LWIP_TCP_OPT_NOP:
1727         /* NOP option. */
1728         LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: NOP\n"));
1729         break;
1730       case LWIP_TCP_OPT_MSS:
1731         LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: MSS\n"));
1732         if (tcp_getoptbyte() != LWIP_TCP_OPT_LEN_MSS || (tcp_optidx - 2 + LWIP_TCP_OPT_LEN_MSS) > tcphdr_optlen) {
1733           /* Bad length */
1734           LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
1735           return;
1736         }
1737         /* An MSS option with the right option length. */
1738         mss = (tcp_getoptbyte() << 8);
1739         mss |= tcp_getoptbyte();
1740         /* Limit the mss to the configured TCP_MSS and prevent division by zero */
1741         pcb->mss = ((mss > TCP_MSS) || (mss == 0)) ? TCP_MSS : mss;
1742         break;
1743 #if LWIP_WND_SCALE
1744       case LWIP_TCP_OPT_WS:
1745         LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: WND_SCALE\n"));
1746         if (tcp_getoptbyte() != LWIP_TCP_OPT_LEN_WS || (tcp_optidx - 2 + LWIP_TCP_OPT_LEN_WS) > tcphdr_optlen) {
1747           /* Bad length */
1748           LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
1749           return;
1750         }
1751         /* If syn was received with wnd scale option,
1752            activate wnd scale opt, but only if this is not a retransmission */
1753         if ((flags & TCP_SYN) && !(pcb->flags & TF_WND_SCALE)) {
1754           /* An WND_SCALE option with the right option length. */
1755           data = tcp_getoptbyte();
1756           pcb->snd_scale = data;
1757           if (pcb->snd_scale > 14U) {
1758             pcb->snd_scale = 14U;
1759           }
1760           pcb->rcv_scale = TCP_RCV_SCALE;
1761           pcb->flags |= TF_WND_SCALE;
1762           /* window scaling is enabled, we can use the full receive window */
1763           LWIP_ASSERT("window not at default value", pcb->rcv_wnd == TCPWND_MIN16(TCP_WND));
1764           LWIP_ASSERT("window not at default value", pcb->rcv_ann_wnd == TCPWND_MIN16(TCP_WND));
1765           pcb->rcv_wnd = pcb->rcv_ann_wnd = TCP_WND;
1766         }
1767         break;
1768 #endif
1769 #if LWIP_TCP_TIMESTAMPS
1770       case LWIP_TCP_OPT_TS:
1771         LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: TS\n"));
1772         if (tcp_getoptbyte() != LWIP_TCP_OPT_LEN_TS || (tcp_optidx - 2 + LWIP_TCP_OPT_LEN_TS) > tcphdr_optlen) {
1773           /* Bad length */
1774           LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
1775           return;
1776         }
1777         /* TCP timestamp option with valid length */
1778         tsval = tcp_getoptbyte();
1779         tsval |= (tcp_getoptbyte() << 8);
1780         tsval |= (tcp_getoptbyte() << 16);
1781         tsval |= (tcp_getoptbyte() << 24);
1782         if (flags & TCP_SYN) {
1783           pcb->ts_recent = lwip_ntohl(tsval);
1784           /* Enable sending timestamps in every segment now that we know
1785              the remote host supports it. */
1786           pcb->flags |= TF_TIMESTAMP;
1787         } else if (TCP_SEQ_BETWEEN(pcb->ts_lastacksent, seqno, seqno+tcplen)) {
1788           pcb->ts_recent = lwip_ntohl(tsval);
1789         }
1790         /* Advance to next option (6 bytes already read) */
1791         tcp_optidx += LWIP_TCP_OPT_LEN_TS - 6;
1792         break;
1793 #endif
1794       default:
1795         LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: other\n"));
1796         data = tcp_getoptbyte();
1797         if (data < 2) {
1798           LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
1799           /* If the length field is zero, the options are malformed
1800              and we don't process them further. */
1801           return;
1802         }
1803         /* All other options have a length field, so that we easily
1804            can skip past them. */
1805         tcp_optidx += data - 2;
1806       }
1807     }
1808   }
1809 }
1810 
1811 void
1812 tcp_trigger_input_pcb_close(void)
1813 {
1814   recv_flags |= TF_CLOSED;
1815 }
1816 
1817 #endif /* LWIP_TCP */
1818