1/**
2 * @file
3 * Transmission Control Protocol, incoming traffic
4 *
5 * The input processing functions of the TCP layer.
6 *
7 * These functions are generally called in the order (ip_input() ->)
8 * tcp_input() -> * tcp_process() -> tcp_receive() (-> application).
9 *
10 */
11
12/*
13 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
14 * All rights reserved.
15 *
16 * Redistribution and use in source and binary forms, with or without modification,
17 * are permitted provided that the following conditions are met:
18 *
19 * 1. Redistributions of source code must retain the above copyright notice,
20 *    this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright notice,
22 *    this list of conditions and the following disclaimer in the documentation
23 *    and/or other materials provided with the distribution.
24 * 3. The name of the author may not be used to endorse or promote products
25 *    derived from this software without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
28 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
29 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
30 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
32 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
35 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
36 * OF SUCH DAMAGE.
37 *
38 * This file is part of the lwIP TCP/IP stack.
39 *
40 * Author: Adam Dunkels <adam@sics.se>
41 *
42 */
43
44#include <inttypes.h>
45
46#include "lwip/opt.h"
47
48#if LWIP_TCP                    /* don't build if not configured for use in lwipopts.h */
49
50#include "lwip/tcp.h"
51#include "lwip/def.h"
52#include "lwip/ip_addr.h"
53#include "lwip/netif.h"
54#include "lwip/mem.h"
55#include "lwip/memp.h"
56#include "lwip/inet.h"
57#include "lwip/inet_chksum.h"
58#include "lwip/stats.h"
59#include "lwip/snmp.h"
60#include "arch/perf.h"
61
62/* These variables are global to all functions involved in the input
63   processing of TCP segments. They are set by the tcp_input()
64   function. */
65static struct tcp_seg inseg;
66static struct tcp_hdr *tcphdr;
67static struct ip_hdr *iphdr;
68static u32_t seqno, ackno;
69static u8_t flags;
70static u16_t tcplen;
71
72static u8_t recv_flags;
73static struct pbuf *recv_data;
74
75struct tcp_pcb *tcp_input_pcb;
76
77/* Forward declarations. */
78static err_t tcp_process(struct tcp_pcb *pcb);
79static u8_t tcp_receive(struct tcp_pcb *pcb);
80static void tcp_parseopt(struct tcp_pcb *pcb);
81
82static err_t tcp_listen_input(struct tcp_pcb_listen *pcb);
83static err_t tcp_timewait_input(struct tcp_pcb *pcb);
84
85/**
86 * The initial input processing of TCP. It verifies the TCP header, demultiplexes
87 * the segment between the PCBs and passes it on to tcp_process(), which implements
88 * the TCP finite state machine. This function is called by the IP layer (in
89 * ip_input()).
90 *
91 * @param p received TCP segment to process (p->payload pointing to the IP header)
92 * @param inp network interface on which this segment was received
93 */
94void tcp_input(struct pbuf *p, struct netif *inp)
95{
96    struct tcp_pcb *pcb, *prev;
97    struct tcp_pcb_listen *lpcb;
98    u8_t hdrlen;
99    err_t err;
100
101    PERF_START;
102
103    TCP_STATS_INC(tcp.recv);
104    snmp_inc_tcpinsegs();
105    iphdr = p->payload;
106    tcphdr = (struct tcp_hdr *) ((u8_t *) p->payload + IPH_HL(iphdr) * 4);
107
108#if TCP_INPUT_DEBUG
109    tcp_debug_print(tcphdr);
110#endif
111
112    /* remove header from payload */
113    if (pbuf_header(p, -((s16_t) (IPH_HL(iphdr) * 4)))
114        || (p->tot_len < sizeof(struct tcp_hdr))) {
115        /* drop short packets */
116        LWIP_DEBUGF(TCP_INPUT_DEBUG,
117                    ("tcp_input: short packet (%" U16_F " bytes) discarded\n",
118                     p->tot_len));
119        TCP_STATS_INC(tcp.lenerr);
120        TCP_STATS_INC(tcp.drop);
121        snmp_inc_tcpinerrs();
122        pbuf_free(p);
123        return;
124    }
125
126    /* Don't even process incoming broadcasts/multicasts. */
127    if (ip_addr_isbroadcast(&(iphdr->dest), inp) ||
128        ip_addr_ismulticast(&(iphdr->dest))) {
129        TCP_STATS_INC(tcp.proterr);
130        TCP_STATS_INC(tcp.drop);
131        snmp_inc_tcpinerrs();
132        pbuf_free(p);
133        return;
134    }
135#if CHECKSUM_CHECK_TCP
136    /* Verify TCP checksum. */
137    int hwcxs_good = ((p->nicflags & NETIF_RXFLAG_L4CHECKSUM) &&
138            (p->nicflags & NETIF_RXFLAG_L4CHECKSUM_GOOD));
139    if (!hwcxs_good &&
140        inet_chksum_pseudo(p, (struct ip_addr *) &(iphdr->src),
141                           (struct ip_addr *) &(iphdr->dest),
142                           IP_PROTO_TCP, p->tot_len) != 0) {
143        LWIP_DEBUGF(TCP_INPUT_DEBUG,
144                    ("tcp_input: packet discarded due to failing checksum 0x%04"
145                     X16_F "\n", inet_chksum_pseudo(p,
146                                                    (struct ip_addr *) &(iphdr->
147                                                                         src),
148                                                    (struct ip_addr *) &(iphdr->
149                                                                         dest),
150                                                    IP_PROTO_TCP, p->tot_len)));
151#if TCP_DEBUG
152        tcp_debug_print(tcphdr);
153#endif                          /* TCP_DEBUG */
154        TCP_STATS_INC(tcp.chkerr);
155        TCP_STATS_INC(tcp.drop);
156        snmp_inc_tcpinerrs();
157        pbuf_free(p);
158        return;
159    }
160#endif
161
162    /* Move the payload pointer in the pbuf so that it points to the
163       TCP data instead of the TCP header. */
164    hdrlen = TCPH_HDRLEN(tcphdr);
165    if (pbuf_header(p, -(hdrlen * 4))) {
166        /* drop short packets */
167        LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet\n"));
168        TCP_STATS_INC(tcp.lenerr);
169        TCP_STATS_INC(tcp.drop);
170        snmp_inc_tcpinerrs();
171        pbuf_free(p);
172        return;
173    }
174
175    /* Convert fields in TCP header to host byte order. */
176    tcphdr->src = ntohs(tcphdr->src);
177    tcphdr->dest = ntohs(tcphdr->dest);
178    seqno = tcphdr->seqno = ntohl(tcphdr->seqno);
179    ackno = tcphdr->ackno = ntohl(tcphdr->ackno);
180    tcphdr->wnd = ntohs(tcphdr->wnd);
181
182    flags = TCPH_FLAGS(tcphdr);
183    tcplen = p->tot_len + ((flags & (TCP_FIN | TCP_SYN)) ? 1 : 0);
184
185    /* Demultiplex an incoming segment. First, we check if it is destined
186       for an active connection. */
187    prev = NULL;
188
189
190    for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
191        LWIP_ASSERT("tcp_input: active pcb->state != CLOSED",
192                    pcb->state != CLOSED);
193        LWIP_ASSERT("tcp_input: active pcb->state != TIME-WAIT",
194                    pcb->state != TIME_WAIT);
195        LWIP_ASSERT("tcp_input: active pcb->state != LISTEN",
196                    pcb->state != LISTEN);
197        if (pcb->remote_port == tcphdr->src && pcb->local_port == tcphdr->dest
198            && ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src))
199            && ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest))) {
200
201
202            /* Move this PCB to the front of the list so that subsequent
203               lookups will be faster (we exploit locality in TCP segment
204               arrivals). */
205            LWIP_ASSERT("tcp_input: pcb->next != pcb (before cache)",
206                        pcb->next != pcb);
207            if (prev != NULL) {
208                prev->next = pcb->next;
209                pcb->next = tcp_active_pcbs;
210                tcp_active_pcbs = pcb;
211            }
212            LWIP_ASSERT("tcp_input: pcb->next != pcb (after cache)",
213                        pcb->next != pcb);
214            break;
215        }
216        prev = pcb;
217    }
218
219    if (pcb == NULL) {
220        /* If it did not go to an active connection, we check the connections
221           in the TIME-WAIT state. */
222
223        for (pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
224            LWIP_ASSERT("tcp_input: TIME-WAIT pcb->state == TIME-WAIT",
225                        pcb->state == TIME_WAIT);
226            if (pcb->remote_port == tcphdr->src
227                && pcb->local_port == tcphdr->dest
228                && ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src))
229                && ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest))) {
230                /* We don't really care enough to move this PCB to the front
231                   of the list since we are not very likely to receive that
232                   many segments for connections in TIME-WAIT. */
233                LWIP_DEBUGF(TCP_INPUT_DEBUG,
234                            ("tcp_input: packed for TIME_WAITing connection.\n"));
235                tcp_timewait_input(pcb);
236                pbuf_free(p);
237                return;
238            }
239        }
240
241        /* Finally, if we still did not get a match, we check all PCBs that
242           are LISTENing for incoming connections. */
243        prev = NULL;
244        for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL;
245             lpcb = lpcb->next) {
246            if ((ip_addr_isany(&(lpcb->local_ip))
247                 || ip_addr_cmp(&(lpcb->local_ip), &(iphdr->dest)))
248                && lpcb->local_port == tcphdr->dest) {
249                /* Move this PCB to the front of the list so that subsequent
250                   lookups will be faster (we exploit locality in TCP segment
251                   arrivals). */
252                if (prev != NULL) {
253                    ((struct tcp_pcb_listen *) prev)->next = lpcb->next;
254                    /* our successor is the remainder of the listening list */
255                    lpcb->next = tcp_listen_pcbs.listen_pcbs;
256                    /* put this listening pcb at the head of the listening list */
257                    tcp_listen_pcbs.listen_pcbs = lpcb;
258                }
259                LWIP_DEBUGF(TCP_INPUT_DEBUG,
260                            ("tcp_input: packed for LISTENing connection.\n"));
261                tcp_listen_input(lpcb);
262                pbuf_free(p);
263                return;
264            }
265            prev = (struct tcp_pcb *) lpcb;
266        }
267    }
268#if TCP_INPUT_DEBUG
269    LWIP_DEBUGF(TCP_INPUT_DEBUG,
270                ("+-+-+-+-+-+-+-+-+-+-+-+-+-+- tcp_input: flags "));
271    tcp_debug_print_flags(TCPH_FLAGS(tcphdr));
272    LWIP_DEBUGF(TCP_INPUT_DEBUG, ("-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n"));
273#endif                          /* TCP_INPUT_DEBUG */
274
275
276    if (pcb != NULL) {
277        /* The incoming segment belongs to a connection. */
278#if TCP_INPUT_DEBUG
279#if TCP_DEBUG
280        tcp_debug_print_state(pcb->state);
281#endif                          /* TCP_DEBUG */
282#endif                          /* TCP_INPUT_DEBUG */
283
284        /* Set up a tcp_seg structure. */
285        inseg.next = NULL;
286        inseg.len = p->tot_len;
287        inseg.dataptr = p->payload;
288        inseg.p = p;
289        inseg.tcphdr = tcphdr;
290
291        recv_data = NULL;
292        recv_flags = 0;
293
294        /* If there is data which was previously "refused" by upper layer */
295        if (pcb->refused_data != NULL) {
296            /* Notify again application with data previously received. */
297            LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: notify kept packet\n"));
298            TCP_EVENT_RECV(pcb, pcb->refused_data, ERR_OK, err);
299            if (err == ERR_OK) {
300                pcb->refused_data = NULL;
301            } else {
302                /* drop incoming packets, because pcb is "full" */
303                LWIP_DEBUGF(TCP_INPUT_DEBUG,
304                            ("tcp_input: drop incoming packets, because pcb is \"full\"\n"));
305                TCP_STATS_INC(tcp.drop);
306                snmp_inc_tcpinerrs();
307                pbuf_free(p);
308                return;
309            }
310        }
311
312        tcp_input_pcb = pcb;
313        err = tcp_process(pcb);
314        tcp_input_pcb = NULL;
315        /* A return value of ERR_ABRT means that tcp_abort() was called
316           and that the pcb has been freed. If so, we don't do anything. */
317        if (err != ERR_ABRT) {
318            if (recv_flags & TF_RESET) {
319                /* TF_RESET means that the connection was reset by the other
320                   end. We then call the error callback to inform the
321                   application that the connection is dead before we
322                   deallocate the PCB. */
323                TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_RST);
324                tcp_pcb_remove(&tcp_active_pcbs, pcb);
325                memp_free(MEMP_TCP_PCB, pcb);
326            } else if (recv_flags & TF_CLOSED) {
327                /* The connection has been closed and we will deallocate the
328                   PCB. */
329                tcp_pcb_remove(&tcp_active_pcbs, pcb);
330                memp_free(MEMP_TCP_PCB, pcb);
331            } else {
332                err = ERR_OK;
333                /* If the application has registered a "sent" function to be
334                   called when new send buffer space is available, we call it
335                   now. */
336                if (pcb->acked > 0) {
337                    TCP_EVENT_SENT(pcb, pcb->acked, err);
338                }
339
340                if (recv_data != NULL) {
341                    if (flags & TCP_PSH) {
342                        recv_data->flags |= PBUF_FLAG_PUSH;
343                    }
344
345                    /* Notify application that data has been received. */
346                    TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err);
347
348                    /* If the upper layer can't receive this data, store it */
349                    if (err != ERR_OK) {
350                        pcb->refused_data = recv_data;
351                        LWIP_DEBUGF(TCP_INPUT_DEBUG,
352                                    ("tcp_input: keep incoming packet, because pcb is \"full\"\n"));
353                    }
354                }
355
356                /* If a FIN segment was received, we call the callback
357                   function with a NULL buffer to indicate EOF. */
358                if (recv_flags & TF_GOT_FIN) {
359                    TCP_EVENT_RECV(pcb, NULL, ERR_OK, err);
360                }
361
362                /* If there were no errors, we try to send something out. */
363                if (err == ERR_OK) {
364                    tcp_output(pcb);
365                }
366            }
367        }
368
369
370        /* give up our reference to inseg.p */
371        if (inseg.p != NULL) {
372            pbuf_free(inseg.p);
373            inseg.p = NULL;
374        }
375#if TCP_INPUT_DEBUG
376#if TCP_DEBUG
377        tcp_debug_print_state(pcb->state);
378#endif                          /* TCP_DEBUG */
379#endif                          /* TCP_INPUT_DEBUG */
380
381    } else {
382
383        /* If no matching PCB was found, send a TCP RST (reset) to the
384           sender. */
385        LWIP_DEBUGF(TCP_RST_DEBUG,
386                    ("tcp_input: no PCB match found, resetting.\n"));
387        if (!(TCPH_FLAGS(tcphdr) & TCP_RST)) {
388            TCP_STATS_INC(tcp.proterr);
389            TCP_STATS_INC(tcp.drop);
390            tcp_rst(ackno, seqno + tcplen,
391                    &(iphdr->dest), &(iphdr->src), tcphdr->dest, tcphdr->src);
392        }
393        pbuf_free(p);
394    }
395
396    LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane());
397    PERF_STOP("tcp_input");
398}
399
400/**
401 * Called by tcp_input() when a segment arrives for a listening
402 * connection (from tcp_input()).
403 *
404 * @param pcb the tcp_pcb_listen for which a segment arrived
405 * @return ERR_OK if the segment was processed
406 *         another err_t on error
407 *
408 * @note the return value is not (yet?) used in tcp_input()
409 * @note the segment which arrived is saved in global variables, therefore only the pcb
410 *       involved is passed as a parameter to this function
411 */
412static err_t tcp_listen_input(struct tcp_pcb_listen *pcb)
413{
414    struct tcp_pcb *npcb;
415    err_t rc;
416
417    /* In the LISTEN state, we check for incoming SYN segments,
418       creates a new PCB, and responds with a SYN|ACK. */
419    if (flags & TCP_ACK) {
420        /* For incoming segments with the ACK flag set, respond with a
421           RST. */
422        LWIP_DEBUGF(TCP_RST_DEBUG,
423                    ("tcp_listen_input: ACK in LISTEN, sending reset\n"));
424        tcp_rst(ackno + 1, seqno + tcplen, &(iphdr->dest), &(iphdr->src),
425                tcphdr->dest, tcphdr->src);
426    } else if (flags & TCP_SYN) {
427        LWIP_DEBUGF(TCP_DEBUG,
428                    ("TCP connection request %" U16_F " -> %" U16_F ".\n",
429                     tcphdr->src, tcphdr->dest));
430#if TCP_LISTEN_BACKLOG
431        if (pcb->accepts_pending >= pcb->backlog) {
432            LWIP_DEBUGF(TCP_DEBUG,
433                        ("tcp_listen_input: listen backlog exceeded for port %"
434                         U16_F "\n", tcphdr->dest));
435            return ERR_ABRT;
436        }
437#endif                          /* TCP_LISTEN_BACKLOG */
438        npcb = tcp_alloc(pcb->prio);
439        /* If a new PCB could not be created (probably due to lack of memory),
440           we don't do anything, but rely on the sender will retransmit the
441           SYN at a time when we have more memory available. */
442        if (npcb == NULL) {
443            LWIP_DEBUGF(TCP_DEBUG,
444                        ("tcp_listen_input: could not allocate PCB\n"));
445            TCP_STATS_INC(tcp.memerr);
446            return ERR_MEM;
447        }
448#if TCP_LISTEN_BACKLOG
449        pcb->accepts_pending++;
450#endif                          /* TCP_LISTEN_BACKLOG */
451        /* Set up the new PCB. */
452        ip_addr_set(&(npcb->local_ip), &(iphdr->dest));
453        npcb->local_port = pcb->local_port;
454        ip_addr_set(&(npcb->remote_ip), &(iphdr->src));
455        npcb->remote_port = tcphdr->src;
456        npcb->state = SYN_RCVD;
457        npcb->rcv_nxt = seqno + 1;
458        npcb->rcv_ann_right_edge = npcb->rcv_nxt;
459        npcb->snd_wnd = tcphdr->wnd;
460        npcb->ssthresh = npcb->snd_wnd;
461        npcb->snd_wl1 = seqno - 1;      /* initialise to seqno-1 to force window update */
462        npcb->callback_arg = pcb->callback_arg;
463#if LWIP_CALLBACK_API
464        npcb->accept = pcb->accept;
465#endif                          /* LWIP_CALLBACK_API */
466        /* inherit socket options */
467        npcb->so_options =
468          pcb->
469          so_options & (SOF_DEBUG | SOF_DONTROUTE | SOF_KEEPALIVE |
470                        SOF_OOBINLINE | SOF_LINGER);
471        /* Register the new PCB so that we can begin receiving segments
472           for it. */
473        TCP_REG(&tcp_active_pcbs, npcb);
474
475        /* Parse any options in the SYN. */
476        tcp_parseopt(npcb);
477#if TCP_CALCULATE_EFF_SEND_MSS
478        npcb->mss = tcp_eff_send_mss(npcb->mss, &(npcb->remote_ip));
479#endif                          /* TCP_CALCULATE_EFF_SEND_MSS */
480
481        snmp_inc_tcppassiveopens();
482
483        /* Send a SYN|ACK together with the MSS option. */
484        rc = tcp_enqueue(npcb, NULL, 0, TCP_SYN | TCP_ACK, 0, TF_SEG_OPTS_MSS
485#if LWIP_TCP_TIMESTAMPS
486                         /* and maybe include the TIMESTAMP option */
487                         | (npcb->flags & TF_TIMESTAMP ? TF_SEG_OPTS_TS : 0)
488#endif
489          );
490        if (rc != ERR_OK) {
491            tcp_abandon(npcb, 0);
492            return rc;
493        }
494        return tcp_output(npcb);
495    }
496    return ERR_OK;
497}
498
499/**
500 * Called by tcp_input() when a segment arrives for a connection in
501 * TIME_WAIT.
502 *
503 * @param pcb the tcp_pcb for which a segment arrived
504 *
505 * @note the segment which arrived is saved in global variables, therefore only the pcb
506 *       involved is passed as a parameter to this function
507 */
508static err_t tcp_timewait_input(struct tcp_pcb *pcb)
509{
510    if (TCP_SEQ_GT(seqno + tcplen, pcb->rcv_nxt)) {
511        pcb->rcv_nxt = seqno + tcplen;
512    }
513    if (tcplen > 0) {
514        tcp_ack_now(pcb);
515    }
516    return tcp_output(pcb);
517}
518
519/**
520 * Implements the TCP state machine. Called by tcp_input. In some
521 * states tcp_receive() is called to receive data. The tcp_seg
522 * argument will be freed by the caller (tcp_input()) unless the
523 * recv_data pointer in the pcb is set.
524 *
525 * @param pcb the tcp_pcb for which a segment arrived
526 *
527 * @note the segment which arrived is saved in global variables, therefore only the pcb
528 *       involved is passed as a parameter to this function
529 */
530static err_t tcp_process(struct tcp_pcb *pcb)
531{
532    struct tcp_seg *rseg;
533    u8_t acceptable = 0;
534    err_t err;
535
536    err = ERR_OK;
537
538    /* Process incoming RST segments. */
539    if (flags & TCP_RST) {
540        /* First, determine if the reset is acceptable. */
541        if (pcb->state == SYN_SENT) {
542            if (ackno == pcb->snd_nxt) {
543                acceptable = 1;
544            }
545        } else {
546            if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt,
547                                pcb->rcv_nxt + pcb->rcv_wnd)) {
548                acceptable = 1;
549            }
550        }
551
552        if (acceptable) {
553            LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: Connection RESET\n"));
554            LWIP_ASSERT("tcp_input: pcb->state != CLOSED",
555                        pcb->state != CLOSED);
556            recv_flags |= TF_RESET;
557            pcb->flags &= ~TF_ACK_DELAY;
558            return ERR_RST;
559        } else {
560            LWIP_DEBUGF(TCP_INPUT_DEBUG,
561                        ("tcp_process: unacceptable reset seqno %" U32_F
562                         " rcv_nxt %" U32_F "\n", seqno, pcb->rcv_nxt));
563            LWIP_DEBUGF(TCP_DEBUG,
564                        ("tcp_process: unacceptable reset seqno %" U32_F
565                         " rcv_nxt %" U32_F "\n", seqno, pcb->rcv_nxt));
566            return ERR_OK;
567        }
568    }
569
570    if ((flags & TCP_SYN) && (pcb->state != SYN_SENT && pcb->state != SYN_RCVD)) {
571        /* Cope with new connection attempt after remote end crashed */
572        tcp_ack_now(pcb);
573        return ERR_OK;
574    }
575
576    /* Update the PCB (in)activity timer. */
577    pcb->tmr = tcp_ticks;
578    pcb->keep_cnt_sent = 0;
579
580    tcp_parseopt(pcb);
581
582    /* Do different things depending on the TCP state. */
583    switch (pcb->state) {
584        case SYN_SENT:
585            LWIP_DEBUGF(TCP_INPUT_DEBUG,
586                        ("SYN-SENT: ackno %" U32_F " pcb->snd_nxt %" U32_F
587                         " unacked %" U32_F "\n", ackno, pcb->snd_nxt,
588                         ntohl(pcb->unacked->tcphdr->seqno)));
589            /* received SYN ACK with expected sequence number? */
590            if ((flags & TCP_ACK) && (flags & TCP_SYN)
591                && ackno == ntohl(pcb->unacked->tcphdr->seqno) + 1) {
592                pcb->snd_buf++;
593                pcb->rcv_nxt = seqno + 1;
594                pcb->rcv_ann_right_edge = pcb->rcv_nxt;
595                pcb->lastack = ackno;
596                pcb->snd_wnd = tcphdr->wnd;
597                pcb->snd_wl1 = seqno - 1;       /* initialise to seqno - 1 to force window update */
598                pcb->state = ESTABLISHED;
599
600#if TCP_CALCULATE_EFF_SEND_MSS
601                pcb->mss = tcp_eff_send_mss(pcb->mss, &(pcb->remote_ip));
602#endif                          /* TCP_CALCULATE_EFF_SEND_MSS */
603
604                /* Set ssthresh again after changing pcb->mss (already set in tcp_connect
605                 * but for the default value of pcb->mss) */
606                pcb->ssthresh = pcb->mss * 10;
607
608                pcb->cwnd = ((pcb->cwnd == 1) ? (pcb->mss * 2) : pcb->mss);
609                LWIP_ASSERT("pcb->snd_queuelen > 0", (pcb->snd_queuelen > 0));
610                --pcb->snd_queuelen;
611                LWIP_DEBUGF(TCP_QLEN_DEBUG,
612                            ("tcp_process: SYN-SENT --queuelen %" U16_F "\n",
613                             (u16_t) pcb->snd_queuelen));
614                rseg = pcb->unacked;
615                pcb->unacked = rseg->next;
616
617                /* If there's nothing left to acknowledge, stop the retransmit
618                   timer, otherwise reset it to start again */
619                if (pcb->unacked == NULL)
620                    pcb->rtime = -1;
621                else {
622                    pcb->rtime = 0;
623                    pcb->nrtx = 0;
624                }
625
626                tcp_seg_free(rseg);
627
628                /* Call the user specified function to call when sucessfully
629                 * connected. */
630                TCP_EVENT_CONNECTED(pcb, ERR_OK, err);
631                tcp_ack_now(pcb);
632            }
633            /* received ACK? possibly a half-open connection */
634            else if (flags & TCP_ACK) {
635                /* send a RST to bring the other side in a non-synchronized state. */
636                tcp_rst(ackno, seqno + tcplen, &(iphdr->dest), &(iphdr->src),
637                        tcphdr->dest, tcphdr->src);
638            }
639            break;
640        case SYN_RCVD:
641            if (flags & TCP_ACK) {
642                /* expected ACK number? */
643                if (TCP_SEQ_BETWEEN(ackno, pcb->lastack + 1, pcb->snd_nxt)) {
644                    u16_t old_cwnd;
645
646                    pcb->state = ESTABLISHED;
647                    LWIP_DEBUGF(TCP_DEBUG,
648                                ("TCP connection established %" U16_F " -> %"
649                                 U16_F ".\n", inseg.tcphdr->src,
650                                 inseg.tcphdr->dest));
651#if LWIP_CALLBACK_API
652                    LWIP_ASSERT("pcb->accept != NULL", pcb->accept != NULL);
653#endif
654                    /* Call the accept function. */
655                    TCP_EVENT_ACCEPT(pcb, ERR_OK, err);
656                    if (err != ERR_OK) {
657                        /* If the accept function returns with an error, we abort
658                         * the connection. */
659                        tcp_abort(pcb);
660                        return ERR_ABRT;
661                    }
662                    old_cwnd = pcb->cwnd;
663                    /* If there was any data contained within this ACK,
664                     * we'd better pass it on to the application as well. */
665                    tcp_receive(pcb);
666
667                    pcb->cwnd = ((old_cwnd == 1) ? (pcb->mss * 2) : pcb->mss);
668
669                    if (recv_flags & TF_GOT_FIN) {
670                        tcp_ack_now(pcb);
671                        pcb->state = CLOSE_WAIT;
672                    }
673                }
674                /* incorrect ACK number */
675                else {
676                    /* send RST */
677                    tcp_rst(ackno, seqno + tcplen, &(iphdr->dest),
678                            &(iphdr->src), tcphdr->dest, tcphdr->src);
679                }
680            } else if ((flags & TCP_SYN) && (seqno == pcb->rcv_nxt - 1)) {
681                /* Looks like another copy of the SYN - retransmit our SYN-ACK */
682                tcp_rexmit(pcb);
683            }
684            break;
685        case CLOSE_WAIT:
686            /* FALLTHROUGH */
687        case ESTABLISHED:
688            tcp_receive(pcb);
689            if (recv_flags & TF_GOT_FIN) {      /* passive close */
690                tcp_ack_now(pcb);
691                pcb->state = CLOSE_WAIT;
692            }
693            break;
694        case FIN_WAIT_1:
695            tcp_receive(pcb);
696            if (recv_flags & TF_GOT_FIN) {
697                if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) {
698                    LWIP_DEBUGF(TCP_DEBUG,
699                                ("TCP connection closed %" U16_F " -> %" U16_F
700                                 ".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
701                    tcp_ack_now(pcb);
702                    tcp_pcb_purge(pcb);
703                    TCP_RMV(&tcp_active_pcbs, pcb);
704                    pcb->state = TIME_WAIT;
705                    TCP_REG(&tcp_tw_pcbs, pcb);
706                } else {
707                    tcp_ack_now(pcb);
708                    pcb->state = CLOSING;
709                }
710            } else if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) {
711                pcb->state = FIN_WAIT_2;
712            }
713            break;
714        case FIN_WAIT_2:
715            tcp_receive(pcb);
716            if (recv_flags & TF_GOT_FIN) {
717                LWIP_DEBUGF(TCP_DEBUG,
718                            ("TCP connection closed %" U16_F " -> %" U16_F
719                             ".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
720                tcp_ack_now(pcb);
721                tcp_pcb_purge(pcb);
722                TCP_RMV(&tcp_active_pcbs, pcb);
723                pcb->state = TIME_WAIT;
724                TCP_REG(&tcp_tw_pcbs, pcb);
725            }
726            break;
727        case CLOSING:
728            tcp_receive(pcb);
729            if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
730                LWIP_DEBUGF(TCP_DEBUG,
731                            ("TCP connection closed %" U16_F " -> %" U16_F
732                             ".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
733                tcp_pcb_purge(pcb);
734                TCP_RMV(&tcp_active_pcbs, pcb);
735                pcb->state = TIME_WAIT;
736                TCP_REG(&tcp_tw_pcbs, pcb);
737            }
738            break;
739        case LAST_ACK:
740            tcp_receive(pcb);
741            if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
742                LWIP_DEBUGF(TCP_DEBUG,
743                            ("TCP connection closed %" U16_F " -> %" U16_F
744                             ".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
745                /* bugfix #21699: don't set pcb->state to CLOSED here or we risk leaking segments */
746                recv_flags |= TF_CLOSED;
747            }
748            break;
749        default:
750            break;
751    }
752    return ERR_OK;
753}
754
755/**
756 * Called by tcp_process. Checks if the given segment is an ACK for outstanding
757 * data, and if so frees the memory of the buffered data. Next, is places the
758 * segment on any of the receive queues (pcb->recved or pcb->ooseq). If the segment
759 * is buffered, the pbuf is referenced by pbuf_ref so that it will not be freed until
760 * i it has been removed from the buffer.
761 *
762 * If the incoming segment constitutes an ACK for a segment that was used for RTT
763 * estimation, the RTT is estimated here as well.
764 *
765 * Called from tcp_process().
766 *
767 * @return 1 if the incoming segment is the next in sequence, 0 if not
768 */
769static u8_t tcp_receive(struct tcp_pcb *pcb)
770{
771    struct tcp_seg *next;
772
773#if TCP_QUEUE_OOSEQ
774    struct tcp_seg *prev, *cseg;
775#endif
776    struct pbuf *p;
777    s32_t off;
778    s16_t m;
779    u32_t right_wnd_edge;
780    u16_t new_tot_len;
781    u8_t accepted_inseq = 0;
782
783    if (flags & TCP_ACK) {
784        right_wnd_edge = pcb->snd_wnd + pcb->snd_wl2;
785
786        /* Update window. */
787        if (TCP_SEQ_LT(pcb->snd_wl1, seqno) ||
788            (pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) ||
789            (pcb->snd_wl2 == ackno && tcphdr->wnd > pcb->snd_wnd)) {
790            pcb->snd_wnd = tcphdr->wnd;
791            pcb->snd_wl1 = seqno;
792            pcb->snd_wl2 = ackno;
793            if (pcb->snd_wnd > 0 && pcb->persist_backoff > 0) {
794                pcb->persist_backoff = 0;
795            }
796            LWIP_DEBUGF(TCP_WND_DEBUG,
797                        ("tcp_receive: window update %" U16_F "\n",
798                         pcb->snd_wnd));
799#if TCP_WND_DEBUG
800        } else {
801            if (pcb->snd_wnd != tcphdr->wnd) {
802                LWIP_DEBUGF(TCP_WND_DEBUG,
803                            ("tcp_receive: no window update lastack %" U32_F
804                             " ackno %" U32_F " wl1 %" U32_F " seqno %" U32_F
805                             " wl2 %" U32_F "\n", pcb->lastack, ackno,
806                             pcb->snd_wl1, seqno, pcb->snd_wl2));
807            }
808#endif                          /* TCP_WND_DEBUG */
809        }
810
811        if (pcb->lastack == ackno) {
812            pcb->acked = 0;
813
814            if (pcb->snd_wl2 + pcb->snd_wnd == right_wnd_edge) {
815                ++pcb->dupacks;
816                if (pcb->dupacks >= 3 && pcb->unacked != NULL) {
817                    if (!(pcb->flags & TF_INFR)) {
818                        /* This is fast retransmit. Retransmit the first unacked segment. */
819                        LWIP_DEBUGF(TCP_FR_DEBUG,
820                                    ("tcp_receive: dupacks %" U16_F " (%" U32_F
821                                     "), fast retransmit %" U32_F "\n",
822                                     (u16_t) pcb->dupacks, pcb->lastack,
823                                     ntohl(pcb->unacked->tcphdr->seqno)));
824                        tcp_rexmit(pcb);
825                        /* Set ssthresh to max (FlightSize / 2, 2*SMSS) */
826                        /*pcb->ssthresh = LWIP_MAX((pcb->snd_max -
827                           pcb->lastack) / 2,
828                           2 * pcb->mss); */
829                        /* Set ssthresh to half of the minimum of the current cwnd and the advertised window */
830                        if (pcb->cwnd > pcb->snd_wnd)
831                            pcb->ssthresh = pcb->snd_wnd / 2;
832                        else
833                            pcb->ssthresh = pcb->cwnd / 2;
834
835                        /* The minimum value for ssthresh should be 2 MSS */
836                        if (pcb->ssthresh < 2 * pcb->mss) {
837                            LWIP_DEBUGF(TCP_FR_DEBUG,
838                                        ("tcp_receive: The minimum value for ssthresh %"
839                                         U16_F " should be min 2 mss %" U16_F
840                                         "...\n", pcb->ssthresh, 2 * pcb->mss));
841                            pcb->ssthresh = 2 * pcb->mss;
842                        }
843
844                        pcb->cwnd = pcb->ssthresh + 3 * pcb->mss;
845                        pcb->flags |= TF_INFR;
846                    } else {
847                        /* Inflate the congestion window, but not if it means that
848                           the value overflows. */
849                        if ((u16_t) (pcb->cwnd + pcb->mss) > pcb->cwnd) {
850                            pcb->cwnd += pcb->mss;
851                        }
852                    }
853                }
854            } else {
855                LWIP_DEBUGF(TCP_FR_DEBUG,
856                            ("tcp_receive: dupack averted %" U32_F " %" U32_F
857                             "\n", pcb->snd_wl2 + pcb->snd_wnd,
858                             right_wnd_edge));
859            }
860        } else if (TCP_SEQ_BETWEEN(ackno, pcb->lastack + 1, pcb->snd_nxt)) {
861            /* We come here when the ACK acknowledges new data. */
862
863            /* Reset the "IN Fast Retransmit" flag, since we are no longer
864               in fast retransmit. Also reset the congestion window to the
865               slow start threshold. */
866            if (pcb->flags & TF_INFR) {
867                pcb->flags &= ~TF_INFR;
868                pcb->cwnd = pcb->ssthresh;
869            }
870
871            /* Reset the number of retransmissions. */
872            pcb->nrtx = 0;
873
874            /* Reset the retransmission time-out. */
875            pcb->rto = (pcb->sa >> 3) + pcb->sv;
876
877            /* Update the send buffer space. Diff between the two can never exceed 64K? */
878            pcb->acked = (u16_t) (ackno - pcb->lastack);
879
880            pcb->snd_buf += pcb->acked;
881
882            /* Reset the fast retransmit variables. */
883            pcb->dupacks = 0;
884            pcb->lastack = ackno;
885
886            /* Update the congestion control variables (cwnd and
887               ssthresh). */
888            if (pcb->state >= ESTABLISHED) {
889                if (pcb->cwnd < pcb->ssthresh) {
890                    if ((u16_t) (pcb->cwnd + pcb->mss) > pcb->cwnd) {
891                        pcb->cwnd += pcb->mss;
892                    }
893                    LWIP_DEBUGF(TCP_CWND_DEBUG,
894                                ("tcp_receive: slow start cwnd %" U16_F "\n",
895                                 pcb->cwnd));
896                } else {
897                    u16_t new_cwnd =
898                      (pcb->cwnd + pcb->mss * pcb->mss / pcb->cwnd);
899                    if (new_cwnd > pcb->cwnd) {
900                        pcb->cwnd = new_cwnd;
901                    }
902                    LWIP_DEBUGF(TCP_CWND_DEBUG,
903                                ("tcp_receive: congestion avoidance cwnd %"
904                                 U16_F "\n", pcb->cwnd));
905                }
906            }
907            LWIP_DEBUGF(TCP_INPUT_DEBUG,
908                        ("tcp_receive: ACK for %" U32_F ", unacked->seqno %"
909                         U32_F ":%" U32_F "\n", ackno,
910                         pcb->unacked !=
911                         NULL ? ntohl(pcb->unacked->tcphdr->seqno) : 0,
912                         pcb->unacked !=
913                         NULL ? ntohl(pcb->unacked->tcphdr->seqno) +
914                         TCP_TCPLEN(pcb->unacked) : 0));
915
916            /* Remove segment from the unacknowledged list if the incoming
917               ACK acknowlegdes them. */
918            while (pcb->unacked != NULL &&
919                   TCP_SEQ_LEQ(ntohl(pcb->unacked->tcphdr->seqno) +
920                               TCP_TCPLEN(pcb->unacked), ackno)) {
921                LWIP_DEBUGF(TCP_INPUT_DEBUG,
922                            ("tcp_receive: removing %" U32_F ":%" U32_F
923                             " from pcb->unacked\n",
924                             ntohl(pcb->unacked->tcphdr->seqno),
925                             ntohl(pcb->unacked->tcphdr->seqno) +
926                             TCP_TCPLEN(pcb->unacked)));
927
928                next = pcb->unacked;
929                pcb->unacked = pcb->unacked->next;
930
931                LWIP_DEBUGF(TCP_QLEN_DEBUG,
932                            ("tcp_receive: queuelen %" U16_F " ... ",
933                             (u16_t) pcb->snd_queuelen));
934                if (pcb->snd_queuelen < pbuf_clen(next->p)) {
935                    printf("snd_queuelen [%"PRIu16"] < pbuf_clen(next->p) [%"PRIu8"]\n",
936                            pcb->snd_queuelen, pbuf_clen(next->p));
937                }
938                LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)",
939                            (pcb->snd_queuelen >= pbuf_clen(next->p)));
940                pcb->snd_queuelen -= pbuf_clen(next->p);
941                tcp_seg_free(next);
942
943                LWIP_DEBUGF(TCP_QLEN_DEBUG,
944                            ("%" U16_F " (after freeing unacked)\n",
945                             (u16_t) pcb->snd_queuelen));
946                if (pcb->snd_queuelen != 0) {
947                    LWIP_ASSERT("tcp_receive: valid queue length",
948                                pcb->unacked != NULL || pcb->unsent != NULL);
949                }
950            }
951
952            /* If there's nothing left to acknowledge, stop the retransmit
953               timer, otherwise reset it to start again */
954            if (pcb->unacked == NULL)
955                pcb->rtime = -1;
956            else
957                pcb->rtime = 0;
958
959            pcb->polltmr = 0;
960        } else {
961            /* Fix bug bug #21582: out of sequence ACK, didn't really ack anything */
962            pcb->acked = 0;
963        }
964
965        /* We go through the ->unsent list to see if any of the segments
966           on the list are acknowledged by the ACK. This may seem
967           strange since an "unsent" segment shouldn't be acked. The
968           rationale is that lwIP puts all outstanding segments on the
969           ->unsent list after a retransmission, so these segments may
970           in fact have been sent once. */
971        while (pcb->unsent != NULL &&
972               TCP_SEQ_BETWEEN(ackno, ntohl(pcb->unsent->tcphdr->seqno) +
973                               TCP_TCPLEN(pcb->unsent), pcb->snd_nxt)) {
974            LWIP_DEBUGF(TCP_INPUT_DEBUG,
975                        ("tcp_receive: removing %" U32_F ":%" U32_F
976                         " from pcb->unsent\n",
977                         ntohl(pcb->unsent->tcphdr->seqno),
978                         ntohl(pcb->unsent->tcphdr->seqno) +
979                         TCP_TCPLEN(pcb->unsent)));
980
981            next = pcb->unsent;
982            pcb->unsent = pcb->unsent->next;
983            LWIP_DEBUGF(TCP_QLEN_DEBUG,
984                        ("tcp_receive: queuelen %" U16_F " ... ",
985                         (u16_t) pcb->snd_queuelen));
986            LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)",
987                        (pcb->snd_queuelen >= pbuf_clen(next->p)));
988            pcb->snd_queuelen -= pbuf_clen(next->p);
989            tcp_seg_free(next);
990            LWIP_DEBUGF(TCP_QLEN_DEBUG,
991                        ("%" U16_F " (after freeing unsent)\n",
992                         (u16_t) pcb->snd_queuelen));
993            if (pcb->snd_queuelen != 0) {
994                LWIP_ASSERT("tcp_receive: valid queue length",
995                            pcb->unacked != NULL || pcb->unsent != NULL);
996            }
997        }
998        /* End of ACK for new data processing. */
999
1000        LWIP_DEBUGF(TCP_RTO_DEBUG,
1001                    ("tcp_receive: pcb->rttest %" U32_F " rtseq %" U32_F
1002                     " ackno %" U32_F "\n", pcb->rttest, pcb->rtseq, ackno));
1003
1004        /* RTT estimation calculations. This is done by checking if the
1005           incoming segment acknowledges the segment we use to take a
1006           round-trip time measurement. */
1007        if (pcb->rttest && TCP_SEQ_LT(pcb->rtseq, ackno)) {
1008            /* diff between this shouldn't exceed 32K since this are tcp timer ticks
1009               and a round-trip shouldn't be that long... */
1010            m = (s16_t) (tcp_ticks - pcb->rttest);
1011
1012            LWIP_DEBUGF(TCP_RTO_DEBUG,
1013                        ("tcp_receive: experienced rtt %" U16_F " ticks (%"
1014                         U16_F " msec).\n", m, m * TCP_SLOW_INTERVAL));
1015
1016            /* This is taken directly from VJs original code in his paper */
1017            m = m - (pcb->sa >> 3);
1018            pcb->sa += m;
1019            if (m < 0) {
1020                m = -m;
1021            }
1022            m = m - (pcb->sv >> 2);
1023            pcb->sv += m;
1024            pcb->rto = (pcb->sa >> 3) + pcb->sv;
1025
1026            LWIP_DEBUGF(TCP_RTO_DEBUG,
1027                        ("tcp_receive: RTO %" U16_F " (%" U16_F
1028                         " milliseconds)\n", pcb->rto,
1029                         pcb->rto * TCP_SLOW_INTERVAL));
1030
1031            pcb->rttest = 0;
1032        }
1033    }
1034
1035    /* If the incoming segment contains data, we must process it
1036       further. */
1037    if (tcplen > 0) {
1038        /* This code basically does three things:
1039
1040           +) If the incoming segment contains data that is the next
1041           in-sequence data, this data is passed to the application. This
1042           might involve trimming the first edge of the data. The rcv_nxt
1043           variable and the advertised window are adjusted.
1044
1045           +) If the incoming segment has data that is above the next
1046           sequence number expected (->rcv_nxt), the segment is placed on
1047           the ->ooseq queue. This is done by finding the appropriate
1048           place in the ->ooseq queue (which is ordered by sequence
1049           number) and trim the segment in both ends if needed. An
1050           immediate ACK is sent to indicate that we received an
1051           out-of-sequence segment.
1052
1053           +) Finally, we check if the first segment on the ->ooseq queue
1054           now is in sequence (i.e., if rcv_nxt >= ooseq->seqno). If
1055           rcv_nxt > ooseq->seqno, we must trim the first edge of the
1056           segment on ->ooseq before we adjust rcv_nxt. The data in the
1057           segments that are now on sequence are chained onto the
1058           incoming segment so that we only need to call the application
1059           once.
1060         */
1061
1062        /* First, we check if we must trim the first edge. We have to do
1063           this if the sequence number of the incoming segment is less
1064           than rcv_nxt, and the sequence number plus the length of the
1065           segment is larger than rcv_nxt. */
1066        /*    if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)){
1067           if (TCP_SEQ_LT(pcb->rcv_nxt, seqno + tcplen)) { */
1068        if (TCP_SEQ_BETWEEN(pcb->rcv_nxt, seqno + 1, seqno + tcplen - 1)) {
1069            /* Trimming the first edge is done by pushing the payload
1070               pointer in the pbuf downwards. This is somewhat tricky since
1071               we do not want to discard the full contents of the pbuf up to
1072               the new starting point of the data since we have to keep the
1073               TCP header which is present in the first pbuf in the chain.
1074
1075               What is done is really quite a nasty hack: the first pbuf in
1076               the pbuf chain is pointed to by inseg.p. Since we need to be
1077               able to deallocate the whole pbuf, we cannot change this
1078               inseg.p pointer to point to any of the later pbufs in the
1079               chain. Instead, we point the ->payload pointer in the first
1080               pbuf to data in one of the later pbufs. We also set the
1081               inseg.data pointer to point to the right place. This way, the
1082               ->p pointer will still point to the first pbuf, but the
1083               ->p->payload pointer will point to data in another pbuf.
1084
1085               After we are done with adjusting the pbuf pointers we must
1086               adjust the ->data pointer in the seg and the segment
1087               length. */
1088
1089            off = pcb->rcv_nxt - seqno;
1090            p = inseg.p;
1091            LWIP_ASSERT("inseg.p != NULL", inseg.p);
1092            LWIP_ASSERT("insane offset!", (off < 0x7fff));
1093            if (inseg.p->len < off) {
1094                LWIP_ASSERT("pbuf too short!",
1095                            (((s32_t) inseg.p->tot_len) >= off));
1096                new_tot_len = (u16_t) (inseg.p->tot_len - off);
1097                while (p->len < off) {
1098                    off -= p->len;
1099                    /* KJM following line changed (with addition of new_tot_len var)
1100                       to fix bug #9076
1101                       inseg.p->tot_len -= p->len; */
1102                    p->tot_len = new_tot_len;
1103                    p->len = 0;
1104                    p = p->next;
1105                }
1106                if (pbuf_header(p, (s16_t) - off)) {
1107                    /* Do we need to cope with this failing?  Assert for now */
1108                    LWIP_ASSERT("pbuf_header failed", 0);
1109                }
1110            } else {
1111                if (pbuf_header(inseg.p, (s16_t) - off)) {
1112                    /* Do we need to cope with this failing?  Assert for now */
1113                    LWIP_ASSERT("pbuf_header failed", 0);
1114                }
1115            }
1116            /* KJM following line changed to use p->payload rather than inseg->p->payload
1117               to fix bug #9076 */
1118            inseg.dataptr = p->payload;
1119            inseg.len -= (u16_t) (pcb->rcv_nxt - seqno);
1120            inseg.tcphdr->seqno = seqno = pcb->rcv_nxt;
1121        } else {
1122            if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)) {
1123                /* the whole segment is < rcv_nxt */
1124                /* must be a duplicate of a packet that has already been correctly handled */
1125
1126                LWIP_DEBUGF(TCP_INPUT_DEBUG,
1127                            ("tcp_receive: duplicate seqno %" U32_F "\n",
1128                             seqno));
1129                tcp_ack_now(pcb);
1130            }
1131        }
1132
1133        /* The sequence number must be within the window (above rcv_nxt
1134           and below rcv_nxt + rcv_wnd) in order to be further
1135           processed. */
1136        if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt,
1137                            pcb->rcv_nxt + pcb->rcv_wnd - 1)) {
1138            if (pcb->rcv_nxt == seqno) {
1139                accepted_inseq = 1;
1140                /* The incoming segment is the next in sequence. We check if
1141                   we have to trim the end of the segment and update rcv_nxt
1142                   and pass the data to the application. */
1143                tcplen = TCP_TCPLEN(&inseg);
1144
1145                if (tcplen > pcb->rcv_wnd) {
1146                    LWIP_DEBUGF(TCP_INPUT_DEBUG,
1147                                ("tcp_receive: other end overran receive window"
1148                                 "seqno %" U32_F " len %" U32_F " right edge %"
1149                                 U32_F "\n", seqno, tcplen,
1150                                 pcb->rcv_nxt + pcb->rcv_wnd));
1151                    if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
1152                        /* Must remove the FIN from the header as we're trimming
1153                         * that byte of sequence-space from the packet */
1154                        TCPH_FLAGS_SET(inseg.tcphdr,
1155                                       TCPH_FLAGS(inseg.tcphdr) & ~TCP_FIN);
1156                    }
1157                    /* Adjust length of segment to fit in the window. */
1158                    inseg.len = pcb->rcv_wnd;
1159                    if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) {
1160                        inseg.len -= 1;
1161                    }
1162                    pbuf_realloc(inseg.p, inseg.len);
1163                    tcplen = TCP_TCPLEN(&inseg);
1164                    LWIP_ASSERT
1165                      ("tcp_receive: segment not trimmed correctly to rcv_wnd\n",
1166                       (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd));
1167                }
1168#if TCP_QUEUE_OOSEQ
1169                if (pcb->ooseq != NULL) {
1170                    if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
1171                        LWIP_DEBUGF(TCP_INPUT_DEBUG,
1172                                    ("tcp_receive: received in-order FIN, binning ooseq queue\n"));
1173                        /* Received in-order FIN means anything that was received
1174                         * out of order must now have been received in-order, so
1175                         * bin the ooseq queue */
1176                        while (pcb->ooseq != NULL) {
1177                            struct tcp_seg *old_ooseq = pcb->ooseq;
1178
1179                            pcb->ooseq = pcb->ooseq->next;
1180                            memp_free(MEMP_TCP_SEG, old_ooseq);
1181                        }
1182                    } else
1183                      if (TCP_SEQ_LEQ
1184                          (pcb->ooseq->tcphdr->seqno, seqno + tcplen)) {
1185                        if (pcb->ooseq->len > 0) {
1186                            /* We have to trim the second edge of the incoming segment. */
1187                            LWIP_ASSERT
1188                              ("tcp_receive: trimmed segment would have zero length\n",
1189                               TCP_SEQ_GT(pcb->ooseq->tcphdr->seqno, seqno));
1190                            /* FIN in inseg already handled by dropping whole ooseq queue */
1191                            inseg.len =
1192                              (u16_t) (pcb->ooseq->tcphdr->seqno - seqno);
1193                            if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) {
1194                                inseg.len -= 1;
1195                            }
1196                            pbuf_realloc(inseg.p, inseg.len);
1197                            tcplen = TCP_TCPLEN(&inseg);
1198                            LWIP_ASSERT
1199                              ("tcp_receive: segment not trimmed correctly to ooseq queue\n",
1200                               (seqno + tcplen) == pcb->ooseq->tcphdr->seqno);
1201                        } else {
1202                            /* does the ooseq segment contain only flags that are in inseg also? */
1203                            if ((TCPH_FLAGS(inseg.tcphdr) & (TCP_FIN | TCP_SYN))
1204                                ==
1205                                (TCPH_FLAGS(pcb->ooseq->tcphdr) &
1206                                 (TCP_FIN | TCP_SYN))) {
1207                                struct tcp_seg *old_ooseq = pcb->ooseq;
1208
1209                                pcb->ooseq = pcb->ooseq->next;
1210                                memp_free(MEMP_TCP_SEG, old_ooseq);
1211                            }
1212                        }
1213                    }
1214                }
1215#endif                          /* TCP_QUEUE_OOSEQ */
1216
1217                pcb->rcv_nxt = seqno + tcplen;
1218
1219                /* Update the receiver's (our) window. */
1220                LWIP_ASSERT("tcp_receive: tcplen > rcv_wnd\n",
1221                            pcb->rcv_wnd >= tcplen);
1222                pcb->rcv_wnd -= tcplen;
1223
1224                tcp_update_rcv_ann_wnd(pcb);
1225
1226                /* If there is data in the segment, we make preparations to
1227                   pass this up to the application. The ->recv_data variable
1228                   is used for holding the pbuf that goes to the
1229                   application. The code for reassembling out-of-sequence data
1230                   chains its data on this pbuf as well.
1231
1232                   If the segment was a FIN, we set the TF_GOT_FIN flag that will
1233                   be used to indicate to the application that the remote side has
1234                   closed its end of the connection. */
1235                if (inseg.p->tot_len > 0) {
1236                    recv_data = inseg.p;
1237                    /* Since this pbuf now is the responsibility of the
1238                       application, we delete our reference to it so that we won't
1239                       (mistakingly) deallocate it. */
1240                    inseg.p = NULL;
1241                }
1242                if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
1243                    LWIP_DEBUGF(TCP_INPUT_DEBUG,
1244                                ("tcp_receive: received FIN.\n"));
1245                    recv_flags |= TF_GOT_FIN;
1246                }
1247#if TCP_QUEUE_OOSEQ
1248                /* We now check if we have segments on the ->ooseq queue that
1249                   is now in sequence. */
1250                while (pcb->ooseq != NULL &&
1251                       pcb->ooseq->tcphdr->seqno == pcb->rcv_nxt) {
1252
1253                    cseg = pcb->ooseq;
1254                    seqno = pcb->ooseq->tcphdr->seqno;
1255
1256                    pcb->rcv_nxt += TCP_TCPLEN(cseg);
1257                    LWIP_ASSERT("tcp_receive: ooseq tcplen > rcv_wnd\n",
1258                                pcb->rcv_wnd >= TCP_TCPLEN(cseg));
1259                    pcb->rcv_wnd -= TCP_TCPLEN(cseg);
1260
1261                    tcp_update_rcv_ann_wnd(pcb);
1262
1263                    if (cseg->p->tot_len > 0) {
1264                        /* Chain this pbuf onto the pbuf that we will pass to
1265                           the application. */
1266                        if (recv_data) {
1267                            pbuf_cat(recv_data, cseg->p);
1268                        } else {
1269                            recv_data = cseg->p;
1270                        }
1271                        cseg->p = NULL;
1272                    }
1273                    if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) {
1274                        LWIP_DEBUGF(TCP_INPUT_DEBUG,
1275                                    ("tcp_receive: dequeued FIN.\n"));
1276                        recv_flags |= TF_GOT_FIN;
1277                        if (pcb->state == ESTABLISHED) {        /* force passive close or we can move to active close */
1278                            pcb->state = CLOSE_WAIT;
1279                        }
1280                    }
1281
1282
1283                    pcb->ooseq = cseg->next;
1284                    tcp_seg_free(cseg);
1285                }
1286#endif                          /* TCP_QUEUE_OOSEQ */
1287
1288
1289                /* Acknowledge the segment(s). */
1290                tcp_ack(pcb);
1291
1292            } else {
1293                /* We get here if the incoming segment is out-of-sequence. */
1294                tcp_ack_now(pcb);
1295#if TCP_QUEUE_OOSEQ
1296                /* We queue the segment on the ->ooseq queue. */
1297                if (pcb->ooseq == NULL) {
1298                    pcb->ooseq = tcp_seg_copy(&inseg);
1299                } else {
1300                    /* If the queue is not empty, we walk through the queue and
1301                       try to find a place where the sequence number of the
1302                       incoming segment is between the sequence numbers of the
1303                       previous and the next segment on the ->ooseq queue. That is
1304                       the place where we put the incoming segment. If needed, we
1305                       trim the second edges of the previous and the incoming
1306                       segment so that it will fit into the sequence.
1307
1308                       If the incoming segment has the same sequence number as a
1309                       segment on the ->ooseq queue, we discard the segment that
1310                       contains less data. */
1311
1312                    prev = NULL;
1313                    for (next = pcb->ooseq; next != NULL; next = next->next) {
1314                        if (seqno == next->tcphdr->seqno) {
1315                            /* The sequence number of the incoming segment is the
1316                               same as the sequence number of the segment on
1317                               ->ooseq. We check the lengths to see which one to
1318                               discard. */
1319                            if (inseg.len > next->len) {
1320                                /* The incoming segment is larger than the old
1321                                   segment. We replace the old segment with the new
1322                                   one. */
1323                                cseg = tcp_seg_copy(&inseg);
1324                                if (cseg != NULL) {
1325                                    cseg->next = next->next;
1326                                    if (prev != NULL) {
1327                                        prev->next = cseg;
1328                                    } else {
1329                                        pcb->ooseq = cseg;
1330                                    }
1331                                    tcp_seg_free(next);
1332                                    if (cseg->next != NULL) {
1333                                        next = cseg->next;
1334                                        if (TCP_SEQ_GT
1335                                            (seqno + cseg->len,
1336                                             next->tcphdr->seqno)) {
1337                                            /* We need to trim the incoming segment. */
1338                                            cseg->len =
1339                                              (u16_t) (next->tcphdr->seqno -
1340                                                       seqno);
1341                                            pbuf_realloc(cseg->p, cseg->len);
1342                                        }
1343                                    }
1344                                }
1345                                break;
1346                            } else {
1347                                /* Either the lenghts are the same or the incoming
1348                                   segment was smaller than the old one; in either
1349                                   case, we ditch the incoming segment. */
1350                                break;
1351                            }
1352                        } else {
1353                            if (prev == NULL) {
1354                                if (TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {
1355                                    /* The sequence number of the incoming segment is lower
1356                                       than the sequence number of the first segment on the
1357                                       queue. We put the incoming segment first on the
1358                                       queue. */
1359
1360                                    if (TCP_SEQ_GT
1361                                        (seqno + inseg.len,
1362                                         next->tcphdr->seqno)) {
1363                                        /* We need to trim the incoming segment. */
1364                                        inseg.len =
1365                                          (u16_t) (next->tcphdr->seqno - seqno);
1366                                        pbuf_realloc(inseg.p, inseg.len);
1367                                    }
1368                                    cseg = tcp_seg_copy(&inseg);
1369                                    if (cseg != NULL) {
1370                                        cseg->next = next;
1371                                        pcb->ooseq = cseg;
1372                                    }
1373                                    break;
1374                                }
1375                            } else
1376                                /*if (TCP_SEQ_LT(prev->tcphdr->seqno, seqno) &&
1377                                   TCP_SEQ_LT(seqno, next->tcphdr->seqno)) { */
1378                            if (TCP_SEQ_BETWEEN
1379                                    (seqno, prev->tcphdr->seqno + 1,
1380                                         next->tcphdr->seqno - 1)) {
1381                                /* The sequence number of the incoming segment is in
1382                                   between the sequence numbers of the previous and
1383                                   the next segment on ->ooseq. We trim and insert the
1384                                   incoming segment and trim the previous segment, if
1385                                   needed. */
1386                                if (TCP_SEQ_GT
1387                                    (seqno + inseg.len, next->tcphdr->seqno)) {
1388                                    /* We need to trim the incoming segment. */
1389                                    inseg.len =
1390                                      (u16_t) (next->tcphdr->seqno - seqno);
1391                                    pbuf_realloc(inseg.p, inseg.len);
1392                                }
1393
1394                                cseg = tcp_seg_copy(&inseg);
1395                                if (cseg != NULL) {
1396                                    cseg->next = next;
1397                                    prev->next = cseg;
1398                                    if (TCP_SEQ_GT
1399                                        (prev->tcphdr->seqno + prev->len,
1400                                         seqno)) {
1401                                        /* We need to trim the prev segment. */
1402                                        prev->len =
1403                                          (u16_t) (seqno - prev->tcphdr->seqno);
1404                                        pbuf_realloc(prev->p, prev->len);
1405                                    }
1406                                }
1407                                break;
1408                            }
1409                            /* If the "next" segment is the last segment on the
1410                               ooseq queue, we add the incoming segment to the end
1411                               of the list. */
1412                            if (next->next == NULL &&
1413                                TCP_SEQ_GT(seqno, next->tcphdr->seqno)) {
1414                                next->next = tcp_seg_copy(&inseg);
1415                                if (next->next != NULL) {
1416                                    if (TCP_SEQ_GT
1417                                        (next->tcphdr->seqno + next->len,
1418                                         seqno)) {
1419                                        /* We need to trim the last segment. */
1420                                        next->len =
1421                                          (u16_t) (seqno - next->tcphdr->seqno);
1422                                        pbuf_realloc(next->p, next->len);
1423                                    }
1424                                }
1425                                break;
1426                            }
1427                        }
1428                        prev = next;
1429                    }
1430                }
1431#endif                          /* TCP_QUEUE_OOSEQ */
1432
1433            }
1434        } else {
1435            tcp_ack_now(pcb);
1436        }
1437    } else {
1438        /* Segments with length 0 is taken care of here. Segments that
1439           fall out of the window are ACKed. */
1440        /*if (TCP_SEQ_GT(pcb->rcv_nxt, seqno) ||
1441           TCP_SEQ_GEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) { */
1442        if (!TCP_SEQ_BETWEEN
1443            (seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd - 1)) {
1444            tcp_ack_now(pcb);
1445        }
1446    }
1447    return accepted_inseq;
1448}
1449
1450/**
1451 * Parses the options contained in the incoming segment.
1452 *
1453 * Called from tcp_listen_input() and tcp_process().
1454 * Currently, only the MSS option is supported!
1455 *
1456 * @param pcb the tcp_pcb for which a segment arrived
1457 */
1458static void tcp_parseopt(struct tcp_pcb *pcb)
1459{
1460    u16_t c, max_c;
1461    u16_t mss;
1462    u8_t *opts, opt;
1463
1464#if LWIP_TCP_TIMESTAMPS
1465    u32_t tsval;
1466#endif
1467
1468    opts = (u8_t *) tcphdr + TCP_HLEN;
1469
1470    /* Parse the TCP MSS option, if present. */
1471    if (TCPH_HDRLEN(tcphdr) > 0x5) {
1472        max_c = (TCPH_HDRLEN(tcphdr) - 5) << 2;
1473        for (c = 0; c < max_c;) {
1474            opt = opts[c];
1475            switch (opt) {
1476                case 0x00:
1477                    /* End of options. */
1478                    LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: EOL\n"));
1479                    return;
1480                case 0x01:
1481                    /* NOP option. */
1482                    ++c;
1483                    LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: NOP\n"));
1484                    break;
1485                case 0x02:
1486                    LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: MSS\n"));
1487                    if (opts[c + 1] != 0x04 || c + 0x04 > max_c) {
1488                        /* Bad length */
1489                        LWIP_DEBUGF(TCP_INPUT_DEBUG,
1490                                    ("tcp_parseopt: bad length\n"));
1491                        return;
1492                    }
1493                    /* An MSS option with the right option length. */
1494                    mss = (opts[c + 2] << 8) | opts[c + 3];
1495                    /* Limit the mss to the configured TCP_MSS and prevent division by zero */
1496                    pcb->mss = ((mss > TCP_MSS) || (mss == 0)) ? TCP_MSS : mss;
1497                    /* Advance to next option */
1498                    c += 0x04;
1499                    break;
1500#if LWIP_TCP_TIMESTAMPS
1501                case 0x08:
1502                    LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: TS\n"));
1503                    if (opts[c + 1] != 0x0A || c + 0x0A > max_c) {
1504                        /* Bad length */
1505                        LWIP_DEBUGF(TCP_INPUT_DEBUG,
1506                                    ("tcp_parseopt: bad length\n"));
1507                        return;
1508                    }
1509                    /* TCP timestamp option with valid length */
1510                    tsval = (opts[c + 2]) | (opts[c + 3] << 8) |
1511                      (opts[c + 4] << 16) | (opts[c + 5] << 24);
1512                    if (flags & TCP_SYN) {
1513                        pcb->ts_recent = ntohl(tsval);
1514                        pcb->flags |= TF_TIMESTAMP;
1515                    } else
1516                      if (TCP_SEQ_BETWEEN
1517                          (pcb->ts_lastacksent, seqno, seqno + tcplen)) {
1518                        pcb->ts_recent = ntohl(tsval);
1519                    }
1520                    /* Advance to next option */
1521                    c += 0x0A;
1522                    break;
1523#endif
1524                default:
1525                    LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: other\n"));
1526                    if (opts[c + 1] == 0) {
1527                        LWIP_DEBUGF(TCP_INPUT_DEBUG,
1528                                    ("tcp_parseopt: bad length\n"));
1529                        /* If the length field is zero, the options are malformed
1530                           and we don't process them further. */
1531                        return;
1532                    }
1533                    /* All other options have a length field, so that we easily
1534                       can skip past them. */
1535                    c += opts[c + 1];
1536            }
1537        }
1538    }
1539}
1540
1541#endif                          /* LWIP_TCP */
1542