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