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