Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers lwip_tcp_in.c Source File

lwip_tcp_in.c

Go to the documentation of this file.
00001 /**
00002  * @file
00003  * Transmission Control Protocol, incoming traffic
00004  *
00005  * The input processing functions of the TCP layer.
00006  *
00007  * These functions are generally called in the order (ip_input() ->)
00008  * tcp_input() -> * tcp_process() -> tcp_receive() (-> application).
00009  *
00010  */
00011 
00012 /*
00013  * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
00014  * All rights reserved.
00015  *
00016  * Redistribution and use in source and binary forms, with or without modification,
00017  * are permitted provided that the following conditions are met:
00018  *
00019  * 1. Redistributions of source code must retain the above copyright notice,
00020  *    this list of conditions and the following disclaimer.
00021  * 2. Redistributions in binary form must reproduce the above copyright notice,
00022  *    this list of conditions and the following disclaimer in the documentation
00023  *    and/or other materials provided with the distribution.
00024  * 3. The name of the author may not be used to endorse or promote products
00025  *    derived from this software without specific prior written permission.
00026  *
00027  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
00028  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00029  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
00030  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00031  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
00032  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00033  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00034  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
00035  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
00036  * OF SUCH DAMAGE.
00037  *
00038  * This file is part of the lwIP TCP/IP stack.
00039  *
00040  * Author: Adam Dunkels <adam@sics.se>
00041  *
00042  */
00043 
00044 #include "lwip/opt.h"
00045 
00046 #if LWIP_TCP /* don't build if not configured for use in lwipopts.h */
00047 
00048 #include "lwip/priv/tcp_priv.h"
00049 #include "lwip/def.h"
00050 #include "lwip/ip_addr.h"
00051 #include "lwip/netif.h"
00052 #include "lwip/mem.h"
00053 #include "lwip/memp.h"
00054 #include "lwip/inet_chksum.h"
00055 #include "lwip/stats.h"
00056 #include "lwip/ip6.h"
00057 #include "lwip/ip6_addr.h"
00058 #if LWIP_ND6_TCP_REACHABILITY_HINTS
00059 #include "lwip/nd6.h"
00060 #endif /* LWIP_ND6_TCP_REACHABILITY_HINTS */
00061 
00062 #include <string.h>
00063 
00064 #ifdef LWIP_HOOK_FILENAME
00065 #include LWIP_HOOK_FILENAME
00066 #endif
00067 
00068 /** Initial CWND calculation as defined RFC 2581 */
00069 #define LWIP_TCP_CALC_INITIAL_CWND(mss) ((tcpwnd_size_t)LWIP_MIN((4U * (mss)), LWIP_MAX((2U * (mss)), 4380U)))
00070 
00071 /* These variables are global to all functions involved in the input
00072    processing of TCP segments. They are set by the tcp_input()
00073    function. */
00074 static struct tcp_seg inseg;
00075 static struct tcp_hdr *tcphdr;
00076 static u16_t tcphdr_optlen;
00077 static u16_t tcphdr_opt1len;
00078 static u8_t *tcphdr_opt2;
00079 static u16_t tcp_optidx;
00080 static u32_t seqno, ackno;
00081 static tcpwnd_size_t recv_acked;
00082 static u16_t tcplen;
00083 static u8_t flags;
00084 
00085 static u8_t recv_flags;
00086 static struct pbuf *recv_data;
00087 
00088 struct tcp_pcb *tcp_input_pcb;
00089 
00090 /* Forward declarations. */
00091 static err_t tcp_process(struct tcp_pcb *pcb);
00092 static void tcp_receive(struct tcp_pcb *pcb);
00093 static void tcp_parseopt(struct tcp_pcb *pcb);
00094 
00095 static void tcp_listen_input(struct tcp_pcb_listen *pcb);
00096 static void tcp_timewait_input(struct tcp_pcb *pcb);
00097 
00098 static int tcp_input_delayed_close(struct tcp_pcb *pcb);
00099 
00100 #if LWIP_TCP_SACK_OUT
00101 static void tcp_add_sack(struct tcp_pcb *pcb, u32_t left, u32_t right);
00102 static void tcp_remove_sacks_lt(struct tcp_pcb *pcb, u32_t seq);
00103 #if defined(TCP_OOSEQ_BYTES_LIMIT) || defined(TCP_OOSEQ_PBUFS_LIMIT)
00104 static void tcp_remove_sacks_gt(struct tcp_pcb *pcb, u32_t seq);
00105 #endif /* TCP_OOSEQ_BYTES_LIMIT || TCP_OOSEQ_PBUFS_LIMIT */
00106 #endif /* LWIP_TCP_SACK_OUT */
00107 
00108 /**
00109  * The initial input processing of TCP. It verifies the TCP header, demultiplexes
00110  * the segment between the PCBs and passes it on to tcp_process(), which implements
00111  * the TCP finite state machine. This function is called by the IP layer (in
00112  * ip_input()).
00113  *
00114  * @param p received TCP segment to process (p->payload pointing to the TCP header)
00115  * @param inp network interface on which this segment was received
00116  */
00117 void
00118 tcp_input(struct pbuf *p, struct netif *inp)
00119 {
00120   struct tcp_pcb *pcb, *prev;
00121   struct tcp_pcb_listen *lpcb;
00122 #if SO_REUSE
00123   struct tcp_pcb *lpcb_prev = NULL;
00124   struct tcp_pcb_listen *lpcb_any = NULL;
00125 #endif /* SO_REUSE */
00126   u8_t hdrlen_bytes;
00127   err_t err;
00128 
00129   LWIP_UNUSED_ARG(inp);
00130   LWIP_ASSERT_CORE_LOCKED();
00131   LWIP_ASSERT("tcp_input: invalid pbuf", p != NULL);
00132 
00133   PERF_START;
00134 
00135   TCP_STATS_INC(tcp.recv);
00136   MIB2_STATS_INC(mib2.tcpinsegs);
00137 
00138   tcphdr = (struct tcp_hdr *)p->payload;
00139 
00140 #if TCP_INPUT_DEBUG
00141   tcp_debug_print(tcphdr);
00142 #endif
00143 
00144   /* Check that TCP header fits in payload */
00145   if (p->len < TCP_HLEN) {
00146     /* drop short packets */
00147     LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet (%"U16_F" bytes) discarded\n", p->tot_len));
00148     TCP_STATS_INC(tcp.lenerr);
00149     goto dropped;
00150   }
00151 
00152   /* Don't even process incoming broadcasts/multicasts. */
00153   if (ip_addr_isbroadcast(ip_current_dest_addr(), ip_current_netif()) ||
00154       ip_addr_ismulticast(ip_current_dest_addr())) {
00155     TCP_STATS_INC(tcp.proterr);
00156     goto dropped;
00157   }
00158 
00159 #if CHECKSUM_CHECK_TCP
00160   IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_TCP) {
00161     /* Verify TCP checksum. */
00162     u16_t chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len,
00163                                     ip_current_src_addr(), ip_current_dest_addr());
00164     if (chksum != 0) {
00165       LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packet discarded due to failing checksum 0x%04"X16_F"\n",
00166                                     chksum));
00167       tcp_debug_print(tcphdr);
00168       TCP_STATS_INC(tcp.chkerr);
00169       goto dropped;
00170     }
00171   }
00172 #endif /* CHECKSUM_CHECK_TCP */
00173 
00174   /* sanity-check header length */
00175   hdrlen_bytes = TCPH_HDRLEN_BYTES(tcphdr);
00176   if ((hdrlen_bytes < TCP_HLEN) || (hdrlen_bytes > p->tot_len)) {
00177     LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: invalid header length (%"U16_F")\n", (u16_t)hdrlen_bytes));
00178     TCP_STATS_INC(tcp.lenerr);
00179     goto dropped;
00180   }
00181 
00182   /* Move the payload pointer in the pbuf so that it points to the
00183      TCP data instead of the TCP header. */
00184   tcphdr_optlen = (u16_t)(hdrlen_bytes - TCP_HLEN);
00185   tcphdr_opt2 = NULL;
00186   if (p->len >= hdrlen_bytes) {
00187     /* all options are in the first pbuf */
00188     tcphdr_opt1len = tcphdr_optlen;
00189     pbuf_remove_header(p, hdrlen_bytes); /* cannot fail */
00190   } else {
00191     u16_t opt2len;
00192     /* TCP header fits into first pbuf, options don't - data is in the next pbuf */
00193     /* there must be a next pbuf, due to hdrlen_bytes sanity check above */
00194     LWIP_ASSERT("p->next != NULL", p->next != NULL);
00195 
00196     /* advance over the TCP header (cannot fail) */
00197     pbuf_remove_header(p, TCP_HLEN);
00198 
00199     /* determine how long the first and second parts of the options are */
00200     tcphdr_opt1len = p->len;
00201     opt2len = (u16_t)(tcphdr_optlen - tcphdr_opt1len);
00202 
00203     /* options continue in the next pbuf: set p to zero length and hide the
00204         options in the next pbuf (adjusting p->tot_len) */
00205     pbuf_remove_header(p, tcphdr_opt1len);
00206 
00207     /* check that the options fit in the second pbuf */
00208     if (opt2len > p->next->len) {
00209       /* drop short packets */
00210       LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: options overflow second pbuf (%"U16_F" bytes)\n", p->next->len));
00211       TCP_STATS_INC(tcp.lenerr);
00212       goto dropped;
00213     }
00214 
00215     /* remember the pointer to the second part of the options */
00216     tcphdr_opt2 = (u8_t *)p->next->payload;
00217 
00218     /* advance p->next to point after the options, and manually
00219         adjust p->tot_len to keep it consistent with the changed p->next */
00220     pbuf_remove_header(p->next, opt2len);
00221     p->tot_len = (u16_t)(p->tot_len - opt2len);
00222 
00223     LWIP_ASSERT("p->len == 0", p->len == 0);
00224     LWIP_ASSERT("p->tot_len == p->next->tot_len", p->tot_len == p->next->tot_len);
00225   }
00226 
00227   /* Convert fields in TCP header to host byte order. */
00228   tcphdr->src = lwip_ntohs(tcphdr->src);
00229   tcphdr->dest = lwip_ntohs(tcphdr->dest);
00230   seqno = tcphdr->seqno = lwip_ntohl(tcphdr->seqno);
00231   ackno = tcphdr->ackno = lwip_ntohl(tcphdr->ackno);
00232   tcphdr->wnd = lwip_ntohs(tcphdr->wnd);
00233 
00234   flags = TCPH_FLAGS(tcphdr);
00235   tcplen = p->tot_len;
00236   if (flags & (TCP_FIN | TCP_SYN)) {
00237     tcplen++;
00238     if (tcplen < p->tot_len) {
00239       /* u16_t overflow, cannot handle this */
00240       LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: length u16_t overflow, cannot handle this\n"));
00241       TCP_STATS_INC(tcp.lenerr);
00242       goto dropped;
00243     }
00244   }
00245 
00246   /* Demultiplex an incoming segment. First, we check if it is destined
00247      for an active connection. */
00248   prev = NULL;
00249 
00250   for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
00251     LWIP_ASSERT("tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED);
00252     LWIP_ASSERT("tcp_input: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);
00253     LWIP_ASSERT("tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN);
00254 
00255     /* check if PCB is bound to specific netif */
00256     if ((pcb->netif_idx != NETIF_NO_INDEX) &&
00257         (pcb->netif_idx != netif_get_index(ip_data.current_input_netif))) {
00258       prev = pcb;
00259       continue;
00260     }
00261 
00262     if (pcb->remote_port == tcphdr->src &&
00263         pcb->local_port == tcphdr->dest &&
00264         ip_addr_cmp(&pcb->remote_ip, ip_current_src_addr()) &&
00265         ip_addr_cmp(&pcb->local_ip, ip_current_dest_addr())) {
00266       /* Move this PCB to the front of the list so that subsequent
00267          lookups will be faster (we exploit locality in TCP segment
00268          arrivals). */
00269       LWIP_ASSERT("tcp_input: pcb->next != pcb (before cache)", pcb->next != pcb);
00270       if (prev != NULL) {
00271         prev->next = pcb->next;
00272         pcb->next = tcp_active_pcbs;
00273         tcp_active_pcbs = pcb;
00274       } else {
00275         TCP_STATS_INC(tcp.cachehit);
00276       }
00277       LWIP_ASSERT("tcp_input: pcb->next != pcb (after cache)", pcb->next != pcb);
00278       break;
00279     }
00280     prev = pcb;
00281   }
00282 
00283   if (pcb == NULL) {
00284     /* If it did not go to an active connection, we check the connections
00285        in the TIME-WAIT state. */
00286     for (pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
00287       LWIP_ASSERT("tcp_input: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
00288 
00289       /* check if PCB is bound to specific netif */
00290       if ((pcb->netif_idx != NETIF_NO_INDEX) &&
00291           (pcb->netif_idx != netif_get_index(ip_data.current_input_netif))) {
00292         continue;
00293       }
00294 
00295       if (pcb->remote_port == tcphdr->src &&
00296           pcb->local_port == tcphdr->dest &&
00297           ip_addr_cmp(&pcb->remote_ip, ip_current_src_addr()) &&
00298           ip_addr_cmp(&pcb->local_ip, ip_current_dest_addr())) {
00299         /* We don't really care enough to move this PCB to the front
00300            of the list since we are not very likely to receive that
00301            many segments for connections in TIME-WAIT. */
00302         LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for TIME_WAITing connection.\n"));
00303 #ifdef LWIP_HOOK_TCP_INPACKET_PCB
00304         if (LWIP_HOOK_TCP_INPACKET_PCB(pcb, tcphdr, tcphdr_optlen, tcphdr_opt1len,
00305                                        tcphdr_opt2, p) == ERR_OK)
00306 #endif
00307         {
00308           tcp_timewait_input(pcb);
00309         }
00310         pbuf_free(p);
00311         return;
00312       }
00313     }
00314 
00315     /* Finally, if we still did not get a match, we check all PCBs that
00316        are LISTENing for incoming connections. */
00317     prev = NULL;
00318     for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
00319       /* check if PCB is bound to specific netif */
00320       if ((lpcb->netif_idx != NETIF_NO_INDEX) &&
00321           (lpcb->netif_idx != netif_get_index(ip_data.current_input_netif))) {
00322         prev = (struct tcp_pcb *)lpcb;
00323         continue;
00324       }
00325 
00326       if (lpcb->local_port == tcphdr->dest) {
00327         if (IP_IS_ANY_TYPE_VAL(lpcb->local_ip)) {
00328           /* found an ANY TYPE (IPv4/IPv6) match */
00329 #if SO_REUSE
00330           lpcb_any = lpcb;
00331           lpcb_prev = prev;
00332 #else /* SO_REUSE */
00333           break;
00334 #endif /* SO_REUSE */
00335         } else if (IP_ADDR_PCB_VERSION_MATCH_EXACT(lpcb, ip_current_dest_addr())) {
00336           if (ip_addr_cmp(&lpcb->local_ip, ip_current_dest_addr())) {
00337             /* found an exact match */
00338             break;
00339           } else if (ip_addr_isany(&lpcb->local_ip)) {
00340             /* found an ANY-match */
00341 #if SO_REUSE
00342             lpcb_any = lpcb;
00343             lpcb_prev = prev;
00344 #else /* SO_REUSE */
00345             break;
00346 #endif /* SO_REUSE */
00347           }
00348         }
00349       }
00350       prev = (struct tcp_pcb *)lpcb;
00351     }
00352 #if SO_REUSE
00353     /* first try specific local IP */
00354     if (lpcb == NULL) {
00355       /* only pass to ANY if no specific local IP has been found */
00356       lpcb = lpcb_any;
00357       prev = lpcb_prev;
00358     }
00359 #endif /* SO_REUSE */
00360     if (lpcb != NULL) {
00361       /* Move this PCB to the front of the list so that subsequent
00362          lookups will be faster (we exploit locality in TCP segment
00363          arrivals). */
00364       if (prev != NULL) {
00365         ((struct tcp_pcb_listen *)prev)->next = lpcb->next;
00366         /* our successor is the remainder of the listening list */
00367         lpcb->next = tcp_listen_pcbs.listen_pcbs;
00368         /* put this listening pcb at the head of the listening list */
00369         tcp_listen_pcbs.listen_pcbs = lpcb;
00370       } else {
00371         TCP_STATS_INC(tcp.cachehit);
00372       }
00373 
00374       LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for LISTENing connection.\n"));
00375 #ifdef LWIP_HOOK_TCP_INPACKET_PCB
00376       if (LWIP_HOOK_TCP_INPACKET_PCB((struct tcp_pcb *)lpcb, tcphdr, tcphdr_optlen,
00377                                      tcphdr_opt1len, tcphdr_opt2, p) == ERR_OK)
00378 #endif
00379       {
00380         tcp_listen_input(lpcb);
00381       }
00382       pbuf_free(p);
00383       return;
00384     }
00385   }
00386 
00387 #if TCP_INPUT_DEBUG
00388   LWIP_DEBUGF(TCP_INPUT_DEBUG, ("+-+-+-+-+-+-+-+-+-+-+-+-+-+- tcp_input: flags "));
00389   tcp_debug_print_flags(TCPH_FLAGS(tcphdr));
00390   LWIP_DEBUGF(TCP_INPUT_DEBUG, ("-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n"));
00391 #endif /* TCP_INPUT_DEBUG */
00392 
00393 
00394 #ifdef LWIP_HOOK_TCP_INPACKET_PCB
00395   if ((pcb != NULL) && LWIP_HOOK_TCP_INPACKET_PCB(pcb, tcphdr, tcphdr_optlen,
00396       tcphdr_opt1len, tcphdr_opt2, p) != ERR_OK) {
00397     pbuf_free(p);
00398     return;
00399   }
00400 #endif
00401   if (pcb != NULL) {
00402     /* The incoming segment belongs to a connection. */
00403 #if TCP_INPUT_DEBUG
00404     tcp_debug_print_state(pcb->state);
00405 #endif /* TCP_INPUT_DEBUG */
00406 
00407     /* Set up a tcp_seg structure. */
00408     inseg.next = NULL;
00409     inseg.len = p->tot_len;
00410     inseg.p = p;
00411     inseg.tcphdr = tcphdr;
00412 
00413     recv_data = NULL;
00414     recv_flags = 0;
00415     recv_acked = 0;
00416 
00417     if (flags & TCP_PSH) {
00418       p->flags |= PBUF_FLAG_PUSH;
00419     }
00420 
00421     /* If there is data which was previously "refused" by upper layer */
00422     if (pcb->refused_data != NULL) {
00423       if ((tcp_process_refused_data(pcb) == ERR_ABRT) ||
00424           ((pcb->refused_data != NULL) && (tcplen > 0))) {
00425         /* pcb has been aborted or refused data is still refused and the new
00426            segment contains data */
00427         if (pcb->rcv_ann_wnd == 0) {
00428           /* this is a zero-window probe, we respond to it with current RCV.NXT
00429           and drop the data segment */
00430           tcp_send_empty_ack(pcb);
00431         }
00432         TCP_STATS_INC(tcp.drop);
00433         MIB2_STATS_INC(mib2.tcpinerrs);
00434         goto aborted;
00435       }
00436     }
00437     tcp_input_pcb = pcb;
00438     err = tcp_process(pcb);
00439     /* A return value of ERR_ABRT means that tcp_abort() was called
00440        and that the pcb has been freed. If so, we don't do anything. */
00441     if (err != ERR_ABRT) {
00442       if (recv_flags & TF_RESET) {
00443         /* TF_RESET means that the connection was reset by the other
00444            end. We then call the error callback to inform the
00445            application that the connection is dead before we
00446            deallocate the PCB. */
00447         TCP_EVENT_ERR(pcb->state, pcb->errf, pcb->callback_arg, ERR_RST);
00448         tcp_pcb_remove(&tcp_active_pcbs, pcb);
00449         tcp_free(pcb);
00450       } else {
00451         err = ERR_OK;
00452         /* If the application has registered a "sent" function to be
00453            called when new send buffer space is available, we call it
00454            now. */
00455         if (recv_acked > 0) {
00456           u16_t acked16;
00457 #if LWIP_WND_SCALE
00458           /* recv_acked is u32_t but the sent callback only takes a u16_t,
00459              so we might have to call it multiple times. */
00460           u32_t acked = recv_acked;
00461           while (acked > 0) {
00462             acked16 = (u16_t)LWIP_MIN(acked, 0xffffu);
00463             acked -= acked16;
00464 #else
00465           {
00466             acked16 = recv_acked;
00467 #endif
00468             TCP_EVENT_SENT(pcb, (u16_t)acked16, err);
00469             if (err == ERR_ABRT) {
00470               goto aborted;
00471             }
00472           }
00473           recv_acked = 0;
00474         }
00475         if (tcp_input_delayed_close(pcb)) {
00476           goto aborted;
00477         }
00478 #if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
00479         while (recv_data != NULL) {
00480           struct pbuf *rest = NULL;
00481           pbuf_split_64k(recv_data, &rest);
00482 #else /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
00483         if (recv_data != NULL) {
00484 #endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
00485 
00486           LWIP_ASSERT("pcb->refused_data == NULL", pcb->refused_data == NULL);
00487           if (pcb->flags & TF_RXCLOSED) {
00488             /* received data although already closed -> abort (send RST) to
00489                notify the remote host that not all data has been processed */
00490             pbuf_free(recv_data);
00491 #if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
00492             if (rest != NULL) {
00493               pbuf_free(rest);
00494             }
00495 #endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
00496             tcp_abort(pcb);
00497             goto aborted;
00498           }
00499 
00500           /* Notify application that data has been received. */
00501           TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err);
00502           if (err == ERR_ABRT) {
00503 #if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
00504             if (rest != NULL) {
00505               pbuf_free(rest);
00506             }
00507 #endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
00508             goto aborted;
00509           }
00510 
00511           /* If the upper layer can't receive this data, store it */
00512           if (err != ERR_OK) {
00513 #if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
00514             if (rest != NULL) {
00515               pbuf_cat(recv_data, rest);
00516             }
00517 #endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
00518             pcb->refused_data = recv_data;
00519             LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: keep incoming packet, because pcb is \"full\"\n"));
00520 #if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
00521             break;
00522           } else {
00523             /* Upper layer received the data, go on with the rest if > 64K */
00524             recv_data = rest;
00525 #endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
00526           }
00527         }
00528 
00529         /* If a FIN segment was received, we call the callback
00530            function with a NULL buffer to indicate EOF. */
00531         if (recv_flags & TF_GOT_FIN) {
00532           if (pcb->refused_data != NULL) {
00533             /* Delay this if we have refused data. */
00534             pcb->refused_data->flags |= PBUF_FLAG_TCP_FIN;
00535           } else {
00536             /* correct rcv_wnd as the application won't call tcp_recved()
00537                for the FIN's seqno */
00538             if (pcb->rcv_wnd != TCP_WND_MAX(pcb)) {
00539               pcb->rcv_wnd++;
00540             }
00541             TCP_EVENT_CLOSED(pcb, err);
00542             if (err == ERR_ABRT) {
00543               goto aborted;
00544             }
00545           }
00546         }
00547 
00548         tcp_input_pcb = NULL;
00549         if (tcp_input_delayed_close(pcb)) {
00550           goto aborted;
00551         }
00552         /* Try to send something out. */
00553         tcp_output(pcb);
00554 #if TCP_INPUT_DEBUG
00555 #if TCP_DEBUG
00556         tcp_debug_print_state(pcb->state);
00557 #endif /* TCP_DEBUG */
00558 #endif /* TCP_INPUT_DEBUG */
00559       }
00560     }
00561     /* Jump target if pcb has been aborted in a callback (by calling tcp_abort()).
00562        Below this line, 'pcb' may not be dereferenced! */
00563 aborted:
00564     tcp_input_pcb = NULL;
00565     recv_data = NULL;
00566 
00567     /* give up our reference to inseg.p */
00568     if (inseg.p != NULL) {
00569       pbuf_free(inseg.p);
00570       inseg.p = NULL;
00571     }
00572   } else {
00573     /* If no matching PCB was found, send a TCP RST (reset) to the
00574        sender. */
00575     LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_input: no PCB match found, resetting.\n"));
00576     if (!(TCPH_FLAGS(tcphdr) & TCP_RST)) {
00577       TCP_STATS_INC(tcp.proterr);
00578       TCP_STATS_INC(tcp.drop);
00579       tcp_rst(NULL, ackno, seqno + tcplen, ip_current_dest_addr(),
00580               ip_current_src_addr(), tcphdr->dest, tcphdr->src);
00581     }
00582     pbuf_free(p);
00583   }
00584 
00585   LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane());
00586   PERF_STOP("tcp_input");
00587   return;
00588 dropped:
00589   TCP_STATS_INC(tcp.drop);
00590   MIB2_STATS_INC(mib2.tcpinerrs);
00591   pbuf_free(p);
00592 }
00593 
00594 /** Called from tcp_input to check for TF_CLOSED flag. This results in closing
00595  * and deallocating a pcb at the correct place to ensure noone references it
00596  * any more.
00597  * @returns 1 if the pcb has been closed and deallocated, 0 otherwise
00598  */
00599 static int
00600 tcp_input_delayed_close(struct tcp_pcb *pcb)
00601 {
00602   LWIP_ASSERT("tcp_input_delayed_close: invalid pcb", pcb != NULL);
00603 
00604   if (recv_flags & TF_CLOSED) {
00605     /* The connection has been closed and we will deallocate the
00606         PCB. */
00607     if (!(pcb->flags & TF_RXCLOSED)) {
00608       /* Connection closed although the application has only shut down the
00609           tx side: call the PCB's err callback and indicate the closure to
00610           ensure the application doesn't continue using the PCB. */
00611       TCP_EVENT_ERR(pcb->state, pcb->errf, pcb->callback_arg, ERR_CLSD);
00612     }
00613     tcp_pcb_remove(&tcp_active_pcbs, pcb);
00614     tcp_free(pcb);
00615     return 1;
00616   }
00617   return 0;
00618 }
00619 
00620 /**
00621  * Called by tcp_input() when a segment arrives for a listening
00622  * connection (from tcp_input()).
00623  *
00624  * @param pcb the tcp_pcb_listen for which a segment arrived
00625  *
00626  * @note the segment which arrived is saved in global variables, therefore only the pcb
00627  *       involved is passed as a parameter to this function
00628  */
00629 static void
00630 tcp_listen_input(struct tcp_pcb_listen *pcb)
00631 {
00632   struct tcp_pcb *npcb;
00633   u32_t iss;
00634   err_t rc;
00635 
00636   if (flags & TCP_RST) {
00637     /* An incoming RST should be ignored. Return. */
00638     return;
00639   }
00640 
00641   LWIP_ASSERT("tcp_listen_input: invalid pcb", pcb != NULL);
00642 
00643   /* In the LISTEN state, we check for incoming SYN segments,
00644      creates a new PCB, and responds with a SYN|ACK. */
00645   if (flags & TCP_ACK) {
00646     /* For incoming segments with the ACK flag set, respond with a
00647        RST. */
00648     LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_listen_input: ACK in LISTEN, sending reset\n"));
00649     tcp_rst((const struct tcp_pcb *)pcb, ackno, seqno + tcplen, ip_current_dest_addr(),
00650             ip_current_src_addr(), tcphdr->dest, tcphdr->src);
00651   } else if (flags & TCP_SYN) {
00652     LWIP_DEBUGF(TCP_DEBUG, ("TCP connection request %"U16_F" -> %"U16_F".\n", tcphdr->src, tcphdr->dest));
00653 #if TCP_LISTEN_BACKLOG
00654     if (pcb->accepts_pending >= pcb->backlog) {
00655       LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: listen backlog exceeded for port %"U16_F"\n", tcphdr->dest));
00656       return;
00657     }
00658 #endif /* TCP_LISTEN_BACKLOG */
00659     npcb = tcp_alloc(pcb->prio);
00660     /* If a new PCB could not be created (probably due to lack of memory),
00661        we don't do anything, but rely on the sender will retransmit the
00662        SYN at a time when we have more memory available. */
00663     if (npcb == NULL) {
00664       err_t err;
00665       LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: could not allocate PCB\n"));
00666       TCP_STATS_INC(tcp.memerr);
00667       TCP_EVENT_ACCEPT(pcb, NULL, pcb->callback_arg, ERR_MEM, err);
00668       LWIP_UNUSED_ARG(err); /* err not useful here */
00669       return;
00670     }
00671 #if TCP_LISTEN_BACKLOG
00672     pcb->accepts_pending++;
00673     tcp_set_flags(npcb, TF_BACKLOGPEND);
00674 #endif /* TCP_LISTEN_BACKLOG */
00675     /* Set up the new PCB. */
00676     ip_addr_copy(npcb->local_ip, *ip_current_dest_addr());
00677     ip_addr_copy(npcb->remote_ip, *ip_current_src_addr());
00678     npcb->local_port = pcb->local_port;
00679     npcb->remote_port = tcphdr->src;
00680     npcb->state = SYN_RCVD;
00681     npcb->rcv_nxt = seqno + 1;
00682     npcb->rcv_ann_right_edge = npcb->rcv_nxt;
00683     iss = tcp_next_iss(npcb);
00684     npcb->snd_wl2 = iss;
00685     npcb->snd_nxt = iss;
00686     npcb->lastack = iss;
00687     npcb->snd_lbb = iss;
00688     npcb->snd_wl1 = seqno - 1;/* initialise to seqno-1 to force window update */
00689     npcb->callback_arg = pcb->callback_arg;
00690 #if LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG
00691     npcb->listener = pcb;
00692 #endif /* LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG */
00693     /* inherit socket options */
00694     npcb->so_options = pcb->so_options & SOF_INHERITED;
00695     npcb->netif_idx = pcb->netif_idx;
00696     /* Register the new PCB so that we can begin receiving segments
00697        for it. */
00698     TCP_REG_ACTIVE(npcb);
00699 
00700     /* Parse any options in the SYN. */
00701     tcp_parseopt(npcb);
00702     npcb->snd_wnd = tcphdr->wnd;
00703     npcb->snd_wnd_max = npcb->snd_wnd;
00704 
00705 #if TCP_CALCULATE_EFF_SEND_MSS
00706     struct netif *netif;
00707     netif = netif_get_by_index(npcb->netif_idx);
00708     if(netif == NULL) {
00709       netif = ip_route(&npcb->local_ip, &npcb->remote_ip);
00710     }
00711     npcb->mss = tcp_eff_send_mss_netif(npcb->mss, netif, &npcb->remote_ip);
00712 #endif /* TCP_CALCULATE_EFF_SEND_MSS */
00713 
00714     MIB2_STATS_INC(mib2.tcppassiveopens);
00715 
00716 #if LWIP_TCP_PCB_NUM_EXT_ARGS
00717     if (tcp_ext_arg_invoke_callbacks_passive_open(pcb, npcb) != ERR_OK) {
00718       tcp_abandon(npcb, 0);
00719       return;
00720     }
00721 #endif
00722 
00723     /* Send a SYN|ACK together with the MSS option. */
00724     rc = tcp_enqueue_flags(npcb, TCP_SYN | TCP_ACK);
00725     if (rc != ERR_OK) {
00726       tcp_abandon(npcb, 0);
00727       return;
00728     }
00729     tcp_output(npcb);
00730   }
00731   return;
00732 }
00733 
00734 /**
00735  * Called by tcp_input() when a segment arrives for a connection in
00736  * TIME_WAIT.
00737  *
00738  * @param pcb the tcp_pcb for which a segment arrived
00739  *
00740  * @note the segment which arrived is saved in global variables, therefore only the pcb
00741  *       involved is passed as a parameter to this function
00742  */
00743 static void
00744 tcp_timewait_input(struct tcp_pcb *pcb)
00745 {
00746   /* RFC 1337: in TIME_WAIT, ignore RST and ACK FINs + any 'acceptable' segments */
00747   /* RFC 793 3.9 Event Processing - Segment Arrives:
00748    * - first check sequence number - we skip that one in TIME_WAIT (always
00749    *   acceptable since we only send ACKs)
00750    * - second check the RST bit (... return) */
00751   if (flags & TCP_RST) {
00752     return;
00753   }
00754 
00755   LWIP_ASSERT("tcp_timewait_input: invalid pcb", pcb != NULL);
00756 
00757   /* - fourth, check the SYN bit, */
00758   if (flags & TCP_SYN) {
00759     /* If an incoming segment is not acceptable, an acknowledgment
00760        should be sent in reply */
00761     if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd)) {
00762       /* If the SYN is in the window it is an error, send a reset */
00763       tcp_rst(pcb, ackno, seqno + tcplen, ip_current_dest_addr(),
00764               ip_current_src_addr(), tcphdr->dest, tcphdr->src);
00765       return;
00766     }
00767   } else if (flags & TCP_FIN) {
00768     /* - eighth, check the FIN bit: Remain in the TIME-WAIT state.
00769          Restart the 2 MSL time-wait timeout.*/
00770     pcb->tmr = tcp_ticks;
00771   }
00772 
00773   if ((tcplen > 0)) {
00774     /* Acknowledge data, FIN or out-of-window SYN */
00775     tcp_ack_now(pcb);
00776     tcp_output(pcb);
00777   }
00778   return;
00779 }
00780 
00781 /**
00782  * Implements the TCP state machine. Called by tcp_input. In some
00783  * states tcp_receive() is called to receive data. The tcp_seg
00784  * argument will be freed by the caller (tcp_input()) unless the
00785  * recv_data pointer in the pcb is set.
00786  *
00787  * @param pcb the tcp_pcb for which a segment arrived
00788  *
00789  * @note the segment which arrived is saved in global variables, therefore only the pcb
00790  *       involved is passed as a parameter to this function
00791  */
00792 static err_t
00793 tcp_process(struct tcp_pcb *pcb)
00794 {
00795   struct tcp_seg *rseg;
00796   u8_t acceptable = 0;
00797   err_t err;
00798 
00799   err = ERR_OK;
00800 
00801   LWIP_ASSERT("tcp_process: invalid pcb", pcb != NULL);
00802 
00803   /* Process incoming RST segments. */
00804   if (flags & TCP_RST) {
00805     /* First, determine if the reset is acceptable. */
00806     if (pcb->state == SYN_SENT) {
00807       /* "In the SYN-SENT state (a RST received in response to an initial SYN),
00808           the RST is acceptable if the ACK field acknowledges the SYN." */
00809       if (ackno == pcb->snd_nxt) {
00810         acceptable = 1;
00811       }
00812     } else {
00813       /* "In all states except SYN-SENT, all reset (RST) segments are validated
00814           by checking their SEQ-fields." */
00815       if (seqno == pcb->rcv_nxt) {
00816         acceptable = 1;
00817       } else  if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt,
00818                                   pcb->rcv_nxt + pcb->rcv_wnd)) {
00819         /* If the sequence number is inside the window, we send a challenge ACK
00820            and wait for a re-send with matching sequence number.
00821            This follows RFC 5961 section 3.2 and addresses CVE-2004-0230
00822            (RST spoofing attack), which is present in RFC 793 RST handling. */
00823         tcp_ack_now(pcb);
00824       }
00825     }
00826 
00827     if (acceptable) {
00828       LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: Connection RESET\n"));
00829       LWIP_ASSERT("tcp_input: pcb->state != CLOSED", pcb->state != CLOSED);
00830       recv_flags |= TF_RESET;
00831       tcp_clear_flags(pcb, TF_ACK_DELAY);
00832       return ERR_RST;
00833     } else {
00834       LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n",
00835                                     seqno, pcb->rcv_nxt));
00836       LWIP_DEBUGF(TCP_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n",
00837                               seqno, pcb->rcv_nxt));
00838       return ERR_OK;
00839     }
00840   }
00841 
00842   if ((flags & TCP_SYN) && (pcb->state != SYN_SENT && pcb->state != SYN_RCVD)) {
00843     /* Cope with new connection attempt after remote end crashed */
00844     tcp_ack_now(pcb);
00845     return ERR_OK;
00846   }
00847 
00848   if ((pcb->flags & TF_RXCLOSED) == 0) {
00849     /* Update the PCB (in)activity timer unless rx is closed (see tcp_shutdown) */
00850     pcb->tmr = tcp_ticks;
00851   }
00852   pcb->keep_cnt_sent = 0;
00853   pcb->persist_probe = 0;
00854 
00855   tcp_parseopt(pcb);
00856 
00857   /* Do different things depending on the TCP state. */
00858   switch (pcb->state) {
00859     case SYN_SENT:
00860       LWIP_DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %"U32_F" pcb->snd_nxt %"U32_F" unacked %"U32_F"\n", ackno,
00861                                     pcb->snd_nxt, lwip_ntohl(pcb->unacked->tcphdr->seqno)));
00862       /* received SYN ACK with expected sequence number? */
00863       if ((flags & TCP_ACK) && (flags & TCP_SYN)
00864           && (ackno == pcb->lastack + 1)) {
00865         pcb->rcv_nxt = seqno + 1;
00866         pcb->rcv_ann_right_edge = pcb->rcv_nxt;
00867         pcb->lastack = ackno;
00868         pcb->snd_wnd = tcphdr->wnd;
00869         pcb->snd_wnd_max = pcb->snd_wnd;
00870         pcb->snd_wl1 = seqno - 1; /* initialise to seqno - 1 to force window update */
00871         pcb->state = ESTABLISHED;
00872 
00873 #if TCP_CALCULATE_EFF_SEND_MSS
00874         struct netif *netif;
00875         netif = netif_get_by_index(pcb->netif_idx);
00876         if(netif == NULL) {
00877           netif = ip_route(&pcb->local_ip, &pcb->remote_ip);
00878         }
00879         pcb->mss = tcp_eff_send_mss_netif(pcb->mss, netif, &pcb->remote_ip);
00880 #endif /* TCP_CALCULATE_EFF_SEND_MSS */
00881 
00882         pcb->cwnd = LWIP_TCP_CALC_INITIAL_CWND(pcb->mss);
00883         LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_process (SENT): cwnd %"TCPWNDSIZE_F
00884                                      " ssthresh %"TCPWNDSIZE_F"\n",
00885                                      pcb->cwnd, pcb->ssthresh));
00886         LWIP_ASSERT("pcb->snd_queuelen > 0", (pcb->snd_queuelen > 0));
00887         --pcb->snd_queuelen;
00888         LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_process: SYN-SENT --queuelen %"TCPWNDSIZE_F"\n", (tcpwnd_size_t)pcb->snd_queuelen));
00889         rseg = pcb->unacked;
00890         if (rseg == NULL) {
00891           /* might happen if tcp_output fails in tcp_rexmit_rto()
00892              in which case the segment is on the unsent list */
00893           rseg = pcb->unsent;
00894           LWIP_ASSERT("no segment to free", rseg != NULL);
00895           pcb->unsent = rseg->next;
00896         } else {
00897           pcb->unacked = rseg->next;
00898         }
00899         tcp_seg_free(rseg);
00900 
00901         /* If there's nothing left to acknowledge, stop the retransmit
00902            timer, otherwise reset it to start again */
00903         if (pcb->unacked == NULL) {
00904           pcb->rtime = -1;
00905         } else {
00906           pcb->rtime = 0;
00907           pcb->nrtx = 0;
00908         }
00909 
00910         /* Call the user specified function to call when successfully
00911          * connected. */
00912         TCP_EVENT_CONNECTED(pcb, ERR_OK, err);
00913         if (err == ERR_ABRT) {
00914           return ERR_ABRT;
00915         }
00916         tcp_ack_now(pcb);
00917       }
00918       /* received ACK? possibly a half-open connection */
00919       else if (flags & TCP_ACK) {
00920         /* send a RST to bring the other side in a non-synchronized state. */
00921         tcp_rst(pcb, ackno, seqno + tcplen, ip_current_dest_addr(),
00922                 ip_current_src_addr(), tcphdr->dest, tcphdr->src);
00923         /* Resend SYN immediately (don't wait for rto timeout) to establish
00924           connection faster, but do not send more SYNs than we otherwise would
00925           have, or we might get caught in a loop on loopback interfaces. */
00926         if (pcb->nrtx < TCP_SYNMAXRTX) {
00927           pcb->rtime = 0;
00928           tcp_rexmit_rto(pcb);
00929         }
00930       }
00931       break;
00932     case SYN_RCVD:
00933       if (flags & TCP_ACK) {
00934         /* expected ACK number? */
00935         if (TCP_SEQ_BETWEEN(ackno, pcb->lastack + 1, pcb->snd_nxt)) {
00936           pcb->state = ESTABLISHED;
00937           LWIP_DEBUGF(TCP_DEBUG, ("TCP connection established %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
00938 #if LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG
00939           if (pcb->listener == NULL) {
00940             /* listen pcb might be closed by now */
00941             err = ERR_VAL;
00942           } else
00943 #endif /* LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG */
00944           {
00945 #if LWIP_CALLBACK_API
00946             LWIP_ASSERT("pcb->listener->accept != NULL", pcb->listener->accept != NULL);
00947 #endif
00948             tcp_backlog_accepted(pcb);
00949             /* Call the accept function. */
00950             TCP_EVENT_ACCEPT(pcb->listener, pcb, pcb->callback_arg, ERR_OK, err);
00951           }
00952           if (err != ERR_OK) {
00953             /* If the accept function returns with an error, we abort
00954              * the connection. */
00955             /* Already aborted? */
00956             if (err != ERR_ABRT) {
00957               tcp_abort(pcb);
00958             }
00959             return ERR_ABRT;
00960           }
00961           /* If there was any data contained within this ACK,
00962            * we'd better pass it on to the application as well. */
00963           tcp_receive(pcb);
00964 
00965           /* Prevent ACK for SYN to generate a sent event */
00966           if (recv_acked != 0) {
00967             recv_acked--;
00968           }
00969 
00970           pcb->cwnd = LWIP_TCP_CALC_INITIAL_CWND(pcb->mss);
00971           LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_process (SYN_RCVD): cwnd %"TCPWNDSIZE_F
00972                                        " ssthresh %"TCPWNDSIZE_F"\n",
00973                                        pcb->cwnd, pcb->ssthresh));
00974 
00975           if (recv_flags & TF_GOT_FIN) {
00976             tcp_ack_now(pcb);
00977             pcb->state = CLOSE_WAIT;
00978           }
00979         } else {
00980           /* incorrect ACK number, send RST */
00981           tcp_rst(pcb, ackno, seqno + tcplen, ip_current_dest_addr(),
00982                   ip_current_src_addr(), tcphdr->dest, tcphdr->src);
00983         }
00984       } else if ((flags & TCP_SYN) && (seqno == pcb->rcv_nxt - 1)) {
00985         /* Looks like another copy of the SYN - retransmit our SYN-ACK */
00986         tcp_rexmit(pcb);
00987       }
00988       break;
00989     case CLOSE_WAIT:
00990     /* FALLTHROUGH */
00991     case ESTABLISHED:
00992       tcp_receive(pcb);
00993       if (recv_flags & TF_GOT_FIN) { /* passive close */
00994         tcp_ack_now(pcb);
00995         pcb->state = CLOSE_WAIT;
00996       }
00997       break;
00998     case FIN_WAIT_1:
00999       tcp_receive(pcb);
01000       if (recv_flags & TF_GOT_FIN) {
01001         if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt) &&
01002             pcb->unsent == NULL) {
01003           LWIP_DEBUGF(TCP_DEBUG,
01004                       ("TCP connection closed: FIN_WAIT_1 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
01005           tcp_ack_now(pcb);
01006           tcp_pcb_purge(pcb);
01007           TCP_RMV_ACTIVE(pcb);
01008           pcb->state = TIME_WAIT;
01009           TCP_REG(&tcp_tw_pcbs, pcb);
01010         } else {
01011           tcp_ack_now(pcb);
01012           pcb->state = CLOSING;
01013         }
01014       } else if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt) &&
01015                  pcb->unsent == NULL) {
01016         pcb->state = FIN_WAIT_2;
01017       }
01018       break;
01019     case FIN_WAIT_2:
01020       tcp_receive(pcb);
01021       if (recv_flags & TF_GOT_FIN) {
01022         LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: FIN_WAIT_2 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
01023         tcp_ack_now(pcb);
01024         tcp_pcb_purge(pcb);
01025         TCP_RMV_ACTIVE(pcb);
01026         pcb->state = TIME_WAIT;
01027         TCP_REG(&tcp_tw_pcbs, pcb);
01028       }
01029       break;
01030     case CLOSING:
01031       tcp_receive(pcb);
01032       if ((flags & TCP_ACK) && ackno == pcb->snd_nxt && pcb->unsent == NULL) {
01033         LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: CLOSING %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
01034         tcp_pcb_purge(pcb);
01035         TCP_RMV_ACTIVE(pcb);
01036         pcb->state = TIME_WAIT;
01037         TCP_REG(&tcp_tw_pcbs, pcb);
01038       }
01039       break;
01040     case LAST_ACK:
01041       tcp_receive(pcb);
01042       if ((flags & TCP_ACK) && ackno == pcb->snd_nxt && pcb->unsent == NULL) {
01043         LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: LAST_ACK %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
01044         /* bugfix #21699: don't set pcb->state to CLOSED here or we risk leaking segments */
01045         recv_flags |= TF_CLOSED;
01046       }
01047       break;
01048     default:
01049       break;
01050   }
01051   return ERR_OK;
01052 }
01053 
01054 #if TCP_QUEUE_OOSEQ
01055 /**
01056  * Insert segment into the list (segments covered with new one will be deleted)
01057  *
01058  * Called from tcp_receive()
01059  */
01060 static void
01061 tcp_oos_insert_segment(struct tcp_seg *cseg, struct tcp_seg *next)
01062 {
01063   struct tcp_seg *old_seg;
01064 
01065   LWIP_ASSERT("tcp_oos_insert_segment: invalid cseg", cseg != NULL);
01066 
01067   if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) {
01068     /* received segment overlaps all following segments */
01069     tcp_segs_free(next);
01070     next = NULL;
01071   } else {
01072     /* delete some following segments
01073        oos queue may have segments with FIN flag */
01074     while (next &&
01075            TCP_SEQ_GEQ((seqno + cseg->len),
01076                        (next->tcphdr->seqno + next->len))) {
01077       /* cseg with FIN already processed */
01078       if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) {
01079         TCPH_SET_FLAG(cseg->tcphdr, TCP_FIN);
01080       }
01081       old_seg = next;
01082       next = next->next;
01083       tcp_seg_free(old_seg);
01084     }
01085     if (next &&
01086         TCP_SEQ_GT(seqno + cseg->len, next->tcphdr->seqno)) {
01087       /* We need to trim the incoming segment. */
01088       cseg->len = (u16_t)(next->tcphdr->seqno - seqno);
01089       pbuf_realloc(cseg->p, cseg->len);
01090     }
01091   }
01092   cseg->next = next;
01093 }
01094 #endif /* TCP_QUEUE_OOSEQ */
01095 
01096 /** Remove segments from a list if the incoming ACK acknowledges them */
01097 static struct tcp_seg *
01098 tcp_free_acked_segments(struct tcp_pcb *pcb, struct tcp_seg *seg_list, const char *dbg_list_name,
01099                         struct tcp_seg *dbg_other_seg_list)
01100 {
01101   struct tcp_seg *next;
01102   u16_t clen;
01103 
01104   LWIP_UNUSED_ARG(dbg_list_name);
01105   LWIP_UNUSED_ARG(dbg_other_seg_list);
01106 
01107   while (seg_list != NULL &&
01108          TCP_SEQ_LEQ(lwip_ntohl(seg_list->tcphdr->seqno) +
01109                      TCP_TCPLEN(seg_list), ackno)) {
01110     LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->%s\n",
01111                                   lwip_ntohl(seg_list->tcphdr->seqno),
01112                                   lwip_ntohl(seg_list->tcphdr->seqno) + TCP_TCPLEN(seg_list),
01113                                   dbg_list_name));
01114 
01115     next = seg_list;
01116     seg_list = seg_list->next;
01117 
01118     clen = pbuf_clen(next->p);
01119     LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"TCPWNDSIZE_F" ... ",
01120                                  (tcpwnd_size_t)pcb->snd_queuelen));
01121     LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= clen));
01122 
01123     pcb->snd_queuelen = (u16_t)(pcb->snd_queuelen - clen);
01124     recv_acked = (tcpwnd_size_t)(recv_acked + next->len);
01125     tcp_seg_free(next);
01126 
01127     LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"TCPWNDSIZE_F" (after freeing %s)\n",
01128                                  (tcpwnd_size_t)pcb->snd_queuelen,
01129                                  dbg_list_name));
01130     if (pcb->snd_queuelen != 0) {
01131       LWIP_ASSERT("tcp_receive: valid queue length",
01132                   seg_list != NULL || dbg_other_seg_list != NULL);
01133     }
01134   }
01135   return seg_list;
01136 }
01137 
01138 /**
01139  * Called by tcp_process. Checks if the given segment is an ACK for outstanding
01140  * data, and if so frees the memory of the buffered data. Next, it places the
01141  * segment on any of the receive queues (pcb->recved or pcb->ooseq). If the segment
01142  * is buffered, the pbuf is referenced by pbuf_ref so that it will not be freed until
01143  * it has been removed from the buffer.
01144  *
01145  * If the incoming segment constitutes an ACK for a segment that was used for RTT
01146  * estimation, the RTT is estimated here as well.
01147  *
01148  * Called from tcp_process().
01149  */
01150 static void
01151 tcp_receive(struct tcp_pcb *pcb)
01152 {
01153   s16_t m;
01154   u32_t right_wnd_edge;
01155   int found_dupack = 0;
01156 
01157   LWIP_ASSERT("tcp_receive: invalid pcb", pcb != NULL);
01158   LWIP_ASSERT("tcp_receive: wrong state", pcb->state >= ESTABLISHED);
01159 
01160   if (flags & TCP_ACK) {
01161     right_wnd_edge = pcb->snd_wnd + pcb->snd_wl2;
01162 
01163     /* Update window. */
01164     if (TCP_SEQ_LT(pcb->snd_wl1, seqno) ||
01165         (pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) ||
01166         (pcb->snd_wl2 == ackno && (u32_t)SND_WND_SCALE(pcb, tcphdr->wnd) > pcb->snd_wnd)) {
01167       pcb->snd_wnd = SND_WND_SCALE(pcb, tcphdr->wnd);
01168       /* keep track of the biggest window announced by the remote host to calculate
01169          the maximum segment size */
01170       if (pcb->snd_wnd_max < pcb->snd_wnd) {
01171         pcb->snd_wnd_max = pcb->snd_wnd;
01172       }
01173       pcb->snd_wl1 = seqno;
01174       pcb->snd_wl2 = ackno;
01175       LWIP_DEBUGF(TCP_WND_DEBUG, ("tcp_receive: window update %"TCPWNDSIZE_F"\n", pcb->snd_wnd));
01176 #if TCP_WND_DEBUG
01177     } else {
01178       if (pcb->snd_wnd != (tcpwnd_size_t)SND_WND_SCALE(pcb, tcphdr->wnd)) {
01179         LWIP_DEBUGF(TCP_WND_DEBUG,
01180                     ("tcp_receive: no window update lastack %"U32_F" ackno %"
01181                      U32_F" wl1 %"U32_F" seqno %"U32_F" wl2 %"U32_F"\n",
01182                      pcb->lastack, ackno, pcb->snd_wl1, seqno, pcb->snd_wl2));
01183       }
01184 #endif /* TCP_WND_DEBUG */
01185     }
01186 
01187     /* (From Stevens TCP/IP Illustrated Vol II, p970.) Its only a
01188      * duplicate ack if:
01189      * 1) It doesn't ACK new data
01190      * 2) length of received packet is zero (i.e. no payload)
01191      * 3) the advertised window hasn't changed
01192      * 4) There is outstanding unacknowledged data (retransmission timer running)
01193      * 5) The ACK is == biggest ACK sequence number so far seen (snd_una)
01194      *
01195      * If it passes all five, should process as a dupack:
01196      * a) dupacks < 3: do nothing
01197      * b) dupacks == 3: fast retransmit
01198      * c) dupacks > 3: increase cwnd
01199      *
01200      * If it only passes 1-3, should reset dupack counter (and add to
01201      * stats, which we don't do in lwIP)
01202      *
01203      * If it only passes 1, should reset dupack counter
01204      *
01205      */
01206 
01207     /* Clause 1 */
01208     if (TCP_SEQ_LEQ(ackno, pcb->lastack)) {
01209       /* Clause 2 */
01210       if (tcplen == 0) {
01211         /* Clause 3 */
01212         if (pcb->snd_wl2 + pcb->snd_wnd == right_wnd_edge) {
01213           /* Clause 4 */
01214           if (pcb->rtime >= 0) {
01215             /* Clause 5 */
01216             if (pcb->lastack == ackno) {
01217               found_dupack = 1;
01218               if ((u8_t)(pcb->dupacks + 1) > pcb->dupacks) {
01219                 ++pcb->dupacks;
01220               }
01221               if (pcb->dupacks > 3) {
01222                 /* Inflate the congestion window */
01223                 TCP_WND_INC(pcb->cwnd, pcb->mss);
01224               }
01225               if (pcb->dupacks >= 3) {
01226                 /* Do fast retransmit (checked via TF_INFR, not via dupacks count) */
01227                 tcp_rexmit_fast(pcb);
01228               }
01229             }
01230           }
01231         }
01232       }
01233       /* If Clause (1) or more is true, but not a duplicate ack, reset
01234        * count of consecutive duplicate acks */
01235       if (!found_dupack) {
01236         pcb->dupacks = 0;
01237       }
01238     } else if (TCP_SEQ_BETWEEN(ackno, pcb->lastack + 1, pcb->snd_nxt)) {
01239       /* We come here when the ACK acknowledges new data. */
01240       tcpwnd_size_t acked;
01241 
01242       /* Reset the "IN Fast Retransmit" flag, since we are no longer
01243          in fast retransmit. Also reset the congestion window to the
01244          slow start threshold. */
01245       if (pcb->flags & TF_INFR) {
01246         tcp_clear_flags(pcb, TF_INFR);
01247         pcb->cwnd = pcb->ssthresh;
01248         pcb->bytes_acked = 0;
01249       }
01250 
01251       /* Reset the number of retransmissions. */
01252       pcb->nrtx = 0;
01253 
01254       /* Reset the retransmission time-out. */
01255       pcb->rto = (s16_t)((pcb->sa >> 3) + pcb->sv);
01256 
01257       /* Record how much data this ACK acks */
01258       acked = (tcpwnd_size_t)(ackno - pcb->lastack);
01259 
01260       /* Reset the fast retransmit variables. */
01261       pcb->dupacks = 0;
01262       pcb->lastack = ackno;
01263 
01264       /* Update the congestion control variables (cwnd and
01265          ssthresh). */
01266       if (pcb->state >= ESTABLISHED) {
01267         if (pcb->cwnd < pcb->ssthresh) {
01268           tcpwnd_size_t increase;
01269           /* limit to 1 SMSS segment during period following RTO */
01270           u8_t num_seg = (pcb->flags & TF_RTO) ? 1 : 2;
01271           /* RFC 3465, section 2.2 Slow Start */
01272           increase = LWIP_MIN(acked, (tcpwnd_size_t)(num_seg * pcb->mss));
01273           TCP_WND_INC(pcb->cwnd, increase);
01274           LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: slow start cwnd %"TCPWNDSIZE_F"\n", pcb->cwnd));
01275         } else {
01276           /* RFC 3465, section 2.1 Congestion Avoidance */
01277           TCP_WND_INC(pcb->bytes_acked, acked);
01278           if (pcb->bytes_acked >= pcb->cwnd) {
01279             pcb->bytes_acked = (tcpwnd_size_t)(pcb->bytes_acked - pcb->cwnd);
01280             TCP_WND_INC(pcb->cwnd, pcb->mss);
01281           }
01282           LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: congestion avoidance cwnd %"TCPWNDSIZE_F"\n", pcb->cwnd));
01283         }
01284       }
01285       LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: ACK for %"U32_F", unacked->seqno %"U32_F":%"U32_F"\n",
01286                                     ackno,
01287                                     pcb->unacked != NULL ?
01288                                     lwip_ntohl(pcb->unacked->tcphdr->seqno) : 0,
01289                                     pcb->unacked != NULL ?
01290                                     lwip_ntohl(pcb->unacked->tcphdr->seqno) + TCP_TCPLEN(pcb->unacked) : 0));
01291 
01292       /* Remove segment from the unacknowledged list if the incoming
01293          ACK acknowledges them. */
01294       pcb->unacked = tcp_free_acked_segments(pcb, pcb->unacked, "unacked", pcb->unsent);
01295       /* We go through the ->unsent list to see if any of the segments
01296          on the list are acknowledged by the ACK. This may seem
01297          strange since an "unsent" segment shouldn't be acked. The
01298          rationale is that lwIP puts all outstanding segments on the
01299          ->unsent list after a retransmission, so these segments may
01300          in fact have been sent once. */
01301       pcb->unsent = tcp_free_acked_segments(pcb, pcb->unsent, "unsent", pcb->unacked);
01302 
01303       /* If there's nothing left to acknowledge, stop the retransmit
01304          timer, otherwise reset it to start again */
01305       if (pcb->unacked == NULL) {
01306         pcb->rtime = -1;
01307       } else {
01308         pcb->rtime = 0;
01309       }
01310 
01311       pcb->polltmr = 0;
01312 
01313 #if TCP_OVERSIZE
01314       if (pcb->unsent == NULL) {
01315         pcb->unsent_oversize = 0;
01316       }
01317 #endif /* TCP_OVERSIZE */
01318 
01319 #if LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS
01320       if (ip_current_is_v6()) {
01321         /* Inform neighbor reachability of forward progress. */
01322         nd6_reachability_hint(ip6_current_src_addr());
01323       }
01324 #endif /* LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS*/
01325 
01326       pcb->snd_buf = (tcpwnd_size_t)(pcb->snd_buf + recv_acked);
01327       /* check if this ACK ends our retransmission of in-flight data */
01328       if (pcb->flags & TF_RTO) {
01329         /* RTO is done if
01330             1) both queues are empty or
01331             2) unacked is empty and unsent head contains data not part of RTO or
01332             3) unacked head contains data not part of RTO */
01333         if (pcb->unacked == NULL) {
01334           if ((pcb->unsent == NULL) ||
01335               (TCP_SEQ_LEQ(pcb->rto_end, lwip_ntohl(pcb->unsent->tcphdr->seqno)))) {
01336             tcp_clear_flags(pcb, TF_RTO);
01337           }
01338         } else if (TCP_SEQ_LEQ(pcb->rto_end, lwip_ntohl(pcb->unacked->tcphdr->seqno))) {
01339           tcp_clear_flags(pcb, TF_RTO);
01340         }
01341       }
01342       /* End of ACK for new data processing. */
01343     } else {
01344       /* Out of sequence ACK, didn't really ack anything */
01345       tcp_send_empty_ack(pcb);
01346     }
01347 
01348     LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: pcb->rttest %"U32_F" rtseq %"U32_F" ackno %"U32_F"\n",
01349                                 pcb->rttest, pcb->rtseq, ackno));
01350 
01351     /* RTT estimation calculations. This is done by checking if the
01352        incoming segment acknowledges the segment we use to take a
01353        round-trip time measurement. */
01354     if (pcb->rttest && TCP_SEQ_LT(pcb->rtseq, ackno)) {
01355       /* diff between this shouldn't exceed 32K since this are tcp timer ticks
01356          and a round-trip shouldn't be that long... */
01357       m = (s16_t)(tcp_ticks - pcb->rttest);
01358 
01359       LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: experienced rtt %"U16_F" ticks (%"U16_F" msec).\n",
01360                                   m, (u16_t)(m * TCP_SLOW_INTERVAL)));
01361 
01362       /* This is taken directly from VJs original code in his paper */
01363       m = (s16_t)(m - (pcb->sa >> 3));
01364       pcb->sa = (s16_t)(pcb->sa + m);
01365       if (m < 0) {
01366         m = (s16_t) - m;
01367       }
01368       m = (s16_t)(m - (pcb->sv >> 2));
01369       pcb->sv = (s16_t)(pcb->sv + m);
01370       pcb->rto = (s16_t)((pcb->sa >> 3) + pcb->sv);
01371 
01372       LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: RTO %"U16_F" (%"U16_F" milliseconds)\n",
01373                                   pcb->rto, (u16_t)(pcb->rto * TCP_SLOW_INTERVAL)));
01374 
01375       pcb->rttest = 0;
01376     }
01377   }
01378 
01379   /* If the incoming segment contains data, we must process it
01380      further unless the pcb already received a FIN.
01381      (RFC 793, chapter 3.9, "SEGMENT ARRIVES" in states CLOSE-WAIT, CLOSING,
01382      LAST-ACK and TIME-WAIT: "Ignore the segment text.") */
01383   if ((tcplen > 0) && (pcb->state < CLOSE_WAIT)) {
01384     /* This code basically does three things:
01385 
01386     +) If the incoming segment contains data that is the next
01387     in-sequence data, this data is passed to the application. This
01388     might involve trimming the first edge of the data. The rcv_nxt
01389     variable and the advertised window are adjusted.
01390 
01391     +) If the incoming segment has data that is above the next
01392     sequence number expected (->rcv_nxt), the segment is placed on
01393     the ->ooseq queue. This is done by finding the appropriate
01394     place in the ->ooseq queue (which is ordered by sequence
01395     number) and trim the segment in both ends if needed. An
01396     immediate ACK is sent to indicate that we received an
01397     out-of-sequence segment.
01398 
01399     +) Finally, we check if the first segment on the ->ooseq queue
01400     now is in sequence (i.e., if rcv_nxt >= ooseq->seqno). If
01401     rcv_nxt > ooseq->seqno, we must trim the first edge of the
01402     segment on ->ooseq before we adjust rcv_nxt. The data in the
01403     segments that are now on sequence are chained onto the
01404     incoming segment so that we only need to call the application
01405     once.
01406     */
01407 
01408     /* First, we check if we must trim the first edge. We have to do
01409        this if the sequence number of the incoming segment is less
01410        than rcv_nxt, and the sequence number plus the length of the
01411        segment is larger than rcv_nxt. */
01412     /*    if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)) {
01413           if (TCP_SEQ_LT(pcb->rcv_nxt, seqno + tcplen)) {*/
01414     if (TCP_SEQ_BETWEEN(pcb->rcv_nxt, seqno + 1, seqno + tcplen - 1)) {
01415       /* Trimming the first edge is done by pushing the payload
01416          pointer in the pbuf downwards. This is somewhat tricky since
01417          we do not want to discard the full contents of the pbuf up to
01418          the new starting point of the data since we have to keep the
01419          TCP header which is present in the first pbuf in the chain.
01420 
01421          What is done is really quite a nasty hack: the first pbuf in
01422          the pbuf chain is pointed to by inseg.p. Since we need to be
01423          able to deallocate the whole pbuf, we cannot change this
01424          inseg.p pointer to point to any of the later pbufs in the
01425          chain. Instead, we point the ->payload pointer in the first
01426          pbuf to data in one of the later pbufs. We also set the
01427          inseg.data pointer to point to the right place. This way, the
01428          ->p pointer will still point to the first pbuf, but the
01429          ->p->payload pointer will point to data in another pbuf.
01430 
01431          After we are done with adjusting the pbuf pointers we must
01432          adjust the ->data pointer in the seg and the segment
01433          length.*/
01434 
01435       struct pbuf *p = inseg.p;
01436       u32_t off32 = pcb->rcv_nxt - seqno;
01437       u16_t new_tot_len, off;
01438       LWIP_ASSERT("inseg.p != NULL", inseg.p);
01439       LWIP_ASSERT("insane offset!", (off32 < 0xffff));
01440       off = (u16_t)off32;
01441       LWIP_ASSERT("pbuf too short!", (((s32_t)inseg.p->tot_len) >= off));
01442       inseg.len -= off;
01443       new_tot_len = (u16_t)(inseg.p->tot_len - off);
01444       while (p->len < off) {
01445         off -= p->len;
01446         /* all pbufs up to and including this one have len==0, so tot_len is equal */
01447         p->tot_len = new_tot_len;
01448         p->len = 0;
01449         p = p->next;
01450       }
01451       /* cannot fail... */
01452       pbuf_remove_header(p, off);
01453       inseg.tcphdr->seqno = seqno = pcb->rcv_nxt;
01454     } else {
01455       if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)) {
01456         /* the whole segment is < rcv_nxt */
01457         /* must be a duplicate of a packet that has already been correctly handled */
01458 
01459         LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: duplicate seqno %"U32_F"\n", seqno));
01460         tcp_ack_now(pcb);
01461       }
01462     }
01463 
01464     /* The sequence number must be within the window (above rcv_nxt
01465        and below rcv_nxt + rcv_wnd) in order to be further
01466        processed. */
01467     if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt,
01468                         pcb->rcv_nxt + pcb->rcv_wnd - 1)) {
01469       if (pcb->rcv_nxt == seqno) {
01470         /* The incoming segment is the next in sequence. We check if
01471            we have to trim the end of the segment and update rcv_nxt
01472            and pass the data to the application. */
01473         tcplen = TCP_TCPLEN(&inseg);
01474 
01475         if (tcplen > pcb->rcv_wnd) {
01476           LWIP_DEBUGF(TCP_INPUT_DEBUG,
01477                       ("tcp_receive: other end overran receive window"
01478                        "seqno %"U32_F" len %"U16_F" right edge %"U32_F"\n",
01479                        seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd));
01480           if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
01481             /* Must remove the FIN from the header as we're trimming
01482              * that byte of sequence-space from the packet */
01483             TCPH_FLAGS_SET(inseg.tcphdr, TCPH_FLAGS(inseg.tcphdr) & ~(unsigned int)TCP_FIN);
01484           }
01485           /* Adjust length of segment to fit in the window. */
01486           TCPWND_CHECK16(pcb->rcv_wnd);
01487           inseg.len = (u16_t)pcb->rcv_wnd;
01488           if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) {
01489             inseg.len -= 1;
01490           }
01491           pbuf_realloc(inseg.p, inseg.len);
01492           tcplen = TCP_TCPLEN(&inseg);
01493           LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n",
01494                       (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd));
01495         }
01496 #if TCP_QUEUE_OOSEQ
01497         /* Received in-sequence data, adjust ooseq data if:
01498            - FIN has been received or
01499            - inseq overlaps with ooseq */
01500         if (pcb->ooseq != NULL) {
01501           if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
01502             LWIP_DEBUGF(TCP_INPUT_DEBUG,
01503                         ("tcp_receive: received in-order FIN, binning ooseq queue\n"));
01504             /* Received in-order FIN means anything that was received
01505              * out of order must now have been received in-order, so
01506              * bin the ooseq queue */
01507             while (pcb->ooseq != NULL) {
01508               struct tcp_seg *old_ooseq = pcb->ooseq;
01509               pcb->ooseq = pcb->ooseq->next;
01510               tcp_seg_free(old_ooseq);
01511             }
01512           } else {
01513             struct tcp_seg *next = pcb->ooseq;
01514             /* Remove all segments on ooseq that are covered by inseg already.
01515              * FIN is copied from ooseq to inseg if present. */
01516             while (next &&
01517                    TCP_SEQ_GEQ(seqno + tcplen,
01518                                next->tcphdr->seqno + next->len)) {
01519               struct tcp_seg *tmp;
01520               /* inseg cannot have FIN here (already processed above) */
01521               if ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0 &&
01522                   (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) == 0) {
01523                 TCPH_SET_FLAG(inseg.tcphdr, TCP_FIN);
01524                 tcplen = TCP_TCPLEN(&inseg);
01525               }
01526               tmp = next;
01527               next = next->next;
01528               tcp_seg_free(tmp);
01529             }
01530             /* Now trim right side of inseg if it overlaps with the first
01531              * segment on ooseq */
01532             if (next &&
01533                 TCP_SEQ_GT(seqno + tcplen,
01534                            next->tcphdr->seqno)) {
01535               /* inseg cannot have FIN here (already processed above) */
01536               inseg.len = (u16_t)(next->tcphdr->seqno - seqno);
01537               if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) {
01538                 inseg.len -= 1;
01539               }
01540               pbuf_realloc(inseg.p, inseg.len);
01541               tcplen = TCP_TCPLEN(&inseg);
01542               LWIP_ASSERT("tcp_receive: segment not trimmed correctly to ooseq queue\n",
01543                           (seqno + tcplen) == next->tcphdr->seqno);
01544             }
01545             pcb->ooseq = next;
01546           }
01547         }
01548 #endif /* TCP_QUEUE_OOSEQ */
01549 
01550         pcb->rcv_nxt = seqno + tcplen;
01551 
01552         /* Update the receiver's (our) window. */
01553         LWIP_ASSERT("tcp_receive: tcplen > rcv_wnd\n", pcb->rcv_wnd >= tcplen);
01554         pcb->rcv_wnd -= tcplen;
01555 
01556         tcp_update_rcv_ann_wnd(pcb);
01557 
01558         /* If there is data in the segment, we make preparations to
01559            pass this up to the application. The ->recv_data variable
01560            is used for holding the pbuf that goes to the
01561            application. The code for reassembling out-of-sequence data
01562            chains its data on this pbuf as well.
01563 
01564            If the segment was a FIN, we set the TF_GOT_FIN flag that will
01565            be used to indicate to the application that the remote side has
01566            closed its end of the connection. */
01567         if (inseg.p->tot_len > 0) {
01568           recv_data = inseg.p;
01569           /* Since this pbuf now is the responsibility of the
01570              application, we delete our reference to it so that we won't
01571              (mistakingly) deallocate it. */
01572           inseg.p = NULL;
01573         }
01574         if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
01575           LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN.\n"));
01576           recv_flags |= TF_GOT_FIN;
01577         }
01578 
01579 #if TCP_QUEUE_OOSEQ
01580         /* We now check if we have segments on the ->ooseq queue that
01581            are now in sequence. */
01582         while (pcb->ooseq != NULL &&
01583                pcb->ooseq->tcphdr->seqno == pcb->rcv_nxt) {
01584 
01585           struct tcp_seg *cseg = pcb->ooseq;
01586           seqno = pcb->ooseq->tcphdr->seqno;
01587 
01588           pcb->rcv_nxt += TCP_TCPLEN(cseg);
01589           LWIP_ASSERT("tcp_receive: ooseq tcplen > rcv_wnd\n",
01590                       pcb->rcv_wnd >= TCP_TCPLEN(cseg));
01591           pcb->rcv_wnd -= TCP_TCPLEN(cseg);
01592 
01593           tcp_update_rcv_ann_wnd(pcb);
01594 
01595           if (cseg->p->tot_len > 0) {
01596             /* Chain this pbuf onto the pbuf that we will pass to
01597                the application. */
01598             /* With window scaling, this can overflow recv_data->tot_len, but
01599                that's not a problem since we explicitly fix that before passing
01600                recv_data to the application. */
01601             if (recv_data) {
01602               pbuf_cat(recv_data, cseg->p);
01603             } else {
01604               recv_data = cseg->p;
01605             }
01606             cseg->p = NULL;
01607           }
01608           if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) {
01609             LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN.\n"));
01610             recv_flags |= TF_GOT_FIN;
01611             if (pcb->state == ESTABLISHED) { /* force passive close or we can move to active close */
01612               pcb->state = CLOSE_WAIT;
01613             }
01614           }
01615 
01616           pcb->ooseq = cseg->next;
01617           tcp_seg_free(cseg);
01618         }
01619 #if LWIP_TCP_SACK_OUT
01620         if (pcb->flags & TF_SACK) {
01621           if (pcb->ooseq != NULL) {
01622             /* Some segments may have been removed from ooseq, let's remove all SACKs that
01623                describe anything before the new beginning of that list. */
01624             tcp_remove_sacks_lt(pcb, pcb->ooseq->tcphdr->seqno);
01625           } else if (LWIP_TCP_SACK_VALID(pcb, 0)) {
01626             /* ooseq has been cleared. Nothing to SACK */
01627             memset(pcb->rcv_sacks, 0, sizeof(pcb->rcv_sacks));
01628           }
01629         }
01630 #endif /* LWIP_TCP_SACK_OUT */
01631 #endif /* TCP_QUEUE_OOSEQ */
01632 
01633 
01634         /* Acknowledge the segment(s). */
01635         tcp_ack(pcb);
01636 
01637 #if LWIP_TCP_SACK_OUT
01638         if (LWIP_TCP_SACK_VALID(pcb, 0)) {
01639           /* Normally the ACK for the data received could be piggy-backed on a data packet,
01640              but lwIP currently does not support including SACKs in data packets. So we force
01641              it to respond with an empty ACK packet (only if there is at least one SACK to be sent).
01642              NOTE: tcp_send_empty_ack() on success clears the ACK flags (set by tcp_ack()) */
01643           tcp_send_empty_ack(pcb);
01644         }
01645 #endif /* LWIP_TCP_SACK_OUT */
01646 
01647 #if LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS
01648         if (ip_current_is_v6()) {
01649           /* Inform neighbor reachability of forward progress. */
01650           nd6_reachability_hint(ip6_current_src_addr());
01651         }
01652 #endif /* LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS*/
01653 
01654       } else {
01655         /* We get here if the incoming segment is out-of-sequence. */
01656 
01657 #if TCP_QUEUE_OOSEQ
01658         /* We queue the segment on the ->ooseq queue. */
01659         if (pcb->ooseq == NULL) {
01660           pcb->ooseq = tcp_seg_copy(&inseg);
01661 #if LWIP_TCP_SACK_OUT
01662           if (pcb->flags & TF_SACK) {
01663             /* All the SACKs should be invalid, so we can simply store the most recent one: */
01664             pcb->rcv_sacks[0].left = seqno;
01665             pcb->rcv_sacks[0].right = seqno + inseg.len;
01666           }
01667 #endif /* LWIP_TCP_SACK_OUT */
01668         } else {
01669           /* If the queue is not empty, we walk through the queue and
01670              try to find a place where the sequence number of the
01671              incoming segment is between the sequence numbers of the
01672              previous and the next segment on the ->ooseq queue. That is
01673              the place where we put the incoming segment. If needed, we
01674              trim the second edges of the previous and the incoming
01675              segment so that it will fit into the sequence.
01676 
01677              If the incoming segment has the same sequence number as a
01678              segment on the ->ooseq queue, we discard the segment that
01679              contains less data. */
01680 
01681 #if LWIP_TCP_SACK_OUT
01682           /* This is the left edge of the lowest possible SACK range.
01683              It may start before the newly received segment (possibly adjusted below). */
01684           u32_t sackbeg = TCP_SEQ_LT(seqno, pcb->ooseq->tcphdr->seqno) ? seqno : pcb->ooseq->tcphdr->seqno;
01685 #endif /* LWIP_TCP_SACK_OUT */
01686           struct tcp_seg *next, *prev = NULL;
01687           for (next = pcb->ooseq; next != NULL; next = next->next) {
01688             if (seqno == next->tcphdr->seqno) {
01689               /* The sequence number of the incoming segment is the
01690                  same as the sequence number of the segment on
01691                  ->ooseq. We check the lengths to see which one to
01692                  discard. */
01693               if (inseg.len > next->len) {
01694                 /* The incoming segment is larger than the old
01695                    segment. We replace some segments with the new
01696                    one. */
01697                 struct tcp_seg *cseg = tcp_seg_copy(&inseg);
01698                 if (cseg != NULL) {
01699                   if (prev != NULL) {
01700                     prev->next = cseg;
01701                   } else {
01702                     pcb->ooseq = cseg;
01703                   }
01704                   tcp_oos_insert_segment(cseg, next);
01705                 }
01706                 break;
01707               } else {
01708                 /* Either the lengths are the same or the incoming
01709                    segment was smaller than the old one; in either
01710                    case, we ditch the incoming segment. */
01711                 break;
01712               }
01713             } else {
01714               if (prev == NULL) {
01715                 if (TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {
01716                   /* The sequence number of the incoming segment is lower
01717                      than the sequence number of the first segment on the
01718                      queue. We put the incoming segment first on the
01719                      queue. */
01720                   struct tcp_seg *cseg = tcp_seg_copy(&inseg);
01721                   if (cseg != NULL) {
01722                     pcb->ooseq = cseg;
01723                     tcp_oos_insert_segment(cseg, next);
01724                   }
01725                   break;
01726                 }
01727               } else {
01728                 /*if (TCP_SEQ_LT(prev->tcphdr->seqno, seqno) &&
01729                   TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {*/
01730                 if (TCP_SEQ_BETWEEN(seqno, prev->tcphdr->seqno + 1, next->tcphdr->seqno - 1)) {
01731                   /* The sequence number of the incoming segment is in
01732                      between the sequence numbers of the previous and
01733                      the next segment on ->ooseq. We trim trim the previous
01734                      segment, delete next segments that included in received segment
01735                      and trim received, if needed. */
01736                   struct tcp_seg *cseg = tcp_seg_copy(&inseg);
01737                   if (cseg != NULL) {
01738                     if (TCP_SEQ_GT(prev->tcphdr->seqno + prev->len, seqno)) {
01739                       /* We need to trim the prev segment. */
01740                       prev->len = (u16_t)(seqno - prev->tcphdr->seqno);
01741                       pbuf_realloc(prev->p, prev->len);
01742                     }
01743                     prev->next = cseg;
01744                     tcp_oos_insert_segment(cseg, next);
01745                   }
01746                   break;
01747                 }
01748               }
01749 
01750 #if LWIP_TCP_SACK_OUT
01751               /* The new segment goes after the 'next' one. If there is a "hole" in sequence numbers
01752                  between 'prev' and the beginning of 'next', we want to move sackbeg. */
01753               if (prev != NULL && prev->tcphdr->seqno + prev->len != next->tcphdr->seqno) {
01754                 sackbeg = next->tcphdr->seqno;
01755               }
01756 #endif /* LWIP_TCP_SACK_OUT */
01757 
01758               /* We don't use 'prev' below, so let's set it to current 'next'.
01759                  This way even if we break the loop below, 'prev' will be pointing
01760                  at the segment right in front of the newly added one. */
01761               prev = next;
01762 
01763               /* If the "next" segment is the last segment on the
01764                  ooseq queue, we add the incoming segment to the end
01765                  of the list. */
01766               if (next->next == NULL &&
01767                   TCP_SEQ_GT(seqno, next->tcphdr->seqno)) {
01768                 if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) {
01769                   /* segment "next" already contains all data */
01770                   break;
01771                 }
01772                 next->next = tcp_seg_copy(&inseg);
01773                 if (next->next != NULL) {
01774                   if (TCP_SEQ_GT(next->tcphdr->seqno + next->len, seqno)) {
01775                     /* We need to trim the last segment. */
01776                     next->len = (u16_t)(seqno - next->tcphdr->seqno);
01777                     pbuf_realloc(next->p, next->len);
01778                   }
01779                   /* check if the remote side overruns our receive window */
01780                   if (TCP_SEQ_GT((u32_t)tcplen + seqno, pcb->rcv_nxt + (u32_t)pcb->rcv_wnd)) {
01781                     LWIP_DEBUGF(TCP_INPUT_DEBUG,
01782                                 ("tcp_receive: other end overran receive window"
01783                                  "seqno %"U32_F" len %"U16_F" right edge %"U32_F"\n",
01784                                  seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd));
01785                     if (TCPH_FLAGS(next->next->tcphdr) & TCP_FIN) {
01786                       /* Must remove the FIN from the header as we're trimming
01787                        * that byte of sequence-space from the packet */
01788                       TCPH_FLAGS_SET(next->next->tcphdr, TCPH_FLAGS(next->next->tcphdr) & ~TCP_FIN);
01789                     }
01790                     /* Adjust length of segment to fit in the window. */
01791                     next->next->len = (u16_t)(pcb->rcv_nxt + pcb->rcv_wnd - seqno);
01792                     pbuf_realloc(next->next->p, next->next->len);
01793                     tcplen = TCP_TCPLEN(next->next);
01794                     LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n",
01795                                 (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd));
01796                   }
01797                 }
01798                 break;
01799               }
01800             }
01801           }
01802 
01803 #if LWIP_TCP_SACK_OUT
01804           if (pcb->flags & TF_SACK) {
01805             if (prev == NULL) {
01806               /* The new segment is at the beginning. sackbeg should already be set properly.
01807                  We need to find the right edge. */
01808               next = pcb->ooseq;
01809             } else if (prev->next != NULL) {
01810               /* The new segment was added after 'prev'. If there is a "hole" between 'prev' and 'prev->next',
01811                  we need to move sackbeg. After that we should find the right edge. */
01812               next = prev->next;
01813               if (prev->tcphdr->seqno + prev->len != next->tcphdr->seqno) {
01814                 sackbeg = next->tcphdr->seqno;
01815               }
01816             } else {
01817               next = NULL;
01818             }
01819             if (next != NULL) {
01820               u32_t sackend = next->tcphdr->seqno;
01821               for ( ; (next != NULL) && (sackend == next->tcphdr->seqno); next = next->next) {
01822                 sackend += next->len;
01823               }
01824               tcp_add_sack(pcb, sackbeg, sackend);
01825             }
01826           }
01827 #endif /* LWIP_TCP_SACK_OUT */
01828         }
01829 #if defined(TCP_OOSEQ_BYTES_LIMIT) || defined(TCP_OOSEQ_PBUFS_LIMIT)
01830         {
01831           /* Check that the data on ooseq doesn't exceed one of the limits
01832              and throw away everything above that limit. */
01833 #ifdef TCP_OOSEQ_BYTES_LIMIT
01834           const u32_t ooseq_max_blen = TCP_OOSEQ_BYTES_LIMIT(pcb);
01835           u32_t ooseq_blen = 0;
01836 #endif
01837 #ifdef TCP_OOSEQ_PBUFS_LIMIT
01838           const u16_t ooseq_max_qlen = TCP_OOSEQ_PBUFS_LIMIT(pcb);
01839           u16_t ooseq_qlen = 0;
01840 #endif
01841           struct tcp_seg *next, *prev = NULL;
01842           for (next = pcb->ooseq; next != NULL; prev = next, next = next->next) {
01843             struct pbuf *p = next->p;
01844             int stop_here = 0;
01845 #ifdef TCP_OOSEQ_BYTES_LIMIT
01846             ooseq_blen += p->tot_len;
01847             if (ooseq_blen > ooseq_max_blen) {
01848               stop_here = 1;
01849             }
01850 #endif
01851 #ifdef TCP_OOSEQ_PBUFS_LIMIT
01852             ooseq_qlen += pbuf_clen(p);
01853             if (ooseq_qlen > ooseq_max_qlen) {
01854               stop_here = 1;
01855             }
01856 #endif
01857             if (stop_here) {
01858 #if LWIP_TCP_SACK_OUT
01859               if (pcb->flags & TF_SACK) {
01860                 /* Let's remove all SACKs from next's seqno up. */
01861                 tcp_remove_sacks_gt(pcb, next->tcphdr->seqno);
01862               }
01863 #endif /* LWIP_TCP_SACK_OUT */
01864               /* too much ooseq data, dump this and everything after it */
01865               tcp_segs_free(next);
01866               if (prev == NULL) {
01867                 /* first ooseq segment is too much, dump the whole queue */
01868                 pcb->ooseq = NULL;
01869               } else {
01870                 /* just dump 'next' and everything after it */
01871                 prev->next = NULL;
01872               }
01873               break;
01874             }
01875           }
01876         }
01877 #endif /* TCP_OOSEQ_BYTES_LIMIT || TCP_OOSEQ_PBUFS_LIMIT */
01878 #endif /* TCP_QUEUE_OOSEQ */
01879 
01880         /* We send the ACK packet after we've (potentially) dealt with SACKs,
01881            so they can be included in the acknowledgment. */
01882         tcp_send_empty_ack(pcb);
01883       }
01884     } else {
01885       /* The incoming segment is not within the window. */
01886       tcp_send_empty_ack(pcb);
01887     }
01888   } else {
01889     /* Segments with length 0 is taken care of here. Segments that
01890        fall out of the window are ACKed. */
01891     if (!TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd - 1)) {
01892       tcp_ack_now(pcb);
01893     }
01894   }
01895 }
01896 
01897 static u8_t
01898 tcp_get_next_optbyte(void)
01899 {
01900   u16_t optidx = tcp_optidx++;
01901   if ((tcphdr_opt2 == NULL) || (optidx < tcphdr_opt1len)) {
01902     u8_t *opts = (u8_t *)tcphdr + TCP_HLEN;
01903     return opts[optidx];
01904   } else {
01905     u8_t idx = (u8_t)(optidx - tcphdr_opt1len);
01906     return tcphdr_opt2[idx];
01907   }
01908 }
01909 
01910 /**
01911  * Parses the options contained in the incoming segment.
01912  *
01913  * Called from tcp_listen_input() and tcp_process().
01914  * Currently, only the MSS option is supported!
01915  *
01916  * @param pcb the tcp_pcb for which a segment arrived
01917  */
01918 static void
01919 tcp_parseopt(struct tcp_pcb *pcb)
01920 {
01921   u8_t data;
01922   u16_t mss;
01923 #if LWIP_TCP_TIMESTAMPS
01924   u32_t tsval;
01925 #endif
01926 
01927   LWIP_ASSERT("tcp_parseopt: invalid pcb", pcb != NULL);
01928 
01929   /* Parse the TCP MSS option, if present. */
01930   if (tcphdr_optlen != 0) {
01931     for (tcp_optidx = 0; tcp_optidx < tcphdr_optlen; ) {
01932       u8_t opt = tcp_get_next_optbyte();
01933       switch (opt) {
01934         case LWIP_TCP_OPT_EOL:
01935           /* End of options. */
01936           LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: EOL\n"));
01937           return;
01938         case LWIP_TCP_OPT_NOP:
01939           /* NOP option. */
01940           LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: NOP\n"));
01941           break;
01942         case LWIP_TCP_OPT_MSS:
01943           LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: MSS\n"));
01944           if (tcp_get_next_optbyte() != LWIP_TCP_OPT_LEN_MSS || (tcp_optidx - 2 + LWIP_TCP_OPT_LEN_MSS) > tcphdr_optlen) {
01945             /* Bad length */
01946             LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
01947             return;
01948           }
01949           /* An MSS option with the right option length. */
01950           mss = (u16_t)(tcp_get_next_optbyte() << 8);
01951           mss |= tcp_get_next_optbyte();
01952           /* Limit the mss to the configured TCP_MSS and prevent division by zero */
01953           pcb->mss = ((mss > TCP_MSS) || (mss == 0)) ? TCP_MSS : mss;
01954           break;
01955 #if LWIP_WND_SCALE
01956         case LWIP_TCP_OPT_WS:
01957           LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: WND_SCALE\n"));
01958           if (tcp_get_next_optbyte() != LWIP_TCP_OPT_LEN_WS || (tcp_optidx - 2 + LWIP_TCP_OPT_LEN_WS) > tcphdr_optlen) {
01959             /* Bad length */
01960             LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
01961             return;
01962           }
01963           /* An WND_SCALE option with the right option length. */
01964           data = tcp_get_next_optbyte();
01965           /* If syn was received with wnd scale option,
01966              activate wnd scale opt, but only if this is not a retransmission */
01967           if ((flags & TCP_SYN) && !(pcb->flags & TF_WND_SCALE)) {
01968             pcb->snd_scale = data;
01969             if (pcb->snd_scale > 14U) {
01970               pcb->snd_scale = 14U;
01971             }
01972             pcb->rcv_scale = TCP_RCV_SCALE;
01973             tcp_set_flags(pcb, TF_WND_SCALE);
01974             /* window scaling is enabled, we can use the full receive window */
01975             LWIP_ASSERT("window not at default value", pcb->rcv_wnd == TCPWND_MIN16(TCP_WND));
01976             LWIP_ASSERT("window not at default value", pcb->rcv_ann_wnd == TCPWND_MIN16(TCP_WND));
01977             pcb->rcv_wnd = pcb->rcv_ann_wnd = TCP_WND;
01978           }
01979           break;
01980 #endif /* LWIP_WND_SCALE */
01981 #if LWIP_TCP_TIMESTAMPS
01982         case LWIP_TCP_OPT_TS:
01983           LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: TS\n"));
01984           if (tcp_get_next_optbyte() != LWIP_TCP_OPT_LEN_TS || (tcp_optidx - 2 + LWIP_TCP_OPT_LEN_TS) > tcphdr_optlen) {
01985             /* Bad length */
01986             LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
01987             return;
01988           }
01989           /* TCP timestamp option with valid length */
01990           tsval = tcp_get_next_optbyte();
01991           tsval |= (tcp_get_next_optbyte() << 8);
01992           tsval |= (tcp_get_next_optbyte() << 16);
01993           tsval |= (tcp_get_next_optbyte() << 24);
01994           if (flags & TCP_SYN) {
01995             pcb->ts_recent = lwip_ntohl(tsval);
01996             /* Enable sending timestamps in every segment now that we know
01997                the remote host supports it. */
01998             tcp_set_flags(pcb, TF_TIMESTAMP);
01999           } else if (TCP_SEQ_BETWEEN(pcb->ts_lastacksent, seqno, seqno + tcplen)) {
02000             pcb->ts_recent = lwip_ntohl(tsval);
02001           }
02002           /* Advance to next option (6 bytes already read) */
02003           tcp_optidx += LWIP_TCP_OPT_LEN_TS - 6;
02004           break;
02005 #endif /* LWIP_TCP_TIMESTAMPS */
02006 #if LWIP_TCP_SACK_OUT
02007         case LWIP_TCP_OPT_SACK_PERM:
02008           LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: SACK_PERM\n"));
02009           if (tcp_get_next_optbyte() != LWIP_TCP_OPT_LEN_SACK_PERM || (tcp_optidx - 2 + LWIP_TCP_OPT_LEN_SACK_PERM) > tcphdr_optlen) {
02010             /* Bad length */
02011             LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
02012             return;
02013           }
02014           /* TCP SACK_PERM option with valid length */
02015           if (flags & TCP_SYN) {
02016             /* We only set it if we receive it in a SYN (or SYN+ACK) packet */
02017             tcp_set_flags(pcb, TF_SACK);
02018           }
02019           break;
02020 #endif /* LWIP_TCP_SACK_OUT */
02021         default:
02022           LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: other\n"));
02023           data = tcp_get_next_optbyte();
02024           if (data < 2) {
02025             LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
02026             /* If the length field is zero, the options are malformed
02027                and we don't process them further. */
02028             return;
02029           }
02030           /* All other options have a length field, so that we easily
02031              can skip past them. */
02032           tcp_optidx += data - 2;
02033       }
02034     }
02035   }
02036 }
02037 
02038 void
02039 tcp_trigger_input_pcb_close(void)
02040 {
02041   recv_flags |= TF_CLOSED;
02042 }
02043 
02044 #if LWIP_TCP_SACK_OUT
02045 /**
02046  * Called by tcp_receive() to add new SACK entry.
02047  *
02048  * The new SACK entry will be placed at the beginning of rcv_sacks[], as the newest one.
02049  * Existing SACK entries will be "pushed back", to preserve their order.
02050  * This is the behavior described in RFC 2018, section 4.
02051  *
02052  * @param pcb the tcp_pcb for which a segment arrived
02053  * @param left the left side of the SACK (the first sequence number)
02054  * @param right the right side of the SACK (the first sequence number past this SACK)
02055  */
02056 static void
02057 tcp_add_sack(struct tcp_pcb *pcb, u32_t left, u32_t right)
02058 {
02059   u8_t i;
02060   u8_t unused_idx;
02061 
02062   if ((pcb->flags & TF_SACK) == 0 || !TCP_SEQ_LT(left, right)) {
02063     return;
02064   }
02065 
02066   /* First, let's remove all SACKs that are no longer needed (because they overlap with the newest one),
02067      while moving all other SACKs forward.
02068      We run this loop for all entries, until we find the first invalid one.
02069      There is no point checking after that. */
02070   for (i = unused_idx = 0; (i < LWIP_TCP_MAX_SACK_NUM) && LWIP_TCP_SACK_VALID(pcb, i); ++i) {
02071     /* We only want to use SACK at [i] if it doesn't overlap with left:right range.
02072        It does not overlap if its right side is before the newly added SACK,
02073        or if its left side is after the newly added SACK.
02074        NOTE: The equality should not really happen, but it doesn't hurt. */
02075     if (TCP_SEQ_LEQ(pcb->rcv_sacks[i].right, left) || TCP_SEQ_LEQ(right, pcb->rcv_sacks[i].left)) {
02076       if (unused_idx != i) {
02077         /* We don't need to copy if it's already in the right spot */
02078         pcb->rcv_sacks[unused_idx] = pcb->rcv_sacks[i];
02079       }
02080       ++unused_idx;
02081     }
02082   }
02083 
02084   /* Now 'unused_idx' is the index of the first invalid SACK entry,
02085      anywhere between 0 (no valid entries) and LWIP_TCP_MAX_SACK_NUM (all entries are valid).
02086      We want to clear this and all following SACKs.
02087      However, we will be adding another one in the front (and shifting everything else back).
02088      So let's just iterate from the back, and set each entry to the one to the left if it's valid,
02089      or to 0 if it is not. */
02090   for (i = LWIP_TCP_MAX_SACK_NUM - 1; i > 0; --i) {
02091     /* [i] is the index we are setting, and the value should be at index [i-1],
02092        or 0 if that index is unused (>= unused_idx). */
02093     if (i - 1 >= unused_idx) {
02094       /* [i-1] is unused. Let's clear [i]. */
02095       pcb->rcv_sacks[i].left = pcb->rcv_sacks[i].right = 0;
02096     } else {
02097       pcb->rcv_sacks[i] = pcb->rcv_sacks[i - 1];
02098     }
02099   }
02100 
02101   /* And now we can store the newest SACK */
02102   pcb->rcv_sacks[0].left = left;
02103   pcb->rcv_sacks[0].right = right;
02104 }
02105 
02106 /**
02107  * Called to remove a range of SACKs.
02108  *
02109  * SACK entries will be removed or adjusted to not acknowledge any sequence
02110  * numbers that are less than 'seq' passed. It not only invalidates entries,
02111  * but also moves all entries that are still valid to the beginning.
02112  *
02113  * @param pcb the tcp_pcb to modify
02114  * @param seq the lowest sequence number to keep in SACK entries
02115  */
02116 static void
02117 tcp_remove_sacks_lt(struct tcp_pcb *pcb, u32_t seq)
02118 {
02119   u8_t i;
02120   u8_t unused_idx;
02121 
02122   /* We run this loop for all entries, until we find the first invalid one.
02123      There is no point checking after that. */
02124   for (i = unused_idx = 0; (i < LWIP_TCP_MAX_SACK_NUM) && LWIP_TCP_SACK_VALID(pcb, i); ++i) {
02125     /* We only want to use SACK at index [i] if its right side is > 'seq'. */
02126     if (TCP_SEQ_GT(pcb->rcv_sacks[i].right, seq)) {
02127       if (unused_idx != i) {
02128         /* We only copy it if it's not in the right spot already. */
02129         pcb->rcv_sacks[unused_idx] = pcb->rcv_sacks[i];
02130       }
02131       /* NOTE: It is possible that its left side is < 'seq', in which case we should adjust it. */
02132       if (TCP_SEQ_LT(pcb->rcv_sacks[unused_idx].left, seq)) {
02133         pcb->rcv_sacks[unused_idx].left = seq;
02134       }
02135       ++unused_idx;
02136     }
02137   }
02138 
02139   /* We also need to invalidate everything from 'unused_idx' till the end */
02140   for (i = unused_idx; i < LWIP_TCP_MAX_SACK_NUM; ++i) {
02141     pcb->rcv_sacks[i].left = pcb->rcv_sacks[i].right = 0;
02142   }
02143 }
02144 
02145 #if defined(TCP_OOSEQ_BYTES_LIMIT) || defined(TCP_OOSEQ_PBUFS_LIMIT)
02146 /**
02147  * Called to remove a range of SACKs.
02148  *
02149  * SACK entries will be removed or adjusted to not acknowledge any sequence
02150  * numbers that are greater than (or equal to) 'seq' passed. It not only invalidates entries,
02151  * but also moves all entries that are still valid to the beginning.
02152  *
02153  * @param pcb the tcp_pcb to modify
02154  * @param seq the highest sequence number to keep in SACK entries
02155  */
02156 static void
02157 tcp_remove_sacks_gt(struct tcp_pcb *pcb, u32_t seq)
02158 {
02159   u8_t i;
02160   u8_t unused_idx;
02161 
02162   /* We run this loop for all entries, until we find the first invalid one.
02163      There is no point checking after that. */
02164   for (i = unused_idx = 0; (i < LWIP_TCP_MAX_SACK_NUM) && LWIP_TCP_SACK_VALID(pcb, i); ++i) {
02165     /* We only want to use SACK at index [i] if its left side is < 'seq'. */
02166     if (TCP_SEQ_LT(pcb->rcv_sacks[i].left, seq)) {
02167       if (unused_idx != i) {
02168         /* We only copy it if it's not in the right spot already. */
02169         pcb->rcv_sacks[unused_idx] = pcb->rcv_sacks[i];
02170       }
02171       /* NOTE: It is possible that its right side is > 'seq', in which case we should adjust it. */
02172       if (TCP_SEQ_GT(pcb->rcv_sacks[unused_idx].right, seq)) {
02173         pcb->rcv_sacks[unused_idx].right = seq;
02174       }
02175       ++unused_idx;
02176     }
02177   }
02178 
02179   /* We also need to invalidate everything from 'unused_idx' till the end */
02180   for (i = unused_idx; i < LWIP_TCP_MAX_SACK_NUM; ++i) {
02181     pcb->rcv_sacks[i].left = pcb->rcv_sacks[i].right = 0;
02182   }
02183 }
02184 #endif /* TCP_OOSEQ_BYTES_LIMIT || TCP_OOSEQ_PBUFS_LIMIT */
02185 
02186 #endif /* LWIP_TCP_SACK_OUT */
02187 
02188 #endif /* LWIP_TCP */