Rizky Ardi Maulana / mbed-os
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 #include "lwip/inet_chksum.h"
00059 #if LWIP_ND6_TCP_REACHABILITY_HINTS
00060 #include "lwip/nd6.h"
00061 #endif /* LWIP_ND6_TCP_REACHABILITY_HINTS */
00062 
00063 /** Initial CWND calculation as defined RFC 2581 */
00064 #define LWIP_TCP_CALC_INITIAL_CWND(mss) LWIP_MIN((4U * (mss)), LWIP_MAX((2U * (mss)), 4380U));
00065 /** Initial slow start threshold value: we use the full window */
00066 #define LWIP_TCP_INITIAL_SSTHRESH(pcb)  ((pcb)->snd_wnd)
00067 
00068 /* These variables are global to all functions involved in the input
00069    processing of TCP segments. They are set by the tcp_input()
00070    function. */
00071 static struct tcp_seg inseg;
00072 static struct tcp_hdr *tcphdr;
00073 static u16_t tcphdr_optlen;
00074 static u16_t tcphdr_opt1len;
00075 static u8_t* tcphdr_opt2;
00076 static u16_t tcp_optidx;
00077 static u32_t seqno, ackno;
00078 static tcpwnd_size_t recv_acked;
00079 static u16_t tcplen;
00080 static u8_t flags;
00081 
00082 static u8_t recv_flags;
00083 static struct pbuf *recv_data;
00084 
00085 struct tcp_pcb *tcp_input_pcb;
00086 
00087 /* Forward declarations. */
00088 static err_t tcp_process(struct tcp_pcb *pcb);
00089 static void tcp_receive(struct tcp_pcb *pcb);
00090 static void tcp_parseopt(struct tcp_pcb *pcb);
00091 
00092 static void tcp_listen_input(struct tcp_pcb_listen *pcb);
00093 static void tcp_timewait_input(struct tcp_pcb *pcb);
00094 
00095 /**
00096  * The initial input processing of TCP. It verifies the TCP header, demultiplexes
00097  * the segment between the PCBs and passes it on to tcp_process(), which implements
00098  * the TCP finite state machine. This function is called by the IP layer (in
00099  * ip_input()).
00100  *
00101  * @param p received TCP segment to process (p->payload pointing to the TCP header)
00102  * @param inp network interface on which this segment was received
00103  */
00104 void
00105 tcp_input(struct pbuf *p, struct netif *inp)
00106 {
00107   struct tcp_pcb *pcb, *prev;
00108   struct tcp_pcb_listen *lpcb;
00109 #if SO_REUSE
00110   struct tcp_pcb *lpcb_prev = NULL;
00111   struct tcp_pcb_listen *lpcb_any = NULL;
00112 #endif /* SO_REUSE */
00113   u8_t hdrlen_bytes;
00114   err_t err;
00115 
00116   LWIP_UNUSED_ARG(inp);
00117 
00118   PERF_START;
00119 
00120   TCP_STATS_INC(tcp.recv);
00121   MIB2_STATS_INC(mib2.tcpinsegs);
00122 
00123   tcphdr = (struct tcp_hdr *)p->payload;
00124 
00125 #if TCP_INPUT_DEBUG
00126   tcp_debug_print(tcphdr);
00127 #endif
00128 
00129   /* Check that TCP header fits in payload */
00130   if (p->len < TCP_HLEN) {
00131     /* drop short packets */
00132     LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet (%"U16_F" bytes) discarded\n", p->tot_len));
00133     TCP_STATS_INC(tcp.lenerr);
00134     goto dropped;
00135   }
00136 
00137   /* Don't even process incoming broadcasts/multicasts. */
00138   if (ip_addr_isbroadcast(ip_current_dest_addr(), ip_current_netif()) ||
00139       ip_addr_ismulticast(ip_current_dest_addr())) {
00140     TCP_STATS_INC(tcp.proterr);
00141     goto dropped;
00142   }
00143 
00144 #if CHECKSUM_CHECK_TCP
00145   IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_TCP) {
00146     /* Verify TCP checksum. */
00147     u16_t chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len,
00148                                ip_current_src_addr(), ip_current_dest_addr());
00149     if (chksum != 0) {
00150         LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packet discarded due to failing checksum 0x%04"X16_F"\n",
00151           chksum));
00152       tcp_debug_print(tcphdr);
00153       TCP_STATS_INC(tcp.chkerr);
00154       goto dropped;
00155     }
00156   }
00157 #endif /* CHECKSUM_CHECK_TCP */
00158 
00159   /* sanity-check header length */
00160   hdrlen_bytes = TCPH_HDRLEN(tcphdr) * 4;
00161   if ((hdrlen_bytes < TCP_HLEN) || (hdrlen_bytes > p->tot_len)) {
00162     LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: invalid header length (%"U16_F")\n", (u16_t)hdrlen_bytes));
00163     TCP_STATS_INC(tcp.lenerr);
00164     goto dropped;
00165   }
00166 
00167   /* Move the payload pointer in the pbuf so that it points to the
00168      TCP data instead of the TCP header. */
00169   tcphdr_optlen = hdrlen_bytes - TCP_HLEN;
00170   tcphdr_opt2 = NULL;
00171   if (p->len >= hdrlen_bytes) {
00172     /* all options are in the first pbuf */
00173     tcphdr_opt1len = tcphdr_optlen;
00174     pbuf_header(p, -(s16_t)hdrlen_bytes); /* cannot fail */
00175   } else {
00176     u16_t opt2len;
00177     /* TCP header fits into first pbuf, options don't - data is in the next pbuf */
00178     /* there must be a next pbuf, due to hdrlen_bytes sanity check above */
00179     LWIP_ASSERT("p->next != NULL", p->next != NULL);
00180 
00181     /* advance over the TCP header (cannot fail) */
00182     pbuf_header(p, -TCP_HLEN);
00183 
00184     /* determine how long the first and second parts of the options are */
00185     tcphdr_opt1len = p->len;
00186     opt2len = tcphdr_optlen - tcphdr_opt1len;
00187 
00188     /* options continue in the next pbuf: set p to zero length and hide the
00189         options in the next pbuf (adjusting p->tot_len) */
00190     pbuf_header(p, -(s16_t)tcphdr_opt1len);
00191 
00192     /* check that the options fit in the second pbuf */
00193     if (opt2len > p->next->len) {
00194       /* drop short packets */
00195       LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: options overflow second pbuf (%"U16_F" bytes)\n", p->next->len));
00196       TCP_STATS_INC(tcp.lenerr);
00197       goto dropped;
00198     }
00199 
00200     /* remember the pointer to the second part of the options */
00201     tcphdr_opt2 = (u8_t*)p->next->payload;
00202     
00203     /* advance p->next to point after the options, and manually
00204         adjust p->tot_len to keep it consistent with the changed p->next */
00205     pbuf_header(p->next, -(s16_t)opt2len);
00206     p->tot_len -= opt2len;
00207 
00208     LWIP_ASSERT("p->len == 0", p->len == 0);
00209     LWIP_ASSERT("p->tot_len == p->next->tot_len", p->tot_len == p->next->tot_len);
00210   }
00211 
00212   /* Convert fields in TCP header to host byte order. */
00213   tcphdr->src = ntohs(tcphdr->src);
00214   tcphdr->dest = ntohs(tcphdr->dest);
00215   seqno = tcphdr->seqno = ntohl(tcphdr->seqno);
00216   ackno = tcphdr->ackno = ntohl(tcphdr->ackno);
00217   tcphdr->wnd = ntohs(tcphdr->wnd);
00218 
00219   flags = TCPH_FLAGS(tcphdr);
00220   tcplen = p->tot_len + ((flags & (TCP_FIN | TCP_SYN)) ? 1 : 0);
00221 
00222   /* Demultiplex an incoming segment. First, we check if it is destined
00223      for an active connection. */
00224   prev = NULL;
00225 
00226   for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
00227     LWIP_ASSERT("tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED);
00228     LWIP_ASSERT("tcp_input: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);
00229     LWIP_ASSERT("tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN);
00230     if (pcb->remote_port == tcphdr->src &&
00231         pcb->local_port == tcphdr->dest &&
00232         ip_addr_cmp(&pcb->remote_ip, ip_current_src_addr()) &&
00233         ip_addr_cmp(&pcb->local_ip, ip_current_dest_addr())) {
00234       /* Move this PCB to the front of the list so that subsequent
00235          lookups will be faster (we exploit locality in TCP segment
00236          arrivals). */
00237       LWIP_ASSERT("tcp_input: pcb->next != pcb (before cache)", pcb->next != pcb);
00238       if (prev != NULL) {
00239         prev->next = pcb->next;
00240         pcb->next = tcp_active_pcbs;
00241         tcp_active_pcbs = pcb;
00242       } else {
00243         TCP_STATS_INC(tcp.cachehit);
00244       }
00245       LWIP_ASSERT("tcp_input: pcb->next != pcb (after cache)", pcb->next != pcb);
00246       break;
00247     }
00248     prev = pcb;
00249   }
00250 
00251   if (pcb == NULL) {
00252     /* If it did not go to an active connection, we check the connections
00253        in the TIME-WAIT state. */
00254     for (pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
00255       LWIP_ASSERT("tcp_input: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
00256       if (pcb->remote_port == tcphdr->src &&
00257           pcb->local_port == tcphdr->dest &&
00258           ip_addr_cmp(&pcb->remote_ip, ip_current_src_addr()) &&
00259           ip_addr_cmp(&pcb->local_ip, ip_current_dest_addr())) {
00260         /* We don't really care enough to move this PCB to the front
00261            of the list since we are not very likely to receive that
00262            many segments for connections in TIME-WAIT. */
00263         LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for TIME_WAITing connection.\n"));
00264         tcp_timewait_input(pcb);
00265         pbuf_free(p);
00266         return;
00267       }
00268     }
00269 
00270     /* Finally, if we still did not get a match, we check all PCBs that
00271        are LISTENing for incoming connections. */
00272     prev = NULL;
00273     for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
00274       if (lpcb->local_port == tcphdr->dest) {
00275         if (IP_IS_ANY_TYPE_VAL(lpcb->local_ip)) {
00276           /* found an ANY TYPE (IPv4/IPv6) match */
00277 #if SO_REUSE
00278           lpcb_any = lpcb;
00279           lpcb_prev = prev;
00280 #else /* SO_REUSE */
00281           break;
00282 #endif /* SO_REUSE */
00283         } else if (IP_ADDR_PCB_VERSION_MATCH_EXACT(lpcb, ip_current_dest_addr())) {
00284           if (ip_addr_cmp(&lpcb->local_ip, ip_current_dest_addr())) {
00285             /* found an exact match */
00286             break;
00287           } else if (ip_addr_isany(&lpcb->local_ip)) {
00288             /* found an ANY-match */
00289 #if SO_REUSE
00290             lpcb_any = lpcb;
00291             lpcb_prev = prev;
00292 #else /* SO_REUSE */
00293             break;
00294  #endif /* SO_REUSE */
00295           }
00296         }
00297       }
00298       prev = (struct tcp_pcb *)lpcb;
00299     }
00300 #if SO_REUSE
00301     /* first try specific local IP */
00302     if (lpcb == NULL) {
00303       /* only pass to ANY if no specific local IP has been found */
00304       lpcb = lpcb_any;
00305       prev = lpcb_prev;
00306     }
00307 #endif /* SO_REUSE */
00308     if (lpcb != NULL) {
00309       /* Move this PCB to the front of the list so that subsequent
00310          lookups will be faster (we exploit locality in TCP segment
00311          arrivals). */
00312       if (prev != NULL) {
00313         ((struct tcp_pcb_listen *)prev)->next = lpcb->next;
00314               /* our successor is the remainder of the listening list */
00315         lpcb->next = tcp_listen_pcbs.listen_pcbs;
00316               /* put this listening pcb at the head of the listening list */
00317         tcp_listen_pcbs.listen_pcbs = lpcb;
00318       } else {
00319         TCP_STATS_INC(tcp.cachehit);
00320       }
00321 
00322       LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for LISTENing connection.\n"));
00323       tcp_listen_input(lpcb);
00324       pbuf_free(p);
00325       return;
00326     }
00327   }
00328 
00329 #if TCP_INPUT_DEBUG
00330   LWIP_DEBUGF(TCP_INPUT_DEBUG, ("+-+-+-+-+-+-+-+-+-+-+-+-+-+- tcp_input: flags "));
00331   tcp_debug_print_flags(TCPH_FLAGS(tcphdr));
00332   LWIP_DEBUGF(TCP_INPUT_DEBUG, ("-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n"));
00333 #endif /* TCP_INPUT_DEBUG */
00334 
00335 
00336   if (pcb != NULL) {
00337     /* The incoming segment belongs to a connection. */
00338 #if TCP_INPUT_DEBUG
00339     tcp_debug_print_state(pcb->state);
00340 #endif /* TCP_INPUT_DEBUG */
00341 
00342     /* Set up a tcp_seg structure. */
00343     inseg.next = NULL;
00344     inseg.len = p->tot_len;
00345     inseg.p = p;
00346     inseg.tcphdr = tcphdr;
00347 
00348     recv_data = NULL;
00349     recv_flags = 0;
00350     recv_acked = 0;
00351 
00352     if (flags & TCP_PSH) {
00353       p->flags |= PBUF_FLAG_PUSH;
00354     }
00355 
00356     /* If there is data which was previously "refused" by upper layer */
00357     if (pcb->refused_data != NULL) {
00358       if ((tcp_process_refused_data(pcb) == ERR_ABRT) ||
00359         ((pcb->refused_data != NULL) && (tcplen > 0))) {
00360         /* pcb has been aborted or refused data is still refused and the new
00361            segment contains data */
00362         TCP_STATS_INC(tcp.drop);
00363         MIB2_STATS_INC(mib2.tcpinerrs);
00364         goto aborted;
00365       }
00366     }
00367     tcp_input_pcb = pcb;
00368     err = tcp_process(pcb);
00369     /* A return value of ERR_ABRT means that tcp_abort() was called
00370        and that the pcb has been freed. If so, we don't do anything. */
00371     if (err != ERR_ABRT) {
00372       if (recv_flags & TF_RESET) {
00373         /* TF_RESET means that the connection was reset by the other
00374            end. We then call the error callback to inform the
00375            application that the connection is dead before we
00376            deallocate the PCB. */
00377         TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_RST);
00378         tcp_pcb_remove(&tcp_active_pcbs, pcb);
00379         memp_free(MEMP_TCP_PCB, pcb);
00380       } else {
00381         err = ERR_OK;
00382         /* If the application has registered a "sent" function to be
00383            called when new send buffer space is available, we call it
00384            now. */
00385         if (recv_acked > 0) {
00386           u16_t acked16;
00387 #if LWIP_WND_SCALE
00388           /* recv_acked is u32_t but the sent callback only takes a u16_t,
00389              so we might have to call it multiple times. */
00390           u32_t acked = recv_acked;
00391           while (acked > 0) {
00392             acked16 = (u16_t)LWIP_MIN(acked, 0xffffu);
00393             acked -= acked16;
00394 #else
00395           {
00396             acked16 = recv_acked;
00397 #endif
00398             TCP_EVENT_SENT(pcb, (u16_t)acked16, err);
00399             if (err == ERR_ABRT) {
00400               goto aborted;
00401             }
00402           }
00403           recv_acked = 0;
00404         }
00405         if (recv_flags & TF_CLOSED) {
00406           /* The connection has been closed and we will deallocate the
00407              PCB. */
00408           if (!(pcb->flags & TF_RXCLOSED)) {
00409             /* Connection closed although the application has only shut down the
00410                tx side: call the PCB's err callback and indicate the closure to
00411                ensure the application doesn't continue using the PCB. */
00412             TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_CLSD);
00413           }
00414           tcp_pcb_remove(&tcp_active_pcbs, pcb);
00415           memp_free(MEMP_TCP_PCB, pcb);
00416           goto aborted;
00417         }
00418 #if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
00419         while (recv_data != NULL) {
00420           struct pbuf *rest = NULL;
00421           pbuf_split_64k(recv_data, &rest);
00422 #else /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
00423         if (recv_data != NULL) {
00424 #endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
00425 
00426           LWIP_ASSERT("pcb->refused_data == NULL", pcb->refused_data == NULL);
00427           if (pcb->flags & TF_RXCLOSED) {
00428             /* received data although already closed -> abort (send RST) to
00429                notify the remote host that not all data has been processed */
00430             pbuf_free(recv_data);
00431 #if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
00432             if (rest != NULL) {
00433               pbuf_free(rest);
00434             }
00435 #endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
00436             tcp_abort(pcb);
00437             goto aborted;
00438           }
00439 
00440           /* Notify application that data has been received. */
00441           TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err);
00442           if (err == ERR_ABRT) {
00443 #if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
00444             if (rest != NULL) {
00445               pbuf_free(rest);
00446             }
00447 #endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
00448             goto aborted;
00449           }
00450 
00451           /* If the upper layer can't receive this data, store it */
00452           if (err != ERR_OK) {
00453 #if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
00454             if (rest != NULL) {
00455               pbuf_cat(recv_data, rest);
00456             }
00457 #endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
00458             pcb->refused_data = recv_data;
00459             LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: keep incoming packet, because pcb is \"full\"\n"));
00460 #if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
00461             break;
00462           } else {
00463             /* Upper layer received the data, go on with the rest if > 64K */
00464             recv_data = rest;
00465 #endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
00466           }
00467         }
00468 
00469         /* If a FIN segment was received, we call the callback
00470            function with a NULL buffer to indicate EOF. */
00471         if (recv_flags & TF_GOT_FIN) {
00472           if (pcb->refused_data != NULL) {
00473             /* Delay this if we have refused data. */
00474             pcb->refused_data->flags |= PBUF_FLAG_TCP_FIN;
00475           } else {
00476             /* correct rcv_wnd as the application won't call tcp_recved()
00477                for the FIN's seqno */
00478             if (pcb->rcv_wnd != TCP_WND_MAX(pcb)) {
00479               pcb->rcv_wnd++;
00480             }
00481             TCP_EVENT_CLOSED(pcb, err);
00482             if (err == ERR_ABRT) {
00483               goto aborted;
00484             }
00485           }
00486         }
00487 
00488         tcp_input_pcb = NULL;
00489         /* Try to send something out. */
00490         tcp_output(pcb);
00491 #if TCP_INPUT_DEBUG
00492 #if TCP_DEBUG
00493         tcp_debug_print_state(pcb->state);
00494 #endif /* TCP_DEBUG */
00495 #endif /* TCP_INPUT_DEBUG */
00496       }
00497     }
00498     /* Jump target if pcb has been aborted in a callback (by calling tcp_abort()).
00499        Below this line, 'pcb' may not be dereferenced! */
00500 aborted:
00501     tcp_input_pcb = NULL;
00502     recv_data = NULL;
00503 
00504     /* give up our reference to inseg.p */
00505     if (inseg.p != NULL)
00506     {
00507       pbuf_free(inseg.p);
00508       inseg.p = NULL;
00509     }
00510   } else {
00511 
00512     /* If no matching PCB was found, send a TCP RST (reset) to the
00513        sender. */
00514     LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_input: no PCB match found, resetting.\n"));
00515     if (!(TCPH_FLAGS(tcphdr) & TCP_RST)) {
00516       TCP_STATS_INC(tcp.proterr);
00517       TCP_STATS_INC(tcp.drop);
00518       tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(),
00519         ip_current_src_addr(), tcphdr->dest, tcphdr->src);
00520     }
00521     pbuf_free(p);
00522   }
00523 
00524   LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane());
00525   PERF_STOP("tcp_input");
00526   return;
00527 dropped:
00528   TCP_STATS_INC(tcp.drop);
00529   MIB2_STATS_INC(mib2.tcpinerrs);
00530   pbuf_free(p);
00531 }
00532 
00533 /**
00534  * Called by tcp_input() when a segment arrives for a listening
00535  * connection (from tcp_input()).
00536  *
00537  * @param pcb the tcp_pcb_listen for which a segment arrived
00538  * @return ERR_OK if the segment was processed
00539  *         another err_t on error
00540  *
00541  * @note the return value is not (yet?) used in tcp_input()
00542  * @note the segment which arrived is saved in global variables, therefore only the pcb
00543  *       involved is passed as a parameter to this function
00544  */
00545 static void
00546 tcp_listen_input(struct tcp_pcb_listen *pcb)
00547 {
00548   struct tcp_pcb *npcb;
00549   err_t rc;
00550 
00551   if (flags & TCP_RST) {
00552     /* An incoming RST should be ignored. Return. */
00553     return;
00554   }
00555 
00556   /* In the LISTEN state, we check for incoming SYN segments,
00557      creates a new PCB, and responds with a SYN|ACK. */
00558   if (flags & TCP_ACK) {
00559     /* For incoming segments with the ACK flag set, respond with a
00560        RST. */
00561     LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_listen_input: ACK in LISTEN, sending reset\n"));
00562     tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(),
00563       ip_current_src_addr(), tcphdr->dest, tcphdr->src);
00564   } else if (flags & TCP_SYN) {
00565     LWIP_DEBUGF(TCP_DEBUG, ("TCP connection request %"U16_F" -> %"U16_F".\n", tcphdr->src, tcphdr->dest));
00566 #if TCP_LISTEN_BACKLOG
00567     if (pcb->accepts_pending >= pcb->backlog) {
00568       LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: listen backlog exceeded for port %"U16_F"\n", tcphdr->dest));
00569       return;
00570     }
00571 #endif /* TCP_LISTEN_BACKLOG */
00572     npcb = tcp_alloc(pcb->prio);
00573     /* If a new PCB could not be created (probably due to lack of memory),
00574        we don't do anything, but rely on the sender will retransmit the
00575        SYN at a time when we have more memory available. */
00576     if (npcb == NULL) {
00577       err_t err;
00578       LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: could not allocate PCB\n"));
00579       TCP_STATS_INC(tcp.memerr);
00580       TCP_EVENT_ACCEPT(pcb, NULL, pcb->callback_arg, ERR_MEM, err);
00581       LWIP_UNUSED_ARG(err); /* err not useful here */
00582       return;
00583     }
00584 #if TCP_LISTEN_BACKLOG
00585     pcb->accepts_pending++;
00586     npcb->flags |= TF_BACKLOGPEND;
00587 #endif /* TCP_LISTEN_BACKLOG */
00588     /* Set up the new PCB. */
00589     ip_addr_copy(npcb->local_ip, *ip_current_dest_addr());
00590     ip_addr_copy(npcb->remote_ip, *ip_current_src_addr());
00591     npcb->local_port = pcb->local_port;
00592     npcb->remote_port = tcphdr->src;
00593     npcb->state = SYN_RCVD;
00594     npcb->rcv_nxt = seqno + 1;
00595     npcb->rcv_ann_right_edge = npcb->rcv_nxt;
00596     npcb->snd_wl1 = seqno - 1;/* initialise to seqno-1 to force window update */
00597     npcb->callback_arg = pcb->callback_arg;
00598 #if LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG
00599     npcb->listener = pcb;
00600 #endif /* LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG */
00601     /* inherit socket options */
00602     npcb->so_options = pcb->so_options & SOF_INHERITED;
00603     /* Register the new PCB so that we can begin receiving segments
00604        for it. */
00605     TCP_REG_ACTIVE(npcb);
00606 
00607     /* Parse any options in the SYN. */
00608     tcp_parseopt(npcb);
00609     npcb->snd_wnd = SND_WND_SCALE(npcb, tcphdr->wnd);
00610     npcb->snd_wnd_max = npcb->snd_wnd;
00611     npcb->ssthresh = LWIP_TCP_INITIAL_SSTHRESH(npcb);
00612 
00613 #if TCP_CALCULATE_EFF_SEND_MSS
00614     npcb->mss = tcp_eff_send_mss(npcb->mss, &npcb->local_ip, &npcb->remote_ip);
00615 #endif /* TCP_CALCULATE_EFF_SEND_MSS */
00616 
00617     MIB2_STATS_INC(mib2.tcppassiveopens);
00618 
00619     /* Send a SYN|ACK together with the MSS option. */
00620     rc = tcp_enqueue_flags(npcb, TCP_SYN | TCP_ACK);
00621     if (rc != ERR_OK) {
00622       tcp_abandon(npcb, 0);
00623       return;
00624     }
00625     tcp_output(npcb);
00626   }
00627   return;
00628 }
00629 
00630 /**
00631  * Called by tcp_input() when a segment arrives for a connection in
00632  * TIME_WAIT.
00633  *
00634  * @param pcb the tcp_pcb for which a segment arrived
00635  *
00636  * @note the segment which arrived is saved in global variables, therefore only the pcb
00637  *       involved is passed as a parameter to this function
00638  */
00639 static void
00640 tcp_timewait_input(struct tcp_pcb *pcb)
00641 {
00642   /* RFC 1337: in TIME_WAIT, ignore RST and ACK FINs + any 'acceptable' segments */
00643   /* RFC 793 3.9 Event Processing - Segment Arrives:
00644    * - first check sequence number - we skip that one in TIME_WAIT (always
00645    *   acceptable since we only send ACKs)
00646    * - second check the RST bit (... return) */
00647   if (flags & TCP_RST) {
00648     return;
00649   }
00650   /* - fourth, check the SYN bit, */
00651   if (flags & TCP_SYN) {
00652     /* If an incoming segment is not acceptable, an acknowledgment
00653        should be sent in reply */
00654     if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd)) {
00655       /* If the SYN is in the window it is an error, send a reset */
00656       tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(),
00657         ip_current_src_addr(), tcphdr->dest, tcphdr->src);
00658       return;
00659     }
00660   } else if (flags & TCP_FIN) {
00661     /* - eighth, check the FIN bit: Remain in the TIME-WAIT state.
00662          Restart the 2 MSL time-wait timeout.*/
00663     pcb->tmr = tcp_ticks;
00664   }
00665 
00666   if ((tcplen > 0)) {
00667     /* Acknowledge data, FIN or out-of-window SYN */
00668     pcb->flags |= TF_ACK_NOW;
00669     tcp_output(pcb);
00670   }
00671   return;
00672 }
00673 
00674 /**
00675  * Implements the TCP state machine. Called by tcp_input. In some
00676  * states tcp_receive() is called to receive data. The tcp_seg
00677  * argument will be freed by the caller (tcp_input()) unless the
00678  * recv_data pointer in the pcb is set.
00679  *
00680  * @param pcb the tcp_pcb for which a segment arrived
00681  *
00682  * @note the segment which arrived is saved in global variables, therefore only the pcb
00683  *       involved is passed as a parameter to this function
00684  */
00685 static err_t
00686 tcp_process(struct tcp_pcb *pcb)
00687 {
00688   struct tcp_seg *rseg;
00689   u8_t acceptable = 0;
00690   err_t err;
00691 
00692   err = ERR_OK;
00693 
00694   /* Process incoming RST segments. */
00695   if (flags & TCP_RST) {
00696     /* First, determine if the reset is acceptable. */
00697     if (pcb->state == SYN_SENT) {
00698       /* "In the SYN-SENT state (a RST received in response to an initial SYN),
00699           the RST is acceptable if the ACK field acknowledges the SYN." */
00700       if (ackno == pcb->snd_nxt) {
00701         acceptable = 1;
00702       }
00703     } else {
00704       /* "In all states except SYN-SENT, all reset (RST) segments are validated
00705           by checking their SEQ-fields." */
00706       if (seqno == pcb->rcv_nxt) {
00707         acceptable = 1;
00708       } else  if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt,
00709                                   pcb->rcv_nxt + pcb->rcv_wnd)) {
00710         /* If the sequence number is inside the window, we only send an ACK
00711            and wait for a re-send with matching sequence number.
00712            This violates RFC 793, but is required to protection against
00713            CVE-2004-0230 (RST spoofing attack). */
00714         tcp_ack_now(pcb);
00715       }
00716     }
00717 
00718     if (acceptable) {
00719       LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: Connection RESET\n"));
00720       LWIP_ASSERT("tcp_input: pcb->state != CLOSED", pcb->state != CLOSED);
00721       recv_flags |= TF_RESET;
00722       pcb->flags &= ~TF_ACK_DELAY;
00723       return ERR_RST;
00724     } else {
00725       LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n",
00726        seqno, pcb->rcv_nxt));
00727       LWIP_DEBUGF(TCP_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n",
00728        seqno, pcb->rcv_nxt));
00729       return ERR_OK;
00730     }
00731   }
00732 
00733   if ((flags & TCP_SYN) && (pcb->state != SYN_SENT && pcb->state != SYN_RCVD)) {
00734     /* Cope with new connection attempt after remote end crashed */
00735     tcp_ack_now(pcb);
00736     return ERR_OK;
00737   }
00738 
00739   if ((pcb->flags & TF_RXCLOSED) == 0) {
00740     /* Update the PCB (in)activity timer unless rx is closed (see tcp_shutdown) */
00741     pcb->tmr = tcp_ticks;
00742   }
00743   pcb->keep_cnt_sent = 0;
00744 
00745   tcp_parseopt(pcb);
00746 
00747   /* Do different things depending on the TCP state. */
00748   switch (pcb->state) {
00749   case SYN_SENT:
00750     LWIP_DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %"U32_F" pcb->snd_nxt %"U32_F" unacked %"U32_F"\n", ackno,
00751      pcb->snd_nxt, ntohl(pcb->unacked->tcphdr->seqno)));
00752     /* received SYN ACK with expected sequence number? */
00753     if ((flags & TCP_ACK) && (flags & TCP_SYN)
00754         && (ackno == pcb->lastack + 1)) {
00755       pcb->rcv_nxt = seqno + 1;
00756       pcb->rcv_ann_right_edge = pcb->rcv_nxt;
00757       pcb->lastack = ackno;
00758       pcb->snd_wnd = SND_WND_SCALE(pcb, tcphdr->wnd);
00759       pcb->snd_wnd_max = pcb->snd_wnd;
00760       pcb->snd_wl1 = seqno - 1; /* initialise to seqno - 1 to force window update */
00761       pcb->state = ESTABLISHED;
00762 
00763 #if TCP_CALCULATE_EFF_SEND_MSS
00764       pcb->mss = tcp_eff_send_mss(pcb->mss, &pcb->local_ip, &pcb->remote_ip);
00765 #endif /* TCP_CALCULATE_EFF_SEND_MSS */
00766 
00767       /* Set ssthresh again after changing 'mss' and 'snd_wnd' */
00768       pcb->ssthresh = LWIP_TCP_INITIAL_SSTHRESH(pcb);
00769 
00770       pcb->cwnd = LWIP_TCP_CALC_INITIAL_CWND(pcb->mss);
00771       LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_process (SENT): cwnd %"TCPWNDSIZE_F
00772                                    " ssthresh %"TCPWNDSIZE_F"\n",
00773                                    pcb->cwnd, pcb->ssthresh));
00774       LWIP_ASSERT("pcb->snd_queuelen > 0", (pcb->snd_queuelen > 0));
00775       --pcb->snd_queuelen;
00776       LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_process: SYN-SENT --queuelen %"TCPWNDSIZE_F"\n", (tcpwnd_size_t)pcb->snd_queuelen));
00777       rseg = pcb->unacked;
00778       if (rseg == NULL) {
00779         /* might happen if tcp_output fails in tcp_rexmit_rto()
00780            in which case the segment is on the unsent list */
00781         rseg = pcb->unsent;
00782         LWIP_ASSERT("no segment to free", rseg != NULL);
00783         pcb->unsent = rseg->next;
00784       } else {
00785         pcb->unacked = rseg->next;
00786       }
00787       tcp_seg_free(rseg);
00788 
00789       /* If there's nothing left to acknowledge, stop the retransmit
00790          timer, otherwise reset it to start again */
00791       if (pcb->unacked == NULL) {
00792         pcb->rtime = -1;
00793       } else {
00794         pcb->rtime = 0;
00795         pcb->nrtx = 0;
00796       }
00797 
00798       /* Call the user specified function to call when successfully
00799        * connected. */
00800       TCP_EVENT_CONNECTED(pcb, ERR_OK, err);
00801       if (err == ERR_ABRT) {
00802         return ERR_ABRT;
00803       }
00804       tcp_ack_now(pcb);
00805     }
00806     /* received ACK? possibly a half-open connection */
00807     else if (flags & TCP_ACK) {
00808       /* send a RST to bring the other side in a non-synchronized state. */
00809       tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(),
00810         ip_current_src_addr(), tcphdr->dest, tcphdr->src);
00811       /* Resend SYN immediately (don't wait for rto timeout) to establish
00812         connection faster */
00813       pcb->rtime = 0;
00814       tcp_rexmit_rto(pcb);
00815     }
00816     break;
00817   case SYN_RCVD:
00818     if (flags & TCP_ACK) {
00819       /* expected ACK number? */
00820       if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)) {
00821         pcb->state = ESTABLISHED;
00822         LWIP_DEBUGF(TCP_DEBUG, ("TCP connection established %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
00823 #if LWIP_CALLBACK_API
00824         LWIP_ASSERT("pcb->listener->accept != NULL",
00825           (pcb->listener == NULL) || (pcb->listener->accept != NULL));
00826         if (pcb->listener == NULL) {
00827           /* listen pcb might be closed by now */
00828           err = ERR_VAL;
00829         } else
00830 #endif
00831         {
00832           tcp_backlog_accepted(pcb);
00833           /* Call the accept function. */
00834           TCP_EVENT_ACCEPT(pcb->listener, pcb, pcb->callback_arg, ERR_OK, err);
00835         }
00836         if (err != ERR_OK) {
00837           /* If the accept function returns with an error, we abort
00838            * the connection. */
00839           /* Already aborted? */
00840           if (err != ERR_ABRT) {
00841             tcp_abort(pcb);
00842           }
00843           return ERR_ABRT;
00844         }
00845         /* If there was any data contained within this ACK,
00846          * we'd better pass it on to the application as well. */
00847         tcp_receive(pcb);
00848 
00849         /* passive open: update initial ssthresh now that the correct window is
00850            known: if the remote side supports window scaling, the window sent
00851            with the initial SYN can be smaller than the one used later */
00852         pcb->ssthresh = LWIP_TCP_INITIAL_SSTHRESH(pcb);
00853 
00854         /* Prevent ACK for SYN to generate a sent event */
00855         if (recv_acked != 0) {
00856           recv_acked--;
00857         }
00858 
00859         pcb->cwnd = LWIP_TCP_CALC_INITIAL_CWND(pcb->mss);
00860         LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_process (SYN_RCVD): cwnd %"TCPWNDSIZE_F
00861                                      " ssthresh %"TCPWNDSIZE_F"\n",
00862                                      pcb->cwnd, pcb->ssthresh));
00863 
00864         if (recv_flags & TF_GOT_FIN) {
00865           tcp_ack_now(pcb);
00866           pcb->state = CLOSE_WAIT;
00867         }
00868       } else {
00869         /* incorrect ACK number, send RST */
00870         tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(),
00871           ip_current_src_addr(), tcphdr->dest, tcphdr->src);
00872       }
00873     } else if ((flags & TCP_SYN) && (seqno == pcb->rcv_nxt - 1)) {
00874       /* Looks like another copy of the SYN - retransmit our SYN-ACK */
00875       tcp_rexmit(pcb);
00876     }
00877     break;
00878   case CLOSE_WAIT:
00879     /* FALLTHROUGH */
00880   case ESTABLISHED:
00881     tcp_receive(pcb);
00882     if (recv_flags & TF_GOT_FIN) { /* passive close */
00883       tcp_ack_now(pcb);
00884       pcb->state = CLOSE_WAIT;
00885     }
00886     break;
00887   case FIN_WAIT_1:
00888     tcp_receive(pcb);
00889     if (recv_flags & TF_GOT_FIN) {
00890       if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) {
00891         LWIP_DEBUGF(TCP_DEBUG,
00892           ("TCP connection closed: FIN_WAIT_1 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
00893         tcp_ack_now(pcb);
00894         tcp_pcb_purge(pcb);
00895         TCP_RMV_ACTIVE(pcb);
00896         pcb->state = TIME_WAIT;
00897         TCP_REG(&tcp_tw_pcbs, pcb);
00898       } else {
00899         tcp_ack_now(pcb);
00900         pcb->state = CLOSING;
00901       }
00902     } else if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) {
00903       pcb->state = FIN_WAIT_2;
00904     }
00905     break;
00906   case FIN_WAIT_2:
00907     tcp_receive(pcb);
00908     if (recv_flags & TF_GOT_FIN) {
00909       LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: FIN_WAIT_2 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
00910       tcp_ack_now(pcb);
00911       tcp_pcb_purge(pcb);
00912       TCP_RMV_ACTIVE(pcb);
00913       pcb->state = TIME_WAIT;
00914       TCP_REG(&tcp_tw_pcbs, pcb);
00915     }
00916     break;
00917   case CLOSING:
00918     tcp_receive(pcb);
00919     if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
00920       LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: CLOSING %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
00921       tcp_pcb_purge(pcb);
00922       TCP_RMV_ACTIVE(pcb);
00923       pcb->state = TIME_WAIT;
00924       TCP_REG(&tcp_tw_pcbs, pcb);
00925     }
00926     break;
00927   case LAST_ACK:
00928     tcp_receive(pcb);
00929     if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
00930       LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: LAST_ACK %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
00931       /* bugfix #21699: don't set pcb->state to CLOSED here or we risk leaking segments */
00932       recv_flags |= TF_CLOSED;
00933     }
00934     break;
00935   default:
00936     break;
00937   }
00938   return ERR_OK;
00939 }
00940 
00941 #if TCP_QUEUE_OOSEQ
00942 /**
00943  * Insert segment into the list (segments covered with new one will be deleted)
00944  *
00945  * Called from tcp_receive()
00946  */
00947 static void
00948 tcp_oos_insert_segment(struct tcp_seg *cseg, struct tcp_seg *next)
00949 {
00950   struct tcp_seg *old_seg;
00951 
00952   if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) {
00953     /* received segment overlaps all following segments */
00954     tcp_segs_free(next);
00955     next = NULL;
00956   } else {
00957     /* delete some following segments
00958        oos queue may have segments with FIN flag */
00959     while (next &&
00960            TCP_SEQ_GEQ((seqno + cseg->len),
00961                       (next->tcphdr->seqno + next->len))) {
00962       /* cseg with FIN already processed */
00963       if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) {
00964         TCPH_SET_FLAG(cseg->tcphdr, TCP_FIN);
00965       }
00966       old_seg = next;
00967       next = next->next;
00968       tcp_seg_free(old_seg);
00969     }
00970     if (next &&
00971         TCP_SEQ_GT(seqno + cseg->len, next->tcphdr->seqno)) {
00972       /* We need to trim the incoming segment. */
00973       cseg->len = (u16_t)(next->tcphdr->seqno - seqno);
00974       pbuf_realloc(cseg->p, cseg->len);
00975     }
00976   }
00977   cseg->next = next;
00978 }
00979 #endif /* TCP_QUEUE_OOSEQ */
00980 
00981 /**
00982  * Called by tcp_process. Checks if the given segment is an ACK for outstanding
00983  * data, and if so frees the memory of the buffered data. Next, it places the
00984  * segment on any of the receive queues (pcb->recved or pcb->ooseq). If the segment
00985  * is buffered, the pbuf is referenced by pbuf_ref so that it will not be freed until
00986  * it has been removed from the buffer.
00987  *
00988  * If the incoming segment constitutes an ACK for a segment that was used for RTT
00989  * estimation, the RTT is estimated here as well.
00990  *
00991  * Called from tcp_process().
00992  */
00993 static void
00994 tcp_receive(struct tcp_pcb *pcb)
00995 {
00996   struct tcp_seg *next;
00997 #if TCP_QUEUE_OOSEQ
00998   struct tcp_seg *prev, *cseg;
00999 #endif /* TCP_QUEUE_OOSEQ */
01000   struct pbuf *p;
01001   s32_t off;
01002   s16_t m;
01003   u32_t right_wnd_edge;
01004   u16_t new_tot_len;
01005   int found_dupack = 0;
01006 #if TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS
01007   u32_t ooseq_blen;
01008   u16_t ooseq_qlen;
01009 #endif /* TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS */
01010 
01011   LWIP_ASSERT("tcp_receive: wrong state", pcb->state >= ESTABLISHED);
01012 
01013   if (flags & TCP_ACK) {
01014     right_wnd_edge = pcb->snd_wnd + pcb->snd_wl2;
01015 
01016     /* Update window. */
01017     if (TCP_SEQ_LT(pcb->snd_wl1, seqno) ||
01018        (pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) ||
01019        (pcb->snd_wl2 == ackno && (u32_t)SND_WND_SCALE(pcb, tcphdr->wnd) > pcb->snd_wnd)) {
01020       pcb->snd_wnd = SND_WND_SCALE(pcb, tcphdr->wnd);
01021       /* keep track of the biggest window announced by the remote host to calculate
01022          the maximum segment size */
01023       if (pcb->snd_wnd_max < pcb->snd_wnd) {
01024         pcb->snd_wnd_max = pcb->snd_wnd;
01025       }
01026       pcb->snd_wl1 = seqno;
01027       pcb->snd_wl2 = ackno;
01028       if (pcb->snd_wnd == 0) {
01029         if (pcb->persist_backoff == 0) {
01030           /* start persist timer */
01031           pcb->persist_cnt = 0;
01032           pcb->persist_backoff = 1;
01033         }
01034       } else if (pcb->persist_backoff > 0) {
01035         /* stop persist timer */
01036           pcb->persist_backoff = 0;
01037       }
01038       LWIP_DEBUGF(TCP_WND_DEBUG, ("tcp_receive: window update %"TCPWNDSIZE_F"\n", pcb->snd_wnd));
01039 #if TCP_WND_DEBUG
01040     } else {
01041       if (pcb->snd_wnd != (tcpwnd_size_t)SND_WND_SCALE(pcb, tcphdr->wnd)) {
01042         LWIP_DEBUGF(TCP_WND_DEBUG,
01043                     ("tcp_receive: no window update lastack %"U32_F" ackno %"
01044                      U32_F" wl1 %"U32_F" seqno %"U32_F" wl2 %"U32_F"\n",
01045                      pcb->lastack, ackno, pcb->snd_wl1, seqno, pcb->snd_wl2));
01046       }
01047 #endif /* TCP_WND_DEBUG */
01048     }
01049 
01050     /* (From Stevens TCP/IP Illustrated Vol II, p970.) Its only a
01051      * duplicate ack if:
01052      * 1) It doesn't ACK new data
01053      * 2) length of received packet is zero (i.e. no payload)
01054      * 3) the advertised window hasn't changed
01055      * 4) There is outstanding unacknowledged data (retransmission timer running)
01056      * 5) The ACK is == biggest ACK sequence number so far seen (snd_una)
01057      *
01058      * If it passes all five, should process as a dupack:
01059      * a) dupacks < 3: do nothing
01060      * b) dupacks == 3: fast retransmit
01061      * c) dupacks > 3: increase cwnd
01062      *
01063      * If it only passes 1-3, should reset dupack counter (and add to
01064      * stats, which we don't do in lwIP)
01065      *
01066      * If it only passes 1, should reset dupack counter
01067      *
01068      */
01069 
01070     /* Clause 1 */
01071     if (TCP_SEQ_LEQ(ackno, pcb->lastack)) {
01072       /* Clause 2 */
01073       if (tcplen == 0) {
01074         /* Clause 3 */
01075         if (pcb->snd_wl2 + pcb->snd_wnd == right_wnd_edge) {
01076           /* Clause 4 */
01077           if (pcb->rtime >= 0) {
01078             /* Clause 5 */
01079             if (pcb->lastack == ackno) {
01080               found_dupack = 1;
01081               if ((u8_t)(pcb->dupacks + 1) > pcb->dupacks) {
01082                 ++pcb->dupacks;
01083               }
01084               if (pcb->dupacks > 3) {
01085                 /* Inflate the congestion window, but not if it means that
01086                    the value overflows. */
01087                 if ((tcpwnd_size_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {
01088                   pcb->cwnd += pcb->mss;
01089                 }
01090               } else if (pcb->dupacks == 3) {
01091                 /* Do fast retransmit */
01092                 tcp_rexmit_fast(pcb);
01093               }
01094             }
01095           }
01096         }
01097       }
01098       /* If Clause (1) or more is true, but not a duplicate ack, reset
01099        * count of consecutive duplicate acks */
01100       if (!found_dupack) {
01101         pcb->dupacks = 0;
01102       }
01103     } else if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)) {
01104       /* We come here when the ACK acknowledges new data. */
01105 
01106       /* Reset the "IN Fast Retransmit" flag, since we are no longer
01107          in fast retransmit. Also reset the congestion window to the
01108          slow start threshold. */
01109       if (pcb->flags & TF_INFR) {
01110         pcb->flags &= ~TF_INFR;
01111         pcb->cwnd = pcb->ssthresh;
01112       }
01113 
01114       /* Reset the number of retransmissions. */
01115       pcb->nrtx = 0;
01116 
01117       /* Reset the retransmission time-out. */
01118       pcb->rto = (pcb->sa >> 3) + pcb->sv;
01119 
01120       /* Reset the fast retransmit variables. */
01121       pcb->dupacks = 0;
01122       pcb->lastack = ackno;
01123 
01124       /* Update the congestion control variables (cwnd and
01125          ssthresh). */
01126       if (pcb->state >= ESTABLISHED) {
01127         if (pcb->cwnd < pcb->ssthresh) {
01128           if ((tcpwnd_size_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {
01129             pcb->cwnd += pcb->mss;
01130           }
01131           LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: slow start cwnd %"TCPWNDSIZE_F"\n", pcb->cwnd));
01132         } else {
01133           tcpwnd_size_t new_cwnd = (pcb->cwnd + pcb->mss * pcb->mss / pcb->cwnd);
01134           if (new_cwnd > pcb->cwnd) {
01135             pcb->cwnd = new_cwnd;
01136           }
01137           LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: congestion avoidance cwnd %"TCPWNDSIZE_F"\n", pcb->cwnd));
01138         }
01139       }
01140       LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: ACK for %"U32_F", unacked->seqno %"U32_F":%"U32_F"\n",
01141                                     ackno,
01142                                     pcb->unacked != NULL?
01143                                     ntohl(pcb->unacked->tcphdr->seqno): 0,
01144                                     pcb->unacked != NULL?
01145                                     ntohl(pcb->unacked->tcphdr->seqno) + TCP_TCPLEN(pcb->unacked): 0));
01146 
01147       /* Remove segment from the unacknowledged list if the incoming
01148          ACK acknowledges them. */
01149       while (pcb->unacked != NULL &&
01150              TCP_SEQ_LEQ(ntohl(pcb->unacked->tcphdr->seqno) +
01151                          TCP_TCPLEN(pcb->unacked), ackno)) {
01152         LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unacked\n",
01153                                       ntohl(pcb->unacked->tcphdr->seqno),
01154                                       ntohl(pcb->unacked->tcphdr->seqno) +
01155                                       TCP_TCPLEN(pcb->unacked)));
01156 
01157         next = pcb->unacked;
01158         pcb->unacked = pcb->unacked->next;
01159 
01160         LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"TCPWNDSIZE_F" ... ", (tcpwnd_size_t)pcb->snd_queuelen));
01161         LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p)));
01162 
01163         pcb->snd_queuelen -= pbuf_clen(next->p);
01164         recv_acked += next->len;
01165         tcp_seg_free(next);
01166 
01167         LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"TCPWNDSIZE_F" (after freeing unacked)\n", (tcpwnd_size_t)pcb->snd_queuelen));
01168         if (pcb->snd_queuelen != 0) {
01169           LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL ||
01170                       pcb->unsent != NULL);
01171         }
01172       }
01173 
01174       /* If there's nothing left to acknowledge, stop the retransmit
01175          timer, otherwise reset it to start again */
01176       if (pcb->unacked == NULL) {
01177         pcb->rtime = -1;
01178       } else {
01179         pcb->rtime = 0;
01180       }
01181 
01182       pcb->polltmr = 0;
01183 
01184 #if LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS
01185       if (ip_current_is_v6()) {
01186         /* Inform neighbor reachability of forward progress. */
01187         nd6_reachability_hint(ip6_current_src_addr());
01188       }
01189 #endif /* LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS*/
01190     } else {
01191       /* Out of sequence ACK, didn't really ack anything */
01192       tcp_send_empty_ack(pcb);
01193     }
01194 
01195     /* We go through the ->unsent list to see if any of the segments
01196        on the list are acknowledged by the ACK. This may seem
01197        strange since an "unsent" segment shouldn't be acked. The
01198        rationale is that lwIP puts all outstanding segments on the
01199        ->unsent list after a retransmission, so these segments may
01200        in fact have been sent once. */
01201     while (pcb->unsent != NULL &&
01202            TCP_SEQ_BETWEEN(ackno, ntohl(pcb->unsent->tcphdr->seqno) +
01203                            TCP_TCPLEN(pcb->unsent), pcb->snd_nxt)) {
01204       LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unsent\n",
01205                                     ntohl(pcb->unsent->tcphdr->seqno), ntohl(pcb->unsent->tcphdr->seqno) +
01206                                     TCP_TCPLEN(pcb->unsent)));
01207 
01208       next = pcb->unsent;
01209       pcb->unsent = pcb->unsent->next;
01210 #if TCP_OVERSIZE
01211       if (pcb->unsent == NULL) {
01212         pcb->unsent_oversize = 0;
01213       }
01214 #endif /* TCP_OVERSIZE */
01215       LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"TCPWNDSIZE_F" ... ", (tcpwnd_size_t)pcb->snd_queuelen));
01216       LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p)));
01217       /* Prevent ACK for FIN to generate a sent event */
01218       pcb->snd_queuelen -= pbuf_clen(next->p);
01219       recv_acked += next->len;
01220       tcp_seg_free(next);
01221       LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"TCPWNDSIZE_F" (after freeing unsent)\n", (tcpwnd_size_t)pcb->snd_queuelen));
01222       if (pcb->snd_queuelen != 0) {
01223         LWIP_ASSERT("tcp_receive: valid queue length",
01224           pcb->unacked != NULL || pcb->unsent != NULL);
01225       }
01226     }
01227     pcb->snd_buf += recv_acked;
01228     /* End of ACK for new data processing. */
01229 
01230     LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: pcb->rttest %"U32_F" rtseq %"U32_F" ackno %"U32_F"\n",
01231                                 pcb->rttest, pcb->rtseq, ackno));
01232 
01233     /* RTT estimation calculations. This is done by checking if the
01234        incoming segment acknowledges the segment we use to take a
01235        round-trip time measurement. */
01236     if (pcb->rttest && TCP_SEQ_LT(pcb->rtseq, ackno)) {
01237       /* diff between this shouldn't exceed 32K since this are tcp timer ticks
01238          and a round-trip shouldn't be that long... */
01239       m = (s16_t)(tcp_ticks - pcb->rttest);
01240 
01241       LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: experienced rtt %"U16_F" ticks (%"U16_F" msec).\n",
01242                                   m, (u16_t)(m * TCP_SLOW_INTERVAL)));
01243 
01244       /* This is taken directly from VJs original code in his paper */
01245       m = m - (pcb->sa >> 3);
01246       pcb->sa += m;
01247       if (m < 0) {
01248         m = -m;
01249       }
01250       m = m - (pcb->sv >> 2);
01251       pcb->sv += m;
01252       pcb->rto = (pcb->sa >> 3) + pcb->sv;
01253 
01254       LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: RTO %"U16_F" (%"U16_F" milliseconds)\n",
01255                                   pcb->rto, (u16_t)(pcb->rto * TCP_SLOW_INTERVAL)));
01256 
01257       pcb->rttest = 0;
01258     }
01259   }
01260 
01261   /* If the incoming segment contains data, we must process it
01262      further unless the pcb already received a FIN.
01263      (RFC 793, chapter 3.9, "SEGMENT ARRIVES" in states CLOSE-WAIT, CLOSING,
01264      LAST-ACK and TIME-WAIT: "Ignore the segment text.") */
01265   if ((tcplen > 0) && (pcb->state < CLOSE_WAIT)) {
01266     /* This code basically does three things:
01267 
01268     +) If the incoming segment contains data that is the next
01269     in-sequence data, this data is passed to the application. This
01270     might involve trimming the first edge of the data. The rcv_nxt
01271     variable and the advertised window are adjusted.
01272 
01273     +) If the incoming segment has data that is above the next
01274     sequence number expected (->rcv_nxt), the segment is placed on
01275     the ->ooseq queue. This is done by finding the appropriate
01276     place in the ->ooseq queue (which is ordered by sequence
01277     number) and trim the segment in both ends if needed. An
01278     immediate ACK is sent to indicate that we received an
01279     out-of-sequence segment.
01280 
01281     +) Finally, we check if the first segment on the ->ooseq queue
01282     now is in sequence (i.e., if rcv_nxt >= ooseq->seqno). If
01283     rcv_nxt > ooseq->seqno, we must trim the first edge of the
01284     segment on ->ooseq before we adjust rcv_nxt. The data in the
01285     segments that are now on sequence are chained onto the
01286     incoming segment so that we only need to call the application
01287     once.
01288     */
01289 
01290     /* First, we check if we must trim the first edge. We have to do
01291        this if the sequence number of the incoming segment is less
01292        than rcv_nxt, and the sequence number plus the length of the
01293        segment is larger than rcv_nxt. */
01294     /*    if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)) {
01295           if (TCP_SEQ_LT(pcb->rcv_nxt, seqno + tcplen)) {*/
01296     if (TCP_SEQ_BETWEEN(pcb->rcv_nxt, seqno + 1, seqno + tcplen - 1)) {
01297       /* Trimming the first edge is done by pushing the payload
01298          pointer in the pbuf downwards. This is somewhat tricky since
01299          we do not want to discard the full contents of the pbuf up to
01300          the new starting point of the data since we have to keep the
01301          TCP header which is present in the first pbuf in the chain.
01302 
01303          What is done is really quite a nasty hack: the first pbuf in
01304          the pbuf chain is pointed to by inseg.p. Since we need to be
01305          able to deallocate the whole pbuf, we cannot change this
01306          inseg.p pointer to point to any of the later pbufs in the
01307          chain. Instead, we point the ->payload pointer in the first
01308          pbuf to data in one of the later pbufs. We also set the
01309          inseg.data pointer to point to the right place. This way, the
01310          ->p pointer will still point to the first pbuf, but the
01311          ->p->payload pointer will point to data in another pbuf.
01312 
01313          After we are done with adjusting the pbuf pointers we must
01314          adjust the ->data pointer in the seg and the segment
01315          length.*/
01316 
01317       off = pcb->rcv_nxt - seqno;
01318       p = inseg.p;
01319       LWIP_ASSERT("inseg.p != NULL", inseg.p);
01320       LWIP_ASSERT("insane offset!", (off < 0x7fff));
01321       if (inseg.p->len < off) {
01322         LWIP_ASSERT("pbuf too short!", (((s32_t)inseg.p->tot_len) >= off));
01323         new_tot_len = (u16_t)(inseg.p->tot_len - off);
01324         while (p->len < off) {
01325           off -= p->len;
01326           /* KJM following line changed (with addition of new_tot_len var)
01327              to fix bug #9076
01328              inseg.p->tot_len -= p->len; */
01329           p->tot_len = new_tot_len;
01330           p->len = 0;
01331           p = p->next;
01332         }
01333         if (pbuf_header(p, (s16_t)-off)) {
01334           /* Do we need to cope with this failing?  Assert for now */
01335           LWIP_ASSERT("pbuf_header failed", 0);
01336         }
01337       } else {
01338         if (pbuf_header(inseg.p, (s16_t)-off)) {
01339           /* Do we need to cope with this failing?  Assert for now */
01340           LWIP_ASSERT("pbuf_header failed", 0);
01341         }
01342       }
01343       inseg.len -= (u16_t)(pcb->rcv_nxt - seqno);
01344       inseg.tcphdr->seqno = seqno = pcb->rcv_nxt;
01345     }
01346     else {
01347       if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)) {
01348         /* the whole segment is < rcv_nxt */
01349         /* must be a duplicate of a packet that has already been correctly handled */
01350 
01351         LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: duplicate seqno %"U32_F"\n", seqno));
01352         tcp_ack_now(pcb);
01353       }
01354     }
01355 
01356     /* The sequence number must be within the window (above rcv_nxt
01357        and below rcv_nxt + rcv_wnd) in order to be further
01358        processed. */
01359     if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt,
01360                         pcb->rcv_nxt + pcb->rcv_wnd - 1)) {
01361       if (pcb->rcv_nxt == seqno) {
01362         /* The incoming segment is the next in sequence. We check if
01363            we have to trim the end of the segment and update rcv_nxt
01364            and pass the data to the application. */
01365         tcplen = TCP_TCPLEN(&inseg);
01366 
01367         if (tcplen > pcb->rcv_wnd) {
01368           LWIP_DEBUGF(TCP_INPUT_DEBUG,
01369                       ("tcp_receive: other end overran receive window"
01370                        "seqno %"U32_F" len %"U16_F" right edge %"U32_F"\n",
01371                        seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd));
01372           if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
01373             /* Must remove the FIN from the header as we're trimming
01374              * that byte of sequence-space from the packet */
01375             TCPH_FLAGS_SET(inseg.tcphdr, TCPH_FLAGS(inseg.tcphdr) & ~(unsigned int)TCP_FIN);
01376           }
01377           /* Adjust length of segment to fit in the window. */
01378           TCPWND_CHECK16(pcb->rcv_wnd);
01379           inseg.len = (u16_t)pcb->rcv_wnd;
01380           if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) {
01381             inseg.len -= 1;
01382           }
01383           pbuf_realloc(inseg.p, inseg.len);
01384           tcplen = TCP_TCPLEN(&inseg);
01385           LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n",
01386                       (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd));
01387         }
01388 #if TCP_QUEUE_OOSEQ
01389         /* Received in-sequence data, adjust ooseq data if:
01390            - FIN has been received or
01391            - inseq overlaps with ooseq */
01392         if (pcb->ooseq != NULL) {
01393           if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
01394             LWIP_DEBUGF(TCP_INPUT_DEBUG,
01395                         ("tcp_receive: received in-order FIN, binning ooseq queue\n"));
01396             /* Received in-order FIN means anything that was received
01397              * out of order must now have been received in-order, so
01398              * bin the ooseq queue */
01399             while (pcb->ooseq != NULL) {
01400               struct tcp_seg *old_ooseq = pcb->ooseq;
01401               pcb->ooseq = pcb->ooseq->next;
01402               tcp_seg_free(old_ooseq);
01403             }
01404           } else {
01405             next = pcb->ooseq;
01406             /* Remove all segments on ooseq that are covered by inseg already.
01407              * FIN is copied from ooseq to inseg if present. */
01408             while (next &&
01409                    TCP_SEQ_GEQ(seqno + tcplen,
01410                                next->tcphdr->seqno + next->len)) {
01411               /* inseg cannot have FIN here (already processed above) */
01412               if (TCPH_FLAGS(next->tcphdr) & TCP_FIN &&
01413                   (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) == 0) {
01414                 TCPH_SET_FLAG(inseg.tcphdr, TCP_FIN);
01415                 tcplen = TCP_TCPLEN(&inseg);
01416               }
01417               prev = next;
01418               next = next->next;
01419               tcp_seg_free(prev);
01420             }
01421             /* Now trim right side of inseg if it overlaps with the first
01422              * segment on ooseq */
01423             if (next &&
01424                 TCP_SEQ_GT(seqno + tcplen,
01425                            next->tcphdr->seqno)) {
01426               /* inseg cannot have FIN here (already processed above) */
01427               inseg.len = (u16_t)(next->tcphdr->seqno - seqno);
01428               if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) {
01429                 inseg.len -= 1;
01430               }
01431               pbuf_realloc(inseg.p, inseg.len);
01432               tcplen = TCP_TCPLEN(&inseg);
01433               LWIP_ASSERT("tcp_receive: segment not trimmed correctly to ooseq queue\n",
01434                           (seqno + tcplen) == next->tcphdr->seqno);
01435             }
01436             pcb->ooseq = next;
01437           }
01438         }
01439 #endif /* TCP_QUEUE_OOSEQ */
01440 
01441         pcb->rcv_nxt = seqno + tcplen;
01442 
01443         /* Update the receiver's (our) window. */
01444         LWIP_ASSERT("tcp_receive: tcplen > rcv_wnd\n", pcb->rcv_wnd >= tcplen);
01445         pcb->rcv_wnd -= tcplen;
01446 
01447         tcp_update_rcv_ann_wnd(pcb);
01448 
01449         /* If there is data in the segment, we make preparations to
01450            pass this up to the application. The ->recv_data variable
01451            is used for holding the pbuf that goes to the
01452            application. The code for reassembling out-of-sequence data
01453            chains its data on this pbuf as well.
01454 
01455            If the segment was a FIN, we set the TF_GOT_FIN flag that will
01456            be used to indicate to the application that the remote side has
01457            closed its end of the connection. */
01458         if (inseg.p->tot_len > 0) {
01459           recv_data = inseg.p;
01460           /* Since this pbuf now is the responsibility of the
01461              application, we delete our reference to it so that we won't
01462              (mistakingly) deallocate it. */
01463           inseg.p = NULL;
01464         }
01465         if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
01466           LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN.\n"));
01467           recv_flags |= TF_GOT_FIN;
01468         }
01469 
01470 #if TCP_QUEUE_OOSEQ
01471         /* We now check if we have segments on the ->ooseq queue that
01472            are now in sequence. */
01473         while (pcb->ooseq != NULL &&
01474                pcb->ooseq->tcphdr->seqno == pcb->rcv_nxt) {
01475 
01476           cseg = pcb->ooseq;
01477           seqno = pcb->ooseq->tcphdr->seqno;
01478 
01479           pcb->rcv_nxt += TCP_TCPLEN(cseg);
01480           LWIP_ASSERT("tcp_receive: ooseq tcplen > rcv_wnd\n",
01481                       pcb->rcv_wnd >= TCP_TCPLEN(cseg));
01482           pcb->rcv_wnd -= TCP_TCPLEN(cseg);
01483 
01484           tcp_update_rcv_ann_wnd(pcb);
01485 
01486           if (cseg->p->tot_len > 0) {
01487             /* Chain this pbuf onto the pbuf that we will pass to
01488                the application. */
01489             /* With window scaling, this can overflow recv_data->tot_len, but
01490                that's not a problem since we explicitly fix that before passing
01491                recv_data to the application. */
01492             if (recv_data) {
01493               pbuf_cat(recv_data, cseg->p);
01494             } else {
01495               recv_data = cseg->p;
01496             }
01497             cseg->p = NULL;
01498           }
01499           if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) {
01500             LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN.\n"));
01501             recv_flags |= TF_GOT_FIN;
01502             if (pcb->state == ESTABLISHED) { /* force passive close or we can move to active close */
01503               pcb->state = CLOSE_WAIT;
01504             }
01505           }
01506 
01507           pcb->ooseq = cseg->next;
01508           tcp_seg_free(cseg);
01509         }
01510 #endif /* TCP_QUEUE_OOSEQ */
01511 
01512 
01513         /* Acknowledge the segment(s). */
01514         tcp_ack(pcb);
01515 
01516 #if LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS
01517         if (ip_current_is_v6()) {
01518           /* Inform neighbor reachability of forward progress. */
01519           nd6_reachability_hint(ip6_current_src_addr());
01520         }
01521 #endif /* LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS*/
01522 
01523       } else {
01524         /* We get here if the incoming segment is out-of-sequence. */
01525         tcp_send_empty_ack(pcb);
01526 #if TCP_QUEUE_OOSEQ
01527         /* We queue the segment on the ->ooseq queue. */
01528         if (pcb->ooseq == NULL) {
01529           pcb->ooseq = tcp_seg_copy(&inseg);
01530         } else {
01531           /* If the queue is not empty, we walk through the queue and
01532              try to find a place where the sequence number of the
01533              incoming segment is between the sequence numbers of the
01534              previous and the next segment on the ->ooseq queue. That is
01535              the place where we put the incoming segment. If needed, we
01536              trim the second edges of the previous and the incoming
01537              segment so that it will fit into the sequence.
01538 
01539              If the incoming segment has the same sequence number as a
01540              segment on the ->ooseq queue, we discard the segment that
01541              contains less data. */
01542 
01543           prev = NULL;
01544           for (next = pcb->ooseq; next != NULL; next = next->next) {
01545             if (seqno == next->tcphdr->seqno) {
01546               /* The sequence number of the incoming segment is the
01547                  same as the sequence number of the segment on
01548                  ->ooseq. We check the lengths to see which one to
01549                  discard. */
01550               if (inseg.len > next->len) {
01551                 /* The incoming segment is larger than the old
01552                    segment. We replace some segments with the new
01553                    one. */
01554                 cseg = tcp_seg_copy(&inseg);
01555                 if (cseg != NULL) {
01556                   if (prev != NULL) {
01557                     prev->next = cseg;
01558                   } else {
01559                     pcb->ooseq = cseg;
01560                   }
01561                   tcp_oos_insert_segment(cseg, next);
01562                 }
01563                 break;
01564               } else {
01565                 /* Either the lengths are the same or the incoming
01566                    segment was smaller than the old one; in either
01567                    case, we ditch the incoming segment. */
01568                 break;
01569               }
01570             } else {
01571               if (prev == NULL) {
01572                 if (TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {
01573                   /* The sequence number of the incoming segment is lower
01574                      than the sequence number of the first segment on the
01575                      queue. We put the incoming segment first on the
01576                      queue. */
01577                   cseg = tcp_seg_copy(&inseg);
01578                   if (cseg != NULL) {
01579                     pcb->ooseq = cseg;
01580                     tcp_oos_insert_segment(cseg, next);
01581                   }
01582                   break;
01583                 }
01584               } else {
01585                 /*if (TCP_SEQ_LT(prev->tcphdr->seqno, seqno) &&
01586                   TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {*/
01587                 if (TCP_SEQ_BETWEEN(seqno, prev->tcphdr->seqno+1, next->tcphdr->seqno-1)) {
01588                   /* The sequence number of the incoming segment is in
01589                      between the sequence numbers of the previous and
01590                      the next segment on ->ooseq. We trim trim the previous
01591                      segment, delete next segments that included in received segment
01592                      and trim received, if needed. */
01593                   cseg = tcp_seg_copy(&inseg);
01594                   if (cseg != NULL) {
01595                     if (TCP_SEQ_GT(prev->tcphdr->seqno + prev->len, seqno)) {
01596                       /* We need to trim the prev segment. */
01597                       prev->len = (u16_t)(seqno - prev->tcphdr->seqno);
01598                       pbuf_realloc(prev->p, prev->len);
01599                     }
01600                     prev->next = cseg;
01601                     tcp_oos_insert_segment(cseg, next);
01602                   }
01603                   break;
01604                 }
01605               }
01606               /* If the "next" segment is the last segment on the
01607                  ooseq queue, we add the incoming segment to the end
01608                  of the list. */
01609               if (next->next == NULL &&
01610                   TCP_SEQ_GT(seqno, next->tcphdr->seqno)) {
01611                 if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) {
01612                   /* segment "next" already contains all data */
01613                   break;
01614                 }
01615                 next->next = tcp_seg_copy(&inseg);
01616                 if (next->next != NULL) {
01617                   if (TCP_SEQ_GT(next->tcphdr->seqno + next->len, seqno)) {
01618                     /* We need to trim the last segment. */
01619                     next->len = (u16_t)(seqno - next->tcphdr->seqno);
01620                     pbuf_realloc(next->p, next->len);
01621                   }
01622                   /* check if the remote side overruns our receive window */
01623                   if (TCP_SEQ_GT((u32_t)tcplen + seqno, pcb->rcv_nxt + (u32_t)pcb->rcv_wnd)) {
01624                     LWIP_DEBUGF(TCP_INPUT_DEBUG,
01625                                 ("tcp_receive: other end overran receive window"
01626                                  "seqno %"U32_F" len %"U16_F" right edge %"U32_F"\n",
01627                                  seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd));
01628                     if (TCPH_FLAGS(next->next->tcphdr) & TCP_FIN) {
01629                       /* Must remove the FIN from the header as we're trimming
01630                        * that byte of sequence-space from the packet */
01631                       TCPH_FLAGS_SET(next->next->tcphdr, TCPH_FLAGS(next->next->tcphdr) & ~TCP_FIN);
01632                     }
01633                     /* Adjust length of segment to fit in the window. */
01634                     next->next->len = (u16_t)(pcb->rcv_nxt + pcb->rcv_wnd - seqno);
01635                     pbuf_realloc(next->next->p, next->next->len);
01636                     tcplen = TCP_TCPLEN(next->next);
01637                     LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n",
01638                                 (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd));
01639                   }
01640                 }
01641                 break;
01642               }
01643             }
01644             prev = next;
01645           }
01646         }
01647 #if TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS
01648         /* Check that the data on ooseq doesn't exceed one of the limits
01649            and throw away everything above that limit. */
01650         ooseq_blen = 0;
01651         ooseq_qlen = 0;
01652         prev = NULL;
01653         for (next = pcb->ooseq; next != NULL; prev = next, next = next->next) {
01654           struct pbuf *p = next->p;
01655           ooseq_blen += p->tot_len;
01656           ooseq_qlen += pbuf_clen(p);
01657           if ((ooseq_blen > TCP_OOSEQ_MAX_BYTES) ||
01658               (ooseq_qlen > TCP_OOSEQ_MAX_PBUFS)) {
01659              /* too much ooseq data, dump this and everything after it */
01660              tcp_segs_free(next);
01661              if (prev == NULL) {
01662                /* first ooseq segment is too much, dump the whole queue */
01663                pcb->ooseq = NULL;
01664              } else {
01665                /* just dump 'next' and everything after it */
01666                prev->next = NULL;
01667              }
01668              break;
01669           }
01670         }
01671 #endif /* TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS */
01672 #endif /* TCP_QUEUE_OOSEQ */
01673       }
01674     } else {
01675       /* The incoming segment is not within the window. */
01676       tcp_send_empty_ack(pcb);
01677     }
01678   } else {
01679     /* Segments with length 0 is taken care of here. Segments that
01680        fall out of the window are ACKed. */
01681     if (!TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd - 1)) {
01682       tcp_ack_now(pcb);
01683     }
01684   }
01685 }
01686 
01687 static u8_t
01688 tcp_getoptbyte(void)
01689 {
01690   if ((tcphdr_opt2 == NULL) || (tcp_optidx < tcphdr_opt1len)) {
01691     u8_t* opts = (u8_t *)tcphdr + TCP_HLEN;
01692     return opts[tcp_optidx++];
01693   } else {
01694     u8_t idx = (u8_t)(tcp_optidx++ - tcphdr_opt1len);
01695     return tcphdr_opt2[idx];
01696   }
01697 }
01698 
01699 /**
01700  * Parses the options contained in the incoming segment.
01701  *
01702  * Called from tcp_listen_input() and tcp_process().
01703  * Currently, only the MSS option is supported!
01704  *
01705  * @param pcb the tcp_pcb for which a segment arrived
01706  */
01707 static void
01708 tcp_parseopt(struct tcp_pcb *pcb)
01709 {
01710   u8_t data;
01711   u16_t mss;
01712 #if LWIP_TCP_TIMESTAMPS
01713   u32_t tsval;
01714 #endif
01715 
01716   /* Parse the TCP MSS option, if present. */
01717   if (tcphdr_optlen != 0) {
01718     for (tcp_optidx = 0; tcp_optidx < tcphdr_optlen; ) {
01719       u8_t opt = tcp_getoptbyte();
01720       switch (opt) {
01721       case LWIP_TCP_OPT_EOL:
01722         /* End of options. */
01723         LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: EOL\n"));
01724         return;
01725       case LWIP_TCP_OPT_NOP:
01726         /* NOP option. */
01727         LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: NOP\n"));
01728         break;
01729       case LWIP_TCP_OPT_MSS:
01730         LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: MSS\n"));
01731         if (tcp_getoptbyte() != LWIP_TCP_OPT_LEN_MSS || (tcp_optidx - 2 + LWIP_TCP_OPT_LEN_MSS) > tcphdr_optlen) {
01732           /* Bad length */
01733           LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
01734           return;
01735         }
01736         /* An MSS option with the right option length. */
01737         mss = (tcp_getoptbyte() << 8);
01738         mss |= tcp_getoptbyte();
01739         /* Limit the mss to the configured TCP_MSS and prevent division by zero */
01740         pcb->mss = ((mss > TCP_MSS) || (mss == 0)) ? TCP_MSS : mss;
01741         break;
01742 #if LWIP_WND_SCALE
01743       case LWIP_TCP_OPT_WS:
01744         LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: WND_SCALE\n"));
01745         if (tcp_getoptbyte() != LWIP_TCP_OPT_LEN_WS || (tcp_optidx - 2 + LWIP_TCP_OPT_LEN_WS) > tcphdr_optlen) {
01746           /* Bad length */
01747           LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
01748           return;
01749         }
01750         /* If syn was received with wnd scale option,
01751            activate wnd scale opt, but only if this is not a retransmission */
01752         if ((flags & TCP_SYN) && !(pcb->flags & TF_WND_SCALE)) {
01753           /* An WND_SCALE option with the right option length. */
01754           data = tcp_getoptbyte();
01755           pcb->snd_scale = data;
01756           if (pcb->snd_scale > 14U) {
01757             pcb->snd_scale = 14U;
01758           }
01759           pcb->rcv_scale = TCP_RCV_SCALE;
01760           pcb->flags |= TF_WND_SCALE;
01761           /* window scaling is enabled, we can use the full receive window */
01762           LWIP_ASSERT("window not at default value", pcb->rcv_wnd == TCPWND_MIN16(TCP_WND));
01763           LWIP_ASSERT("window not at default value", pcb->rcv_ann_wnd == TCPWND_MIN16(TCP_WND));
01764           pcb->rcv_wnd = pcb->rcv_ann_wnd = TCP_WND;
01765         }
01766         break;
01767 #endif
01768 #if LWIP_TCP_TIMESTAMPS
01769       case LWIP_TCP_OPT_TS:
01770         LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: TS\n"));
01771         if (tcp_getoptbyte() != LWIP_TCP_OPT_LEN_TS || (tcp_optidx - 2 + LWIP_TCP_OPT_LEN_TS) > tcphdr_optlen) {
01772           /* Bad length */
01773           LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
01774           return;
01775         }
01776         /* TCP timestamp option with valid length */
01777         tsval = tcp_getoptbyte();
01778         tsval |= (tcp_getoptbyte() << 8);
01779         tsval |= (tcp_getoptbyte() << 16);
01780         tsval |= (tcp_getoptbyte() << 24);
01781         if (flags & TCP_SYN) {
01782           pcb->ts_recent = ntohl(tsval);
01783           /* Enable sending timestamps in every segment now that we know
01784              the remote host supports it. */
01785           pcb->flags |= TF_TIMESTAMP;
01786         } else if (TCP_SEQ_BETWEEN(pcb->ts_lastacksent, seqno, seqno+tcplen)) {
01787           pcb->ts_recent = ntohl(tsval);
01788         }
01789         /* Advance to next option (6 bytes already read) */
01790         tcp_optidx += LWIP_TCP_OPT_LEN_TS - 6;
01791         break;
01792 #endif
01793       default:
01794         LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: other\n"));
01795         data = tcp_getoptbyte();
01796         if (data < 2) {
01797           LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
01798           /* If the length field is zero, the options are malformed
01799              and we don't process them further. */
01800           return;
01801         }
01802         /* All other options have a length field, so that we easily
01803            can skip past them. */
01804         tcp_optidx += data - 2;
01805       }
01806     }
01807   }
01808 }
01809 
01810 void
01811 tcp_trigger_input_pcb_close(void)
01812 {
01813   recv_flags |= TF_CLOSED;
01814 }
01815 
01816 #endif /* LWIP_TCP */