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