Daiki Kato / mbed-os-lychee

Dependents:   mbed-os-example-blinky-gr-lychee GR-Boads_Camera_sample GR-Boards_Audio_Recoder GR-Boads_Camera_DisplayApp ... more

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