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