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