• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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. */
62 static struct tcp_seg inseg;
63 static struct tcp_hdr *tcphdr;
64 static struct ip_hdr *iphdr;
65 static u32_t seqno, ackno;
66 static u8_t flags;
67 static u16_t tcplen;
68 
69 static u8_t recv_flags;
70 static struct pbuf *recv_data;
71 
72 struct tcp_pcb *tcp_input_pcb;
73 
74 /* Forward declarations. */
75 static err_t tcp_process(struct tcp_pcb *pcb);
76 static void tcp_receive(struct tcp_pcb *pcb);
77 static void tcp_parseopt(struct tcp_pcb *pcb);
78 
79 static err_t tcp_listen_input(struct tcp_pcb_listen *pcb);
80 static 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  */
91 void
tcp_input(struct pbuf * p,struct netif * inp)92 tcp_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! */
400 aborted:
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  */
441 static err_t
tcp_listen_input(struct tcp_pcb_listen * pcb)442 tcp_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  */
525 static err_t
tcp_timewait_input(struct tcp_pcb * pcb)526 tcp_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  */
571 static err_t
tcp_process(struct tcp_pcb * pcb)572 tcp_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  */
796 static void
tcp_oos_insert_segment(struct tcp_seg * cseg,struct tcp_seg * next)797 tcp_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  */
843 static void
tcp_receive(struct tcp_pcb * pcb)844 tcp_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  */
1489 static void
tcp_parseopt(struct tcp_pcb * pcb)1490 tcp_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