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