3 * Transmission Control Protocol, incoming traffic
5 * The input processing functions of the TCP layer.
7 * These functions are generally called in the order (ip_input() ->)
8 * tcp_input() -> * tcp_process() -> tcp_receive() (-> application).
13 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
14 * All rights reserved.
16 * Redistribution and use in source and binary forms, with or without modification,
17 * are permitted provided that the following conditions are met:
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.
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
38 * This file is part of the lwIP TCP/IP stack.
40 * Author: Adam Dunkels <adam@sics.se>
46 #if LWIP_TCP /* don't build if not configured for use in lwipopts.h */
50 #include "lwip/ip_addr.h"
51 #include "lwip/netif.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"
60 /* These variables are global to all functions involved in the input
61 processing of TCP segments. They are set by the tcp_input()
63 static struct tcp_seg inseg;
64 static struct tcp_hdr *tcphdr;
65 static struct ip_hdr *iphdr;
66 static u32_t seqno, ackno;
70 static u8_t recv_flags;
71 static struct pbuf *recv_data;
73 struct tcp_pcb *tcp_input_pcb;
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);
80 static err_t tcp_listen_input(struct tcp_pcb_listen *pcb);
81 static err_t tcp_timewait_input(struct tcp_pcb *pcb);
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
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
93 tcp_input(struct pbuf *p, struct netif *inp)
95 struct tcp_pcb *pcb, *prev;
96 struct tcp_pcb_listen *lpcb;
102 TCP_STATS_INC(tcp.recv);
103 snmp_inc_tcpinsegs();
106 tcphdr = (struct tcp_hdr *)((u8_t *)p->payload + IPH_HL(iphdr) * 4);
109 tcp_debug_print(tcphdr);
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();
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();
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)));
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();
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();
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);
172 flags = TCPH_FLAGS(tcphdr);
173 tcplen = p->tot_len + ((flags & (TCP_FIN | TCP_SYN)) ? 1 : 0);
175 /* Demultiplex an incoming segment. First, we check if it is destined
176 for an active connection. */
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))) {
189 /* Move this PCB to the front of the list so that subsequent
190 lookups will be faster (we exploit locality in TCP segment
192 LWIP_ASSERT("tcp_input: pcb->next != pcb (before cache)", pcb->next != pcb);
194 prev->next = pcb->next;
195 pcb->next = tcp_active_pcbs;
196 tcp_active_pcbs = pcb;
198 LWIP_ASSERT("tcp_input: pcb->next != pcb (after cache)", pcb->next != pcb);
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);
223 /* Finally, if we still did not get a match, we check all PCBs that
224 are LISTENing for incoming connections. */
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
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;
241 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for LISTENing connection.\n"));
242 tcp_listen_input(lpcb);
246 prev = (struct tcp_pcb *)lpcb;
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 */
258 /* The incoming segment belongs to a connection. */
261 tcp_debug_print_state(pcb->state);
262 #endif /* TCP_DEBUG */
263 #endif /* TCP_INPUT_DEBUG */
265 /* Set up a tcp_seg structure. */
267 inseg.len = p->tot_len;
268 inseg.dataptr = p->payload;
270 inseg.tcphdr = tcphdr;
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);
281 pcb->refused_data = NULL;
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();
292 err = tcp_process(pcb);
293 /* A return value of ERR_ABRT means that tcp_abort() was called
294 and that the pcb has been freed. If so, we don't do anything. */
295 if (err != ERR_ABRT) {
296 if (recv_flags & TF_RESET) {
297 /* TF_RESET means that the connection was reset by the other
298 end. We then call the error callback to inform the
299 application that the connection is dead before we
300 deallocate the PCB. */
301 TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_RST);
302 tcp_pcb_remove(&tcp_active_pcbs, pcb);
303 memp_free(MEMP_TCP_PCB, pcb);
304 } else if (recv_flags & TF_CLOSED) {
305 /* The connection has been closed and we will deallocate the
307 tcp_pcb_remove(&tcp_active_pcbs, pcb);
308 memp_free(MEMP_TCP_PCB, pcb);
311 /* If the application has registered a "sent" function to be
312 called when new send buffer space is available, we call it
314 if (pcb->acked > 0) {
315 TCP_EVENT_SENT(pcb, pcb->acked, err);
318 if (recv_data != NULL) {
319 if(flags & TCP_PSH) {
320 recv_data->flags |= PBUF_FLAG_PUSH;
323 /* Notify application that data has been received. */
324 TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err);
326 /* If the upper layer can't receive this data, store it */
328 pcb->refused_data = recv_data;
329 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: keep incoming packet, because pcb is \"full\"\n"));
333 /* If a FIN segment was received, we call the callback
334 function with a NULL buffer to indicate EOF. */
335 if (recv_flags & TF_GOT_FIN) {
336 TCP_EVENT_RECV(pcb, NULL, ERR_OK, err);
339 tcp_input_pcb = NULL;
340 /* Try to send something out. */
344 tcp_debug_print_state(pcb->state);
345 #endif /* TCP_DEBUG */
346 #endif /* TCP_INPUT_DEBUG */
349 tcp_input_pcb = NULL;
352 /* give up our reference to inseg.p */
360 /* If no matching PCB was found, send a TCP RST (reset) to the
362 LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_input: no PCB match found, resetting.\n"));
363 if (!(TCPH_FLAGS(tcphdr) & TCP_RST)) {
364 TCP_STATS_INC(tcp.proterr);
365 TCP_STATS_INC(tcp.drop);
366 tcp_rst(ackno, seqno + tcplen,
367 &(iphdr->dest), &(iphdr->src),
368 tcphdr->dest, tcphdr->src);
373 LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane());
374 PERF_STOP("tcp_input");
378 * Called by tcp_input() when a segment arrives for a listening
379 * connection (from tcp_input()).
381 * @param pcb the tcp_pcb_listen for which a segment arrived
382 * @return ERR_OK if the segment was processed
383 * another err_t on error
385 * @note the return value is not (yet?) used in tcp_input()
386 * @note the segment which arrived is saved in global variables, therefore only the pcb
387 * involved is passed as a parameter to this function
390 tcp_listen_input(struct tcp_pcb_listen *pcb)
392 struct tcp_pcb *npcb;
395 /* In the LISTEN state, we check for incoming SYN segments,
396 creates a new PCB, and responds with a SYN|ACK. */
397 if (flags & TCP_ACK) {
398 /* For incoming segments with the ACK flag set, respond with a
400 LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_listen_input: ACK in LISTEN, sending reset\n"));
401 tcp_rst(ackno + 1, seqno + tcplen,
402 &(iphdr->dest), &(iphdr->src),
403 tcphdr->dest, tcphdr->src);
404 } else if (flags & TCP_SYN) {
405 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection request %"U16_F" -> %"U16_F".\n", tcphdr->src, tcphdr->dest));
406 #if TCP_LISTEN_BACKLOG
407 if (pcb->accepts_pending >= pcb->backlog) {
408 LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: listen backlog exceeded for port %"U16_F"\n", tcphdr->dest));
411 #endif /* TCP_LISTEN_BACKLOG */
412 npcb = tcp_alloc(pcb->prio);
413 /* If a new PCB could not be created (probably due to lack of memory),
414 we don't do anything, but rely on the sender will retransmit the
415 SYN at a time when we have more memory available. */
417 LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: could not allocate PCB\n"));
418 TCP_STATS_INC(tcp.memerr);
421 #if TCP_LISTEN_BACKLOG
422 pcb->accepts_pending++;
423 #endif /* TCP_LISTEN_BACKLOG */
424 /* Set up the new PCB. */
425 ip_addr_set(&(npcb->local_ip), &(iphdr->dest));
426 npcb->local_port = pcb->local_port;
427 ip_addr_set(&(npcb->remote_ip), &(iphdr->src));
428 npcb->remote_port = tcphdr->src;
429 npcb->state = SYN_RCVD;
430 npcb->rcv_nxt = seqno + 1;
431 npcb->rcv_ann_right_edge = npcb->rcv_nxt;
432 npcb->snd_wnd = tcphdr->wnd;
433 npcb->ssthresh = npcb->snd_wnd;
434 npcb->snd_wl1 = seqno - 1;/* initialise to seqno-1 to force window update */
435 npcb->callback_arg = pcb->callback_arg;
436 #if LWIP_CALLBACK_API
437 npcb->accept = pcb->accept;
438 #endif /* LWIP_CALLBACK_API */
439 /* inherit socket options */
440 npcb->so_options = pcb->so_options & (SOF_DEBUG|SOF_DONTROUTE|SOF_KEEPALIVE|SOF_OOBINLINE|SOF_LINGER);
441 /* Register the new PCB so that we can begin receiving segments
443 TCP_REG(&tcp_active_pcbs, npcb);
445 /* Parse any options in the SYN. */
447 #if TCP_CALCULATE_EFF_SEND_MSS
448 npcb->mss = tcp_eff_send_mss(npcb->mss, &(npcb->remote_ip));
449 #endif /* TCP_CALCULATE_EFF_SEND_MSS */
451 snmp_inc_tcppassiveopens();
453 /* Send a SYN|ACK together with the MSS option. */
454 rc = tcp_enqueue(npcb, NULL, 0, TCP_SYN | TCP_ACK, 0, TF_SEG_OPTS_MSS
455 #if LWIP_TCP_TIMESTAMPS
456 /* and maybe include the TIMESTAMP option */
457 | (npcb->flags & TF_TIMESTAMP ? TF_SEG_OPTS_TS : 0)
461 tcp_abandon(npcb, 0);
464 return tcp_output(npcb);
470 * Called by tcp_input() when a segment arrives for a connection in
473 * @param pcb the tcp_pcb for which a segment arrived
475 * @note the segment which arrived is saved in global variables, therefore only the pcb
476 * involved is passed as a parameter to this function
479 tcp_timewait_input(struct tcp_pcb *pcb)
481 /* RFC 1337: in TIME_WAIT, ignore RST and ACK FINs + any 'acceptable' segments */
482 /* RFC 793 3.9 Event Processing - Segment Arrives:
483 * - first check sequence number - we skip that one in TIME_WAIT (always
484 * acceptable since we only send ACKs)
485 * - second check the RST bit (... return) */
486 if (flags & TCP_RST) {
489 /* - fourth, check the SYN bit, */
490 if (flags & TCP_SYN) {
491 /* If an incoming segment is not acceptable, an acknowledgment
492 should be sent in reply */
493 if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt+pcb->rcv_wnd)) {
494 /* If the SYN is in the window it is an error, send a reset */
495 tcp_rst(ackno, seqno + tcplen, &(iphdr->dest), &(iphdr->src),
496 tcphdr->dest, tcphdr->src);
499 } else if (flags & TCP_FIN) {
500 /* - eighth, check the FIN bit: Remain in the TIME-WAIT state.
501 Restart the 2 MSL time-wait timeout.*/
502 pcb->tmr = tcp_ticks;
506 /* Acknowledge data, FIN or out-of-window SYN */
507 pcb->flags |= TF_ACK_NOW;
508 return tcp_output(pcb);
514 * Implements the TCP state machine. Called by tcp_input. In some
515 * states tcp_receive() is called to receive data. The tcp_seg
516 * argument will be freed by the caller (tcp_input()) unless the
517 * recv_data pointer in the pcb is set.
519 * @param pcb the tcp_pcb for which a segment arrived
521 * @note the segment which arrived is saved in global variables, therefore only the pcb
522 * involved is passed as a parameter to this function
525 tcp_process(struct tcp_pcb *pcb)
527 struct tcp_seg *rseg;
533 /* Process incoming RST segments. */
534 if (flags & TCP_RST) {
535 /* First, determine if the reset is acceptable. */
536 if (pcb->state == SYN_SENT) {
537 if (ackno == pcb->snd_nxt) {
541 if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt,
542 pcb->rcv_nxt+pcb->rcv_wnd)) {
548 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: Connection RESET\n"));
549 LWIP_ASSERT("tcp_input: pcb->state != CLOSED", pcb->state != CLOSED);
550 recv_flags |= TF_RESET;
551 pcb->flags &= ~TF_ACK_DELAY;
554 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n",
555 seqno, pcb->rcv_nxt));
556 LWIP_DEBUGF(TCP_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n",
557 seqno, pcb->rcv_nxt));
562 if ((flags & TCP_SYN) && (pcb->state != SYN_SENT && pcb->state != SYN_RCVD)) {
563 /* Cope with new connection attempt after remote end crashed */
568 /* Update the PCB (in)activity timer. */
569 pcb->tmr = tcp_ticks;
570 pcb->keep_cnt_sent = 0;
574 /* Do different things depending on the TCP state. */
575 switch (pcb->state) {
577 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %"U32_F" pcb->snd_nxt %"U32_F" unacked %"U32_F"\n", ackno,
578 pcb->snd_nxt, ntohl(pcb->unacked->tcphdr->seqno)));
579 /* received SYN ACK with expected sequence number? */
580 if ((flags & TCP_ACK) && (flags & TCP_SYN)
581 && ackno == ntohl(pcb->unacked->tcphdr->seqno) + 1) {
583 pcb->rcv_nxt = seqno + 1;
584 pcb->rcv_ann_right_edge = pcb->rcv_nxt;
585 pcb->lastack = ackno;
586 pcb->snd_wnd = tcphdr->wnd;
587 pcb->snd_wl1 = seqno - 1; /* initialise to seqno - 1 to force window update */
588 pcb->state = ESTABLISHED;
590 #if TCP_CALCULATE_EFF_SEND_MSS
591 pcb->mss = tcp_eff_send_mss(pcb->mss, &(pcb->remote_ip));
592 #endif /* TCP_CALCULATE_EFF_SEND_MSS */
594 /* Set ssthresh again after changing pcb->mss (already set in tcp_connect
595 * but for the default value of pcb->mss) */
596 pcb->ssthresh = pcb->mss * 10;
598 pcb->cwnd = ((pcb->cwnd == 1) ? (pcb->mss * 2) : pcb->mss);
599 LWIP_ASSERT("pcb->snd_queuelen > 0", (pcb->snd_queuelen > 0));
601 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_process: SYN-SENT --queuelen %"U16_F"\n", (u16_t)pcb->snd_queuelen));
603 pcb->unacked = rseg->next;
605 /* If there's nothing left to acknowledge, stop the retransmit
606 timer, otherwise reset it to start again */
607 if(pcb->unacked == NULL)
616 /* Call the user specified function to call when sucessfully
618 TCP_EVENT_CONNECTED(pcb, ERR_OK, err);
621 /* received ACK? possibly a half-open connection */
622 else if (flags & TCP_ACK) {
623 /* send a RST to bring the other side in a non-synchronized state. */
624 tcp_rst(ackno, seqno + tcplen, &(iphdr->dest), &(iphdr->src),
625 tcphdr->dest, tcphdr->src);
629 if (flags & TCP_ACK) {
630 /* expected ACK number? */
631 if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)) {
633 pcb->state = ESTABLISHED;
634 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection established %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
635 #if LWIP_CALLBACK_API
636 LWIP_ASSERT("pcb->accept != NULL", pcb->accept != NULL);
638 /* Call the accept function. */
639 TCP_EVENT_ACCEPT(pcb, ERR_OK, err);
641 /* If the accept function returns with an error, we abort
646 old_cwnd = pcb->cwnd;
647 /* If there was any data contained within this ACK,
648 * we'd better pass it on to the application as well. */
651 /* Prevent ACK for SYN to generate a sent event */
652 if (pcb->acked != 0) {
656 pcb->cwnd = ((old_cwnd == 1) ? (pcb->mss * 2) : pcb->mss);
658 if (recv_flags & TF_GOT_FIN) {
660 pcb->state = CLOSE_WAIT;
663 /* incorrect ACK number */
666 tcp_rst(ackno, seqno + tcplen, &(iphdr->dest), &(iphdr->src),
667 tcphdr->dest, tcphdr->src);
669 } else if ((flags & TCP_SYN) && (seqno == pcb->rcv_nxt - 1)) {
670 /* Looks like another copy of the SYN - retransmit our SYN-ACK */
678 if (recv_flags & TF_GOT_FIN) { /* passive close */
680 pcb->state = CLOSE_WAIT;
685 if (recv_flags & TF_GOT_FIN) {
686 if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) {
687 LWIP_DEBUGF(TCP_DEBUG,
688 ("TCP connection closed: FIN_WAIT_1 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
691 TCP_RMV(&tcp_active_pcbs, pcb);
692 pcb->state = TIME_WAIT;
693 TCP_REG(&tcp_tw_pcbs, pcb);
696 pcb->state = CLOSING;
698 } else if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) {
699 pcb->state = FIN_WAIT_2;
704 if (recv_flags & TF_GOT_FIN) {
705 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: FIN_WAIT_2 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
708 TCP_RMV(&tcp_active_pcbs, pcb);
709 pcb->state = TIME_WAIT;
710 TCP_REG(&tcp_tw_pcbs, pcb);
715 if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
716 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: CLOSING %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
718 TCP_RMV(&tcp_active_pcbs, pcb);
719 pcb->state = TIME_WAIT;
720 TCP_REG(&tcp_tw_pcbs, pcb);
725 if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
726 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: LAST_ACK %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
727 /* bugfix #21699: don't set pcb->state to CLOSED here or we risk leaking segments */
728 recv_flags |= TF_CLOSED;
739 * Insert segment into the list (segments covered with new one will be deleted)
741 * Called from tcp_receive()
744 tcp_oos_insert_segment(struct tcp_seg *cseg, struct tcp_seg *next)
746 struct tcp_seg *old_seg;
748 if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) {
749 /* received segment overlaps all following segments */
754 /* delete some following segments
755 oos queue may have segments with FIN flag */
757 TCP_SEQ_GEQ((seqno + cseg->len),
758 (next->tcphdr->seqno + next->len))) {
759 /* cseg with FIN already processed */
760 if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) {
761 TCPH_FLAGS_SET(cseg->tcphdr, TCPH_FLAGS(cseg->tcphdr) | TCP_FIN);
765 tcp_seg_free(old_seg);
768 TCP_SEQ_GT(seqno + cseg->len, next->tcphdr->seqno)) {
769 /* We need to trim the incoming segment. */
770 cseg->len = (u16_t)(next->tcphdr->seqno - seqno);
771 pbuf_realloc(cseg->p, cseg->len);
779 * Called by tcp_process. Checks if the given segment is an ACK for outstanding
780 * data, and if so frees the memory of the buffered data. Next, is places the
781 * segment on any of the receive queues (pcb->recved or pcb->ooseq). If the segment
782 * is buffered, the pbuf is referenced by pbuf_ref so that it will not be freed until
783 * i it has been removed from the buffer.
785 * If the incoming segment constitutes an ACK for a segment that was used for RTT
786 * estimation, the RTT is estimated here as well.
788 * Called from tcp_process().
791 tcp_receive(struct tcp_pcb *pcb)
793 struct tcp_seg *next;
795 struct tcp_seg *prev, *cseg;
800 u32_t right_wnd_edge;
802 int found_dupack = 0;
804 if (flags & TCP_ACK) {
805 right_wnd_edge = pcb->snd_wnd + pcb->snd_wl2;
808 if (TCP_SEQ_LT(pcb->snd_wl1, seqno) ||
809 (pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) ||
810 (pcb->snd_wl2 == ackno && tcphdr->wnd > pcb->snd_wnd)) {
811 pcb->snd_wnd = tcphdr->wnd;
812 pcb->snd_wl1 = seqno;
813 pcb->snd_wl2 = ackno;
814 if (pcb->snd_wnd > 0 && pcb->persist_backoff > 0) {
815 pcb->persist_backoff = 0;
817 LWIP_DEBUGF(TCP_WND_DEBUG, ("tcp_receive: window update %"U16_F"\n", pcb->snd_wnd));
820 if (pcb->snd_wnd != tcphdr->wnd) {
821 LWIP_DEBUGF(TCP_WND_DEBUG,
822 ("tcp_receive: no window update lastack %"U32_F" ackno %"
823 U32_F" wl1 %"U32_F" seqno %"U32_F" wl2 %"U32_F"\n",
824 pcb->lastack, ackno, pcb->snd_wl1, seqno, pcb->snd_wl2));
826 #endif /* TCP_WND_DEBUG */
829 /* (From Stevens TCP/IP Illustrated Vol II, p970.) Its only a
831 * 1) It doesn't ACK new data
832 * 2) length of received packet is zero (i.e. no payload)
833 * 3) the advertised window hasn't changed
834 * 4) There is outstanding unacknowledged data (retransmission timer running)
835 * 5) The ACK is == biggest ACK sequence number so far seen (snd_una)
837 * If it passes all five, should process as a dupack:
838 * a) dupacks < 3: do nothing
839 * b) dupacks == 3: fast retransmit
840 * c) dupacks > 3: increase cwnd
842 * If it only passes 1-3, should reset dupack counter (and add to
843 * stats, which we don't do in lwIP)
845 * If it only passes 1, should reset dupack counter
850 if (TCP_SEQ_LEQ(ackno, pcb->lastack)) {
855 if (pcb->snd_wl2 + pcb->snd_wnd == right_wnd_edge){
857 if (pcb->rtime >= 0) {
859 if (pcb->lastack == ackno) {
861 if (pcb->dupacks + 1 > pcb->dupacks)
863 if (pcb->dupacks > 3) {
864 /* Inflate the congestion window, but not if it means that
865 the value overflows. */
866 if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {
867 pcb->cwnd += pcb->mss;
869 } else if (pcb->dupacks == 3) {
870 /* Do fast retransmit */
871 tcp_rexmit_fast(pcb);
877 /* If Clause (1) or more is true, but not a duplicate ack, reset
878 * count of consecutive duplicate acks */
882 } else if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)){
883 /* We come here when the ACK acknowledges new data. */
885 /* Reset the "IN Fast Retransmit" flag, since we are no longer
886 in fast retransmit. Also reset the congestion window to the
887 slow start threshold. */
888 if (pcb->flags & TF_INFR) {
889 pcb->flags &= ~TF_INFR;
890 pcb->cwnd = pcb->ssthresh;
893 /* Reset the number of retransmissions. */
896 /* Reset the retransmission time-out. */
897 pcb->rto = (pcb->sa >> 3) + pcb->sv;
899 /* Update the send buffer space. Diff between the two can never exceed 64K? */
900 pcb->acked = (u16_t)(ackno - pcb->lastack);
902 pcb->snd_buf += pcb->acked;
904 /* Reset the fast retransmit variables. */
906 pcb->lastack = ackno;
908 /* Update the congestion control variables (cwnd and
910 if (pcb->state >= ESTABLISHED) {
911 if (pcb->cwnd < pcb->ssthresh) {
912 if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {
913 pcb->cwnd += pcb->mss;
915 LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: slow start cwnd %"U16_F"\n", pcb->cwnd));
917 u16_t new_cwnd = (pcb->cwnd + pcb->mss * pcb->mss / pcb->cwnd);
918 if (new_cwnd > pcb->cwnd) {
919 pcb->cwnd = new_cwnd;
921 LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: congestion avoidance cwnd %"U16_F"\n", pcb->cwnd));
924 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: ACK for %"U32_F", unacked->seqno %"U32_F":%"U32_F"\n",
926 pcb->unacked != NULL?
927 ntohl(pcb->unacked->tcphdr->seqno): 0,
928 pcb->unacked != NULL?
929 ntohl(pcb->unacked->tcphdr->seqno) + TCP_TCPLEN(pcb->unacked): 0));
931 /* Remove segment from the unacknowledged list if the incoming
932 ACK acknowlegdes them. */
933 while (pcb->unacked != NULL &&
934 TCP_SEQ_LEQ(ntohl(pcb->unacked->tcphdr->seqno) +
935 TCP_TCPLEN(pcb->unacked), ackno)) {
936 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unacked\n",
937 ntohl(pcb->unacked->tcphdr->seqno),
938 ntohl(pcb->unacked->tcphdr->seqno) +
939 TCP_TCPLEN(pcb->unacked)));
942 pcb->unacked = pcb->unacked->next;
944 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen));
945 LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p)));
946 /* Prevent ACK for FIN to generate a sent event */
947 if ((pcb->acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) {
951 pcb->snd_queuelen -= pbuf_clen(next->p);
954 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U16_F" (after freeing unacked)\n", (u16_t)pcb->snd_queuelen));
955 if (pcb->snd_queuelen != 0) {
956 LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL ||
957 pcb->unsent != NULL);
961 /* If there's nothing left to acknowledge, stop the retransmit
962 timer, otherwise reset it to start again */
963 if(pcb->unacked == NULL)
970 /* Fix bug bug #21582: out of sequence ACK, didn't really ack anything */
974 /* We go through the ->unsent list to see if any of the segments
975 on the list are acknowledged by the ACK. This may seem
976 strange since an "unsent" segment shouldn't be acked. The
977 rationale is that lwIP puts all outstanding segments on the
978 ->unsent list after a retransmission, so these segments may
979 in fact have been sent once. */
980 while (pcb->unsent != NULL &&
981 TCP_SEQ_BETWEEN(ackno, ntohl(pcb->unsent->tcphdr->seqno) +
982 TCP_TCPLEN(pcb->unsent), pcb->snd_nxt)) {
983 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unsent\n",
984 ntohl(pcb->unsent->tcphdr->seqno), ntohl(pcb->unsent->tcphdr->seqno) +
985 TCP_TCPLEN(pcb->unsent)));
988 pcb->unsent = pcb->unsent->next;
989 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen));
990 LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p)));
991 /* Prevent ACK for FIN to generate a sent event */
992 if ((pcb->acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) {
995 pcb->snd_queuelen -= pbuf_clen(next->p);
997 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U16_F" (after freeing unsent)\n", (u16_t)pcb->snd_queuelen));
998 if (pcb->snd_queuelen != 0) {
999 LWIP_ASSERT("tcp_receive: valid queue length",
1000 pcb->unacked != NULL || pcb->unsent != NULL);
1003 /* End of ACK for new data processing. */
1005 LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: pcb->rttest %"U32_F" rtseq %"U32_F" ackno %"U32_F"\n",
1006 pcb->rttest, pcb->rtseq, ackno));
1008 /* RTT estimation calculations. This is done by checking if the
1009 incoming segment acknowledges the segment we use to take a
1010 round-trip time measurement. */
1011 if (pcb->rttest && TCP_SEQ_LT(pcb->rtseq, ackno)) {
1012 /* diff between this shouldn't exceed 32K since this are tcp timer ticks
1013 and a round-trip shouldn't be that long... */
1014 m = (s16_t)(tcp_ticks - pcb->rttest);
1016 LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: experienced rtt %"U16_F" ticks (%"U16_F" msec).\n",
1017 m, m * TCP_SLOW_INTERVAL));
1019 /* This is taken directly from VJs original code in his paper */
1020 m = m - (pcb->sa >> 3);
1025 m = m - (pcb->sv >> 2);
1027 pcb->rto = (pcb->sa >> 3) + pcb->sv;
1029 LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: RTO %"U16_F" (%"U16_F" milliseconds)\n",
1030 pcb->rto, pcb->rto * TCP_SLOW_INTERVAL));
1036 /* If the incoming segment contains data, we must process it
1039 /* This code basically does three things:
1041 +) If the incoming segment contains data that is the next
1042 in-sequence data, this data is passed to the application. This
1043 might involve trimming the first edge of the data. The rcv_nxt
1044 variable and the advertised window are adjusted.
1046 +) If the incoming segment has data that is above the next
1047 sequence number expected (->rcv_nxt), the segment is placed on
1048 the ->ooseq queue. This is done by finding the appropriate
1049 place in the ->ooseq queue (which is ordered by sequence
1050 number) and trim the segment in both ends if needed. An
1051 immediate ACK is sent to indicate that we received an
1052 out-of-sequence segment.
1054 +) Finally, we check if the first segment on the ->ooseq queue
1055 now is in sequence (i.e., if rcv_nxt >= ooseq->seqno). If
1056 rcv_nxt > ooseq->seqno, we must trim the first edge of the
1057 segment on ->ooseq before we adjust rcv_nxt. The data in the
1058 segments that are now on sequence are chained onto the
1059 incoming segment so that we only need to call the application
1063 /* First, we check if we must trim the first edge. We have to do
1064 this if the sequence number of the incoming segment is less
1065 than rcv_nxt, and the sequence number plus the length of the
1066 segment is larger than rcv_nxt. */
1067 /* if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)){
1068 if (TCP_SEQ_LT(pcb->rcv_nxt, seqno + tcplen)) {*/
1069 if (TCP_SEQ_BETWEEN(pcb->rcv_nxt, seqno + 1, seqno + tcplen - 1)){
1070 /* Trimming the first edge is done by pushing the payload
1071 pointer in the pbuf downwards. This is somewhat tricky since
1072 we do not want to discard the full contents of the pbuf up to
1073 the new starting point of the data since we have to keep the
1074 TCP header which is present in the first pbuf in the chain.
1076 What is done is really quite a nasty hack: the first pbuf in
1077 the pbuf chain is pointed to by inseg.p. Since we need to be
1078 able to deallocate the whole pbuf, we cannot change this
1079 inseg.p pointer to point to any of the later pbufs in the
1080 chain. Instead, we point the ->payload pointer in the first
1081 pbuf to data in one of the later pbufs. We also set the
1082 inseg.data pointer to point to the right place. This way, the
1083 ->p pointer will still point to the first pbuf, but the
1084 ->p->payload pointer will point to data in another pbuf.
1086 After we are done with adjusting the pbuf pointers we must
1087 adjust the ->data pointer in the seg and the segment
1090 off = pcb->rcv_nxt - seqno;
1092 LWIP_ASSERT("inseg.p != NULL", inseg.p);
1093 LWIP_ASSERT("insane offset!", (off < 0x7fff));
1094 if (inseg.p->len < off) {
1095 LWIP_ASSERT("pbuf too short!", (((s32_t)inseg.p->tot_len) >= off));
1096 new_tot_len = (u16_t)(inseg.p->tot_len - off);
1097 while (p->len < off) {
1099 /* KJM following line changed (with addition of new_tot_len var)
1101 inseg.p->tot_len -= p->len; */
1102 p->tot_len = new_tot_len;
1106 if(pbuf_header(p, (s16_t)-off)) {
1107 /* Do we need to cope with this failing? Assert for now */
1108 LWIP_ASSERT("pbuf_header failed", 0);
1111 if(pbuf_header(inseg.p, (s16_t)-off)) {
1112 /* Do we need to cope with this failing? Assert for now */
1113 LWIP_ASSERT("pbuf_header failed", 0);
1116 /* KJM following line changed to use p->payload rather than inseg->p->payload
1118 inseg.dataptr = p->payload;
1119 inseg.len -= (u16_t)(pcb->rcv_nxt - seqno);
1120 inseg.tcphdr->seqno = seqno = pcb->rcv_nxt;
1123 if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)){
1124 /* the whole segment is < rcv_nxt */
1125 /* must be a duplicate of a packet that has already been correctly handled */
1127 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: duplicate seqno %"U32_F"\n", seqno));
1132 /* The sequence number must be within the window (above rcv_nxt
1133 and below rcv_nxt + rcv_wnd) in order to be further
1135 if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt,
1136 pcb->rcv_nxt + pcb->rcv_wnd - 1)){
1137 if (pcb->rcv_nxt == seqno) {
1138 /* The incoming segment is the next in sequence. We check if
1139 we have to trim the end of the segment and update rcv_nxt
1140 and pass the data to the application. */
1141 tcplen = TCP_TCPLEN(&inseg);
1143 if (tcplen > pcb->rcv_wnd) {
1144 LWIP_DEBUGF(TCP_INPUT_DEBUG,
1145 ("tcp_receive: other end overran receive window"
1146 "seqno %"U32_F" len %"U32_F" right edge %"U32_F"\n",
1147 seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd));
1148 if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
1149 /* Must remove the FIN from the header as we're trimming
1150 * that byte of sequence-space from the packet */
1151 TCPH_FLAGS_SET(inseg.tcphdr, TCPH_FLAGS(inseg.tcphdr) &~ TCP_FIN);
1153 /* Adjust length of segment to fit in the window. */
1154 inseg.len = pcb->rcv_wnd;
1155 if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) {
1158 pbuf_realloc(inseg.p, inseg.len);
1159 tcplen = TCP_TCPLEN(&inseg);
1160 LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n",
1161 (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd));
1164 if (pcb->ooseq != NULL) {
1165 if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
1166 LWIP_DEBUGF(TCP_INPUT_DEBUG,
1167 ("tcp_receive: received in-order FIN, binning ooseq queue\n"));
1168 /* Received in-order FIN means anything that was received
1169 * out of order must now have been received in-order, so
1170 * bin the ooseq queue
1173 * .==seg============|FIN
1175 while (pcb->ooseq != NULL) {
1176 struct tcp_seg *old_ooseq = pcb->ooseq;
1177 pcb->ooseq = pcb->ooseq->next;
1178 tcp_seg_free(old_ooseq);
1182 struct tcp_seg* next = pcb->ooseq;
1183 struct tcp_seg *old_seg;
1186 * .==seg============|
1189 TCP_SEQ_GEQ(seqno + tcplen,
1190 next->tcphdr->seqno + next->len)) {
1191 /* inseg doesn't have FIN (already processed) */
1192 if (TCPH_FLAGS(next->tcphdr) & TCP_FIN &&
1193 (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) == 0) {
1194 TCPH_FLAGS_SET(inseg.tcphdr,
1195 TCPH_FLAGS(inseg.tcphdr) | TCP_FIN);
1196 tcplen = TCP_TCPLEN(&inseg);
1200 tcp_seg_free(old_seg);
1204 * .==seg============|
1207 TCP_SEQ_GT(seqno + tcplen,
1208 next->tcphdr->seqno)) {
1209 /* FIN in inseg already handled by dropping whole ooseq queue */
1210 inseg.len = (u16_t)(pcb->ooseq->tcphdr->seqno - seqno);
1211 if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) {
1214 pbuf_realloc(inseg.p, inseg.len);
1215 tcplen = TCP_TCPLEN(&inseg);
1216 LWIP_ASSERT("tcp_receive: segment not trimmed correctly to ooseq queue\n",
1217 (seqno + tcplen) == pcb->ooseq->tcphdr->seqno);
1222 #endif /* TCP_QUEUE_OOSEQ */
1224 pcb->rcv_nxt = seqno + tcplen;
1226 /* Update the receiver's (our) window. */
1227 LWIP_ASSERT("tcp_receive: tcplen > rcv_wnd\n", pcb->rcv_wnd >= tcplen);
1228 pcb->rcv_wnd -= tcplen;
1230 tcp_update_rcv_ann_wnd(pcb);
1232 /* If there is data in the segment, we make preparations to
1233 pass this up to the application. The ->recv_data variable
1234 is used for holding the pbuf that goes to the
1235 application. The code for reassembling out-of-sequence data
1236 chains its data on this pbuf as well.
1238 If the segment was a FIN, we set the TF_GOT_FIN flag that will
1239 be used to indicate to the application that the remote side has
1240 closed its end of the connection. */
1241 if (inseg.p->tot_len > 0) {
1242 recv_data = inseg.p;
1243 /* Since this pbuf now is the responsibility of the
1244 application, we delete our reference to it so that we won't
1245 (mistakingly) deallocate it. */
1248 if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
1249 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN.\n"));
1250 recv_flags |= TF_GOT_FIN;
1254 /* We now check if we have segments on the ->ooseq queue that
1255 is now in sequence. */
1256 while (pcb->ooseq != NULL &&
1257 pcb->ooseq->tcphdr->seqno == pcb->rcv_nxt) {
1260 seqno = pcb->ooseq->tcphdr->seqno;
1262 pcb->rcv_nxt += TCP_TCPLEN(cseg);
1263 LWIP_ASSERT("tcp_receive: ooseq tcplen > rcv_wnd\n",
1264 pcb->rcv_wnd >= TCP_TCPLEN(cseg));
1265 pcb->rcv_wnd -= TCP_TCPLEN(cseg);
1267 tcp_update_rcv_ann_wnd(pcb);
1269 if (cseg->p->tot_len > 0) {
1270 /* Chain this pbuf onto the pbuf that we will pass to
1273 pbuf_cat(recv_data, cseg->p);
1275 recv_data = cseg->p;
1279 if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) {
1280 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN.\n"));
1281 recv_flags |= TF_GOT_FIN;
1282 if (pcb->state == ESTABLISHED) { /* force passive close or we can move to active close */
1283 pcb->state = CLOSE_WAIT;
1287 pcb->ooseq = cseg->next;
1290 #endif /* TCP_QUEUE_OOSEQ */
1293 /* Acknowledge the segment(s). */
1297 /* We get here if the incoming segment is out-of-sequence. */
1298 tcp_send_empty_ack(pcb);
1300 /* We queue the segment on the ->ooseq queue. */
1301 if (pcb->ooseq == NULL) {
1302 pcb->ooseq = tcp_seg_copy(&inseg);
1304 /* If the queue is not empty, we walk through the queue and
1305 try to find a place where the sequence number of the
1306 incoming segment is between the sequence numbers of the
1307 previous and the next segment on the ->ooseq queue. That is
1308 the place where we put the incoming segment. If needed, we
1309 trim the second edges of the previous and the incoming
1310 segment so that it will fit into the sequence.
1312 If the incoming segment has the same sequence number as a
1313 segment on the ->ooseq queue, we discard the segment that
1314 contains less data. */
1317 for(next = pcb->ooseq; next != NULL; next = next->next) {
1318 if (seqno == next->tcphdr->seqno) {
1319 /* The sequence number of the incoming segment is the
1320 same as the sequence number of the segment on
1321 ->ooseq. We check the lengths to see which one to
1323 if (inseg.len > next->len) {
1324 /* The incoming segment is larger than the old
1325 segment. We replace some segments with the new
1327 cseg = tcp_seg_copy(&inseg);
1334 tcp_oos_insert_segment(cseg, next);
1338 /* Either the lenghts are the same or the incoming
1339 segment was smaller than the old one; in either
1340 case, we ditch the incoming segment. */
1345 if (TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {
1346 /* The sequence number of the incoming segment is lower
1347 than the sequence number of the first segment on the
1348 queue. We put the incoming segment first on the
1350 cseg = tcp_seg_copy(&inseg);
1353 tcp_oos_insert_segment(cseg, next);
1358 /*if (TCP_SEQ_LT(prev->tcphdr->seqno, seqno) &&
1359 TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {*/
1360 if (TCP_SEQ_BETWEEN(seqno, prev->tcphdr->seqno+1, next->tcphdr->seqno-1)) {
1361 /* The sequence number of the incoming segment is in
1362 between the sequence numbers of the previous and
1363 the next segment on ->ooseq. We trim trim the previous
1364 segment, delete next segments that included in received segment
1365 and trim received, if needed. */
1366 cseg = tcp_seg_copy(&inseg);
1368 if (TCP_SEQ_GT(prev->tcphdr->seqno + prev->len, seqno)) {
1369 /* We need to trim the prev segment. */
1370 prev->len = (u16_t)(seqno - prev->tcphdr->seqno);
1371 pbuf_realloc(prev->p, prev->len);
1374 tcp_oos_insert_segment(cseg, next);
1379 /* If the "next" segment is the last segment on the
1380 ooseq queue, we add the incoming segment to the end
1382 if (next->next == NULL &&
1383 TCP_SEQ_GT(seqno, next->tcphdr->seqno)) {
1384 if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) {
1385 /* segment "next" already contains all data */
1388 next->next = tcp_seg_copy(&inseg);
1389 if (next->next != NULL) {
1390 if (TCP_SEQ_GT(next->tcphdr->seqno + next->len, seqno)) {
1391 /* We need to trim the last segment. */
1392 next->len = (u16_t)(seqno - next->tcphdr->seqno);
1393 pbuf_realloc(next->p, next->len);
1402 #endif /* TCP_QUEUE_OOSEQ */
1406 /* The incoming segment is not withing the window. */
1407 tcp_send_empty_ack(pcb);
1410 /* Segments with length 0 is taken care of here. Segments that
1411 fall out of the window are ACKed. */
1412 /*if (TCP_SEQ_GT(pcb->rcv_nxt, seqno) ||
1413 TCP_SEQ_GEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {*/
1414 if(!TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd-1)){
1421 * Parses the options contained in the incoming segment.
1423 * Called from tcp_listen_input() and tcp_process().
1424 * Currently, only the MSS option is supported!
1426 * @param pcb the tcp_pcb for which a segment arrived
1429 tcp_parseopt(struct tcp_pcb *pcb)
1434 #if LWIP_TCP_TIMESTAMPS
1438 opts = (u8_t *)tcphdr + TCP_HLEN;
1440 /* Parse the TCP MSS option, if present. */
1441 if(TCPH_HDRLEN(tcphdr) > 0x5) {
1442 max_c = (TCPH_HDRLEN(tcphdr) - 5) << 2;
1443 for (c = 0; c < max_c; ) {
1447 /* End of options. */
1448 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: EOL\n"));
1453 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: NOP\n"));
1456 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: MSS\n"));
1457 if (opts[c + 1] != 0x04 || c + 0x04 > max_c) {
1459 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
1462 /* An MSS option with the right option length. */
1463 mss = (opts[c + 2] << 8) | opts[c + 3];
1464 /* Limit the mss to the configured TCP_MSS and prevent division by zero */
1465 pcb->mss = ((mss > TCP_MSS) || (mss == 0)) ? TCP_MSS : mss;
1466 /* Advance to next option */
1469 #if LWIP_TCP_TIMESTAMPS
1471 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: TS\n"));
1472 if (opts[c + 1] != 0x0A || c + 0x0A > max_c) {
1474 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
1477 /* TCP timestamp option with valid length */
1478 tsval = (opts[c+2]) | (opts[c+3] << 8) |
1479 (opts[c+4] << 16) | (opts[c+5] << 24);
1480 if (flags & TCP_SYN) {
1481 pcb->ts_recent = ntohl(tsval);
1482 pcb->flags |= TF_TIMESTAMP;
1483 } else if (TCP_SEQ_BETWEEN(pcb->ts_lastacksent, seqno, seqno+tcplen)) {
1484 pcb->ts_recent = ntohl(tsval);
1486 /* Advance to next option */
1491 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: other\n"));
1492 if (opts[c + 1] == 0) {
1493 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
1494 /* If the length field is zero, the options are malformed
1495 and we don't process them further. */
1498 /* All other options have a length field, so that we easily
1499 can skip past them. */
1506 #endif /* LWIP_TCP */