Bonjour/Zerconf library

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers tcp_in.c Source File

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