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();
105 iphdr = (struct ip_hdr *)p->payload;
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 /* if err == ERR_ABRT, 'pcb' is already deallocated */
284 /* drop incoming packets, because pcb is "full" */
285 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: drop incoming packets, because pcb is \"full\"\n"));
286 TCP_STATS_INC(tcp.drop);
287 snmp_inc_tcpinerrs();
293 err = tcp_process(pcb);
294 /* A return value of ERR_ABRT means that tcp_abort() was called
295 and that the pcb has been freed. If so, we don't do anything. */
296 if (err != ERR_ABRT) {
297 if (recv_flags & TF_RESET) {
298 /* TF_RESET means that the connection was reset by the other
299 end. We then call the error callback to inform the
300 application that the connection is dead before we
301 deallocate the PCB. */
302 TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_RST);
303 tcp_pcb_remove(&tcp_active_pcbs, pcb);
304 memp_free(MEMP_TCP_PCB, pcb);
305 } else if (recv_flags & TF_CLOSED) {
306 /* The connection has been closed and we will deallocate the
308 tcp_pcb_remove(&tcp_active_pcbs, pcb);
309 memp_free(MEMP_TCP_PCB, pcb);
312 /* If the application has registered a "sent" function to be
313 called when new send buffer space is available, we call it
315 if (pcb->acked > 0) {
316 TCP_EVENT_SENT(pcb, pcb->acked, err);
317 if (err == ERR_ABRT) {
322 if (recv_data != NULL) {
323 if(flags & TCP_PSH) {
324 recv_data->flags |= PBUF_FLAG_PUSH;
327 /* Notify application that data has been received. */
328 TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err);
329 if (err == ERR_ABRT) {
333 /* If the upper layer can't receive this data, store it */
335 pcb->refused_data = recv_data;
336 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: keep incoming packet, because pcb is \"full\"\n"));
340 /* If a FIN segment was received, we call the callback
341 function with a NULL buffer to indicate EOF. */
342 if (recv_flags & TF_GOT_FIN) {
343 TCP_EVENT_RECV(pcb, NULL, ERR_OK, err);
344 if (err == ERR_ABRT) {
349 tcp_input_pcb = NULL;
350 /* Try to send something out. */
354 tcp_debug_print_state(pcb->state);
355 #endif /* TCP_DEBUG */
356 #endif /* TCP_INPUT_DEBUG */
359 /* Jump target if pcb has been aborted in a callback (by calling tcp_abort()).
360 Below this line, 'pcb' may not be dereferenced! */
362 tcp_input_pcb = NULL;
365 /* give up our reference to inseg.p */
373 /* If no matching PCB was found, send a TCP RST (reset) to the
375 LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_input: no PCB match found, resetting.\n"));
376 if (!(TCPH_FLAGS(tcphdr) & TCP_RST)) {
377 TCP_STATS_INC(tcp.proterr);
378 TCP_STATS_INC(tcp.drop);
379 tcp_rst(ackno, seqno + tcplen,
380 &(iphdr->dest), &(iphdr->src),
381 tcphdr->dest, tcphdr->src);
386 LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane());
387 PERF_STOP("tcp_input");
391 * Called by tcp_input() when a segment arrives for a listening
392 * connection (from tcp_input()).
394 * @param pcb the tcp_pcb_listen for which a segment arrived
395 * @return ERR_OK if the segment was processed
396 * another err_t on error
398 * @note the return value is not (yet?) used in tcp_input()
399 * @note the segment which arrived is saved in global variables, therefore only the pcb
400 * involved is passed as a parameter to this function
403 tcp_listen_input(struct tcp_pcb_listen *pcb)
405 struct tcp_pcb *npcb;
408 /* In the LISTEN state, we check for incoming SYN segments,
409 creates a new PCB, and responds with a SYN|ACK. */
410 if (flags & TCP_ACK) {
411 /* For incoming segments with the ACK flag set, respond with a
413 LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_listen_input: ACK in LISTEN, sending reset\n"));
414 tcp_rst(ackno + 1, seqno + tcplen,
415 &(iphdr->dest), &(iphdr->src),
416 tcphdr->dest, tcphdr->src);
417 } else if (flags & TCP_SYN) {
418 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection request %"U16_F" -> %"U16_F".\n", tcphdr->src, tcphdr->dest));
419 #if TCP_LISTEN_BACKLOG
420 if (pcb->accepts_pending >= pcb->backlog) {
421 LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: listen backlog exceeded for port %"U16_F"\n", tcphdr->dest));
424 #endif /* TCP_LISTEN_BACKLOG */
425 npcb = tcp_alloc(pcb->prio);
426 /* If a new PCB could not be created (probably due to lack of memory),
427 we don't do anything, but rely on the sender will retransmit the
428 SYN at a time when we have more memory available. */
430 LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: could not allocate PCB\n"));
431 TCP_STATS_INC(tcp.memerr);
434 #if TCP_LISTEN_BACKLOG
435 pcb->accepts_pending++;
436 #endif /* TCP_LISTEN_BACKLOG */
437 /* Set up the new PCB. */
438 ip_addr_set(&(npcb->local_ip), &(iphdr->dest));
439 npcb->local_port = pcb->local_port;
440 ip_addr_set(&(npcb->remote_ip), &(iphdr->src));
441 npcb->remote_port = tcphdr->src;
442 npcb->state = SYN_RCVD;
443 npcb->rcv_nxt = seqno + 1;
444 npcb->rcv_ann_right_edge = npcb->rcv_nxt;
445 npcb->snd_wnd = tcphdr->wnd;
446 npcb->ssthresh = npcb->snd_wnd;
447 npcb->snd_wl1 = seqno - 1;/* initialise to seqno-1 to force window update */
448 npcb->callback_arg = pcb->callback_arg;
449 #if LWIP_CALLBACK_API
450 npcb->accept = pcb->accept;
451 #endif /* LWIP_CALLBACK_API */
452 /* inherit socket options */
453 npcb->so_options = pcb->so_options & (SOF_DEBUG|SOF_DONTROUTE|SOF_KEEPALIVE|SOF_OOBINLINE|SOF_LINGER);
454 /* Register the new PCB so that we can begin receiving segments
456 TCP_REG(&tcp_active_pcbs, npcb);
458 /* Parse any options in the SYN. */
460 #if TCP_CALCULATE_EFF_SEND_MSS
461 npcb->mss = tcp_eff_send_mss(npcb->mss, &(npcb->remote_ip));
462 #endif /* TCP_CALCULATE_EFF_SEND_MSS */
464 snmp_inc_tcppassiveopens();
466 /* Send a SYN|ACK together with the MSS option. */
467 rc = tcp_enqueue(npcb, NULL, 0, TCP_SYN | TCP_ACK, 0, TF_SEG_OPTS_MSS
468 #if LWIP_TCP_TIMESTAMPS
469 /* and maybe include the TIMESTAMP option */
470 | (npcb->flags & TF_TIMESTAMP ? TF_SEG_OPTS_TS : 0)
474 tcp_abandon(npcb, 0);
477 return tcp_output(npcb);
483 * Called by tcp_input() when a segment arrives for a connection in
486 * @param pcb the tcp_pcb for which a segment arrived
488 * @note the segment which arrived is saved in global variables, therefore only the pcb
489 * involved is passed as a parameter to this function
492 tcp_timewait_input(struct tcp_pcb *pcb)
494 /* RFC 1337: in TIME_WAIT, ignore RST and ACK FINs + any 'acceptable' segments */
495 /* RFC 793 3.9 Event Processing - Segment Arrives:
496 * - first check sequence number - we skip that one in TIME_WAIT (always
497 * acceptable since we only send ACKs)
498 * - second check the RST bit (... return) */
499 if (flags & TCP_RST) {
502 /* - fourth, check the SYN bit, */
503 if (flags & TCP_SYN) {
504 /* If an incoming segment is not acceptable, an acknowledgment
505 should be sent in reply */
506 if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt+pcb->rcv_wnd)) {
507 /* If the SYN is in the window it is an error, send a reset */
508 tcp_rst(ackno, seqno + tcplen, &(iphdr->dest), &(iphdr->src),
509 tcphdr->dest, tcphdr->src);
512 } else if (flags & TCP_FIN) {
513 /* - eighth, check the FIN bit: Remain in the TIME-WAIT state.
514 Restart the 2 MSL time-wait timeout.*/
515 pcb->tmr = tcp_ticks;
519 /* Acknowledge data, FIN or out-of-window SYN */
520 pcb->flags |= TF_ACK_NOW;
521 return tcp_output(pcb);
527 * Implements the TCP state machine. Called by tcp_input. In some
528 * states tcp_receive() is called to receive data. The tcp_seg
529 * argument will be freed by the caller (tcp_input()) unless the
530 * recv_data pointer in the pcb is set.
532 * @param pcb the tcp_pcb for which a segment arrived
534 * @note the segment which arrived is saved in global variables, therefore only the pcb
535 * involved is passed as a parameter to this function
538 tcp_process(struct tcp_pcb *pcb)
540 struct tcp_seg *rseg;
546 /* Process incoming RST segments. */
547 if (flags & TCP_RST) {
548 /* First, determine if the reset is acceptable. */
549 if (pcb->state == SYN_SENT) {
550 if (ackno == pcb->snd_nxt) {
554 if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt,
555 pcb->rcv_nxt+pcb->rcv_wnd)) {
561 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: Connection RESET\n"));
562 LWIP_ASSERT("tcp_input: pcb->state != CLOSED", pcb->state != CLOSED);
563 recv_flags |= TF_RESET;
564 pcb->flags &= ~TF_ACK_DELAY;
567 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n",
568 seqno, pcb->rcv_nxt));
569 LWIP_DEBUGF(TCP_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n",
570 seqno, pcb->rcv_nxt));
575 if ((flags & TCP_SYN) && (pcb->state != SYN_SENT && pcb->state != SYN_RCVD)) {
576 /* Cope with new connection attempt after remote end crashed */
581 /* Update the PCB (in)activity timer. */
582 pcb->tmr = tcp_ticks;
583 pcb->keep_cnt_sent = 0;
587 /* Do different things depending on the TCP state. */
588 switch (pcb->state) {
590 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %"U32_F" pcb->snd_nxt %"U32_F" unacked %"U32_F"\n", ackno,
591 pcb->snd_nxt, ntohl(pcb->unacked->tcphdr->seqno)));
592 /* received SYN ACK with expected sequence number? */
593 if ((flags & TCP_ACK) && (flags & TCP_SYN)
594 && ackno == ntohl(pcb->unacked->tcphdr->seqno) + 1) {
596 pcb->rcv_nxt = seqno + 1;
597 pcb->rcv_ann_right_edge = pcb->rcv_nxt;
598 pcb->lastack = ackno;
599 pcb->snd_wnd = tcphdr->wnd;
600 pcb->snd_wl1 = seqno - 1; /* initialise to seqno - 1 to force window update */
601 pcb->state = ESTABLISHED;
603 #if TCP_CALCULATE_EFF_SEND_MSS
604 pcb->mss = tcp_eff_send_mss(pcb->mss, &(pcb->remote_ip));
605 #endif /* TCP_CALCULATE_EFF_SEND_MSS */
607 /* Set ssthresh again after changing pcb->mss (already set in tcp_connect
608 * but for the default value of pcb->mss) */
609 pcb->ssthresh = pcb->mss * 10;
611 pcb->cwnd = ((pcb->cwnd == 1) ? (pcb->mss * 2) : pcb->mss);
612 LWIP_ASSERT("pcb->snd_queuelen > 0", (pcb->snd_queuelen > 0));
614 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_process: SYN-SENT --queuelen %"U16_F"\n", (u16_t)pcb->snd_queuelen));
616 pcb->unacked = rseg->next;
618 /* If there's nothing left to acknowledge, stop the retransmit
619 timer, otherwise reset it to start again */
620 if(pcb->unacked == NULL)
629 /* Call the user specified function to call when sucessfully
631 TCP_EVENT_CONNECTED(pcb, ERR_OK, err);
632 if (err == ERR_ABRT) {
637 /* received ACK? possibly a half-open connection */
638 else if (flags & TCP_ACK) {
639 /* send a RST to bring the other side in a non-synchronized state. */
640 tcp_rst(ackno, seqno + tcplen, &(iphdr->dest), &(iphdr->src),
641 tcphdr->dest, tcphdr->src);
645 if (flags & TCP_ACK) {
646 /* expected ACK number? */
647 if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)) {
649 pcb->state = ESTABLISHED;
650 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection established %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
651 #if LWIP_CALLBACK_API
652 LWIP_ASSERT("pcb->accept != NULL", pcb->accept != NULL);
654 /* Call the accept function. */
655 TCP_EVENT_ACCEPT(pcb, ERR_OK, err);
657 /* If the accept function returns with an error, we abort
659 /* Already aborted? */
660 if (err != ERR_ABRT) {
665 old_cwnd = pcb->cwnd;
666 /* If there was any data contained within this ACK,
667 * we'd better pass it on to the application as well. */
670 /* Prevent ACK for SYN to generate a sent event */
671 if (pcb->acked != 0) {
675 pcb->cwnd = ((old_cwnd == 1) ? (pcb->mss * 2) : pcb->mss);
677 if (recv_flags & TF_GOT_FIN) {
679 pcb->state = CLOSE_WAIT;
682 /* incorrect ACK number */
685 tcp_rst(ackno, seqno + tcplen, &(iphdr->dest), &(iphdr->src),
686 tcphdr->dest, tcphdr->src);
688 } else if ((flags & TCP_SYN) && (seqno == pcb->rcv_nxt - 1)) {
689 /* Looks like another copy of the SYN - retransmit our SYN-ACK */
697 if (recv_flags & TF_GOT_FIN) { /* passive close */
699 pcb->state = CLOSE_WAIT;
704 if (recv_flags & TF_GOT_FIN) {
705 if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) {
706 LWIP_DEBUGF(TCP_DEBUG,
707 ("TCP connection closed: FIN_WAIT_1 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
710 TCP_RMV(&tcp_active_pcbs, pcb);
711 pcb->state = TIME_WAIT;
712 TCP_REG(&tcp_tw_pcbs, pcb);
715 pcb->state = CLOSING;
717 } else if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) {
718 pcb->state = FIN_WAIT_2;
723 if (recv_flags & TF_GOT_FIN) {
724 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: FIN_WAIT_2 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
727 TCP_RMV(&tcp_active_pcbs, pcb);
728 pcb->state = TIME_WAIT;
729 TCP_REG(&tcp_tw_pcbs, pcb);
734 if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
735 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: CLOSING %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
737 TCP_RMV(&tcp_active_pcbs, pcb);
738 pcb->state = TIME_WAIT;
739 TCP_REG(&tcp_tw_pcbs, pcb);
744 if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
745 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: LAST_ACK %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
746 /* bugfix #21699: don't set pcb->state to CLOSED here or we risk leaking segments */
747 recv_flags |= TF_CLOSED;
758 * Insert segment into the list (segments covered with new one will be deleted)
760 * Called from tcp_receive()
763 tcp_oos_insert_segment(struct tcp_seg *cseg, struct tcp_seg *next)
765 struct tcp_seg *old_seg;
767 if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) {
768 /* received segment overlaps all following segments */
773 /* delete some following segments
774 oos queue may have segments with FIN flag */
776 TCP_SEQ_GEQ((seqno + cseg->len),
777 (next->tcphdr->seqno + next->len))) {
778 /* cseg with FIN already processed */
779 if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) {
780 TCPH_FLAGS_SET(cseg->tcphdr, TCPH_FLAGS(cseg->tcphdr) | TCP_FIN);
784 tcp_seg_free(old_seg);
787 TCP_SEQ_GT(seqno + cseg->len, next->tcphdr->seqno)) {
788 /* We need to trim the incoming segment. */
789 cseg->len = (u16_t)(next->tcphdr->seqno - seqno);
790 pbuf_realloc(cseg->p, cseg->len);
795 #endif /* TCP_QUEUE_OOSEQ */
798 * Called by tcp_process. Checks if the given segment is an ACK for outstanding
799 * data, and if so frees the memory of the buffered data. Next, is places the
800 * segment on any of the receive queues (pcb->recved or pcb->ooseq). If the segment
801 * is buffered, the pbuf is referenced by pbuf_ref so that it will not be freed until
802 * i it has been removed from the buffer.
804 * If the incoming segment constitutes an ACK for a segment that was used for RTT
805 * estimation, the RTT is estimated here as well.
807 * Called from tcp_process().
810 tcp_receive(struct tcp_pcb *pcb)
812 struct tcp_seg *next;
814 struct tcp_seg *prev, *cseg;
815 #endif /* TCP_QUEUE_OOSEQ */
819 u32_t right_wnd_edge;
821 int found_dupack = 0;
823 if (flags & TCP_ACK) {
824 right_wnd_edge = pcb->snd_wnd + pcb->snd_wl2;
827 if (TCP_SEQ_LT(pcb->snd_wl1, seqno) ||
828 (pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) ||
829 (pcb->snd_wl2 == ackno && tcphdr->wnd > pcb->snd_wnd)) {
830 pcb->snd_wnd = tcphdr->wnd;
831 pcb->snd_wl1 = seqno;
832 pcb->snd_wl2 = ackno;
833 if (pcb->snd_wnd > 0 && pcb->persist_backoff > 0) {
834 pcb->persist_backoff = 0;
836 LWIP_DEBUGF(TCP_WND_DEBUG, ("tcp_receive: window update %"U16_F"\n", pcb->snd_wnd));
839 if (pcb->snd_wnd != tcphdr->wnd) {
840 LWIP_DEBUGF(TCP_WND_DEBUG,
841 ("tcp_receive: no window update lastack %"U32_F" ackno %"
842 U32_F" wl1 %"U32_F" seqno %"U32_F" wl2 %"U32_F"\n",
843 pcb->lastack, ackno, pcb->snd_wl1, seqno, pcb->snd_wl2));
845 #endif /* TCP_WND_DEBUG */
848 /* (From Stevens TCP/IP Illustrated Vol II, p970.) Its only a
850 * 1) It doesn't ACK new data
851 * 2) length of received packet is zero (i.e. no payload)
852 * 3) the advertised window hasn't changed
853 * 4) There is outstanding unacknowledged data (retransmission timer running)
854 * 5) The ACK is == biggest ACK sequence number so far seen (snd_una)
856 * If it passes all five, should process as a dupack:
857 * a) dupacks < 3: do nothing
858 * b) dupacks == 3: fast retransmit
859 * c) dupacks > 3: increase cwnd
861 * If it only passes 1-3, should reset dupack counter (and add to
862 * stats, which we don't do in lwIP)
864 * If it only passes 1, should reset dupack counter
869 if (TCP_SEQ_LEQ(ackno, pcb->lastack)) {
874 if (pcb->snd_wl2 + pcb->snd_wnd == right_wnd_edge){
876 if (pcb->rtime >= 0) {
878 if (pcb->lastack == ackno) {
880 if (pcb->dupacks + 1 > pcb->dupacks)
882 if (pcb->dupacks > 3) {
883 /* Inflate the congestion window, but not if it means that
884 the value overflows. */
885 if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {
886 pcb->cwnd += pcb->mss;
888 } else if (pcb->dupacks == 3) {
889 /* Do fast retransmit */
890 tcp_rexmit_fast(pcb);
896 /* If Clause (1) or more is true, but not a duplicate ack, reset
897 * count of consecutive duplicate acks */
901 } else if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)){
902 /* We come here when the ACK acknowledges new data. */
904 /* Reset the "IN Fast Retransmit" flag, since we are no longer
905 in fast retransmit. Also reset the congestion window to the
906 slow start threshold. */
907 if (pcb->flags & TF_INFR) {
908 pcb->flags &= ~TF_INFR;
909 pcb->cwnd = pcb->ssthresh;
912 /* Reset the number of retransmissions. */
915 /* Reset the retransmission time-out. */
916 pcb->rto = (pcb->sa >> 3) + pcb->sv;
918 /* Update the send buffer space. Diff between the two can never exceed 64K? */
919 pcb->acked = (u16_t)(ackno - pcb->lastack);
921 pcb->snd_buf += pcb->acked;
923 /* Reset the fast retransmit variables. */
925 pcb->lastack = ackno;
927 /* Update the congestion control variables (cwnd and
929 if (pcb->state >= ESTABLISHED) {
930 if (pcb->cwnd < pcb->ssthresh) {
931 if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {
932 pcb->cwnd += pcb->mss;
934 LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: slow start cwnd %"U16_F"\n", pcb->cwnd));
936 u16_t new_cwnd = (pcb->cwnd + pcb->mss * pcb->mss / pcb->cwnd);
937 if (new_cwnd > pcb->cwnd) {
938 pcb->cwnd = new_cwnd;
940 LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: congestion avoidance cwnd %"U16_F"\n", pcb->cwnd));
943 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: ACK for %"U32_F", unacked->seqno %"U32_F":%"U32_F"\n",
945 pcb->unacked != NULL?
946 ntohl(pcb->unacked->tcphdr->seqno): 0,
947 pcb->unacked != NULL?
948 ntohl(pcb->unacked->tcphdr->seqno) + TCP_TCPLEN(pcb->unacked): 0));
950 /* Remove segment from the unacknowledged list if the incoming
951 ACK acknowlegdes them. */
952 while (pcb->unacked != NULL &&
953 TCP_SEQ_LEQ(ntohl(pcb->unacked->tcphdr->seqno) +
954 TCP_TCPLEN(pcb->unacked), ackno)) {
955 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unacked\n",
956 ntohl(pcb->unacked->tcphdr->seqno),
957 ntohl(pcb->unacked->tcphdr->seqno) +
958 TCP_TCPLEN(pcb->unacked)));
961 pcb->unacked = pcb->unacked->next;
963 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen));
964 LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p)));
965 /* Prevent ACK for FIN to generate a sent event */
966 if ((pcb->acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) {
970 pcb->snd_queuelen -= pbuf_clen(next->p);
973 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U16_F" (after freeing unacked)\n", (u16_t)pcb->snd_queuelen));
974 if (pcb->snd_queuelen != 0) {
975 LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL ||
976 pcb->unsent != NULL);
980 /* If there's nothing left to acknowledge, stop the retransmit
981 timer, otherwise reset it to start again */
982 if(pcb->unacked == NULL)
989 /* Fix bug bug #21582: out of sequence ACK, didn't really ack anything */
993 /* We go through the ->unsent list to see if any of the segments
994 on the list are acknowledged by the ACK. This may seem
995 strange since an "unsent" segment shouldn't be acked. The
996 rationale is that lwIP puts all outstanding segments on the
997 ->unsent list after a retransmission, so these segments may
998 in fact have been sent once. */
999 while (pcb->unsent != NULL &&
1000 TCP_SEQ_BETWEEN(ackno, ntohl(pcb->unsent->tcphdr->seqno) +
1001 TCP_TCPLEN(pcb->unsent), pcb->snd_nxt)) {
1002 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unsent\n",
1003 ntohl(pcb->unsent->tcphdr->seqno), ntohl(pcb->unsent->tcphdr->seqno) +
1004 TCP_TCPLEN(pcb->unsent)));
1007 pcb->unsent = pcb->unsent->next;
1008 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen));
1009 LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p)));
1010 /* Prevent ACK for FIN to generate a sent event */
1011 if ((pcb->acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) {
1014 pcb->snd_queuelen -= pbuf_clen(next->p);
1016 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U16_F" (after freeing unsent)\n", (u16_t)pcb->snd_queuelen));
1017 if (pcb->snd_queuelen != 0) {
1018 LWIP_ASSERT("tcp_receive: valid queue length",
1019 pcb->unacked != NULL || pcb->unsent != NULL);
1022 /* End of ACK for new data processing. */
1024 LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: pcb->rttest %"U32_F" rtseq %"U32_F" ackno %"U32_F"\n",
1025 pcb->rttest, pcb->rtseq, ackno));
1027 /* RTT estimation calculations. This is done by checking if the
1028 incoming segment acknowledges the segment we use to take a
1029 round-trip time measurement. */
1030 if (pcb->rttest && TCP_SEQ_LT(pcb->rtseq, ackno)) {
1031 /* diff between this shouldn't exceed 32K since this are tcp timer ticks
1032 and a round-trip shouldn't be that long... */
1033 m = (s16_t)(tcp_ticks - pcb->rttest);
1035 LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: experienced rtt %"U16_F" ticks (%"U16_F" msec).\n",
1036 m, m * TCP_SLOW_INTERVAL));
1038 /* This is taken directly from VJs original code in his paper */
1039 m = m - (pcb->sa >> 3);
1044 m = m - (pcb->sv >> 2);
1046 pcb->rto = (pcb->sa >> 3) + pcb->sv;
1048 LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: RTO %"U16_F" (%"U16_F" milliseconds)\n",
1049 pcb->rto, pcb->rto * TCP_SLOW_INTERVAL));
1055 /* If the incoming segment contains data, we must process it
1058 /* This code basically does three things:
1060 +) If the incoming segment contains data that is the next
1061 in-sequence data, this data is passed to the application. This
1062 might involve trimming the first edge of the data. The rcv_nxt
1063 variable and the advertised window are adjusted.
1065 +) If the incoming segment has data that is above the next
1066 sequence number expected (->rcv_nxt), the segment is placed on
1067 the ->ooseq queue. This is done by finding the appropriate
1068 place in the ->ooseq queue (which is ordered by sequence
1069 number) and trim the segment in both ends if needed. An
1070 immediate ACK is sent to indicate that we received an
1071 out-of-sequence segment.
1073 +) Finally, we check if the first segment on the ->ooseq queue
1074 now is in sequence (i.e., if rcv_nxt >= ooseq->seqno). If
1075 rcv_nxt > ooseq->seqno, we must trim the first edge of the
1076 segment on ->ooseq before we adjust rcv_nxt. The data in the
1077 segments that are now on sequence are chained onto the
1078 incoming segment so that we only need to call the application
1082 /* First, we check if we must trim the first edge. We have to do
1083 this if the sequence number of the incoming segment is less
1084 than rcv_nxt, and the sequence number plus the length of the
1085 segment is larger than rcv_nxt. */
1086 /* if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)){
1087 if (TCP_SEQ_LT(pcb->rcv_nxt, seqno + tcplen)) {*/
1088 if (TCP_SEQ_BETWEEN(pcb->rcv_nxt, seqno + 1, seqno + tcplen - 1)){
1089 /* Trimming the first edge is done by pushing the payload
1090 pointer in the pbuf downwards. This is somewhat tricky since
1091 we do not want to discard the full contents of the pbuf up to
1092 the new starting point of the data since we have to keep the
1093 TCP header which is present in the first pbuf in the chain.
1095 What is done is really quite a nasty hack: the first pbuf in
1096 the pbuf chain is pointed to by inseg.p. Since we need to be
1097 able to deallocate the whole pbuf, we cannot change this
1098 inseg.p pointer to point to any of the later pbufs in the
1099 chain. Instead, we point the ->payload pointer in the first
1100 pbuf to data in one of the later pbufs. We also set the
1101 inseg.data pointer to point to the right place. This way, the
1102 ->p pointer will still point to the first pbuf, but the
1103 ->p->payload pointer will point to data in another pbuf.
1105 After we are done with adjusting the pbuf pointers we must
1106 adjust the ->data pointer in the seg and the segment
1109 off = pcb->rcv_nxt - seqno;
1111 LWIP_ASSERT("inseg.p != NULL", inseg.p);
1112 LWIP_ASSERT("insane offset!", (off < 0x7fff));
1113 if (inseg.p->len < off) {
1114 LWIP_ASSERT("pbuf too short!", (((s32_t)inseg.p->tot_len) >= off));
1115 new_tot_len = (u16_t)(inseg.p->tot_len - off);
1116 while (p->len < off) {
1118 /* KJM following line changed (with addition of new_tot_len var)
1120 inseg.p->tot_len -= p->len; */
1121 p->tot_len = new_tot_len;
1125 if(pbuf_header(p, (s16_t)-off)) {
1126 /* Do we need to cope with this failing? Assert for now */
1127 LWIP_ASSERT("pbuf_header failed", 0);
1130 if(pbuf_header(inseg.p, (s16_t)-off)) {
1131 /* Do we need to cope with this failing? Assert for now */
1132 LWIP_ASSERT("pbuf_header failed", 0);
1135 /* KJM following line changed to use p->payload rather than inseg->p->payload
1137 inseg.dataptr = p->payload;
1138 inseg.len -= (u16_t)(pcb->rcv_nxt - seqno);
1139 inseg.tcphdr->seqno = seqno = pcb->rcv_nxt;
1142 if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)){
1143 /* the whole segment is < rcv_nxt */
1144 /* must be a duplicate of a packet that has already been correctly handled */
1146 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: duplicate seqno %"U32_F"\n", seqno));
1151 /* The sequence number must be within the window (above rcv_nxt
1152 and below rcv_nxt + rcv_wnd) in order to be further
1154 if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt,
1155 pcb->rcv_nxt + pcb->rcv_wnd - 1)){
1156 if (pcb->rcv_nxt == seqno) {
1157 /* The incoming segment is the next in sequence. We check if
1158 we have to trim the end of the segment and update rcv_nxt
1159 and pass the data to the application. */
1160 tcplen = TCP_TCPLEN(&inseg);
1162 if (tcplen > pcb->rcv_wnd) {
1163 LWIP_DEBUGF(TCP_INPUT_DEBUG,
1164 ("tcp_receive: other end overran receive window"
1165 "seqno %"U32_F" len %"U32_F" right edge %"U32_F"\n",
1166 seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd));
1167 if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
1168 /* Must remove the FIN from the header as we're trimming
1169 * that byte of sequence-space from the packet */
1170 TCPH_FLAGS_SET(inseg.tcphdr, TCPH_FLAGS(inseg.tcphdr) &~ TCP_FIN);
1172 /* Adjust length of segment to fit in the window. */
1173 inseg.len = pcb->rcv_wnd;
1174 if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) {
1177 pbuf_realloc(inseg.p, inseg.len);
1178 tcplen = TCP_TCPLEN(&inseg);
1179 LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n",
1180 (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd));
1183 /* Received in-sequence data, adjust ooseq data if:
1184 - FIN has been received or
1185 - inseq overlaps with ooseq */
1186 if (pcb->ooseq != NULL) {
1187 if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
1188 LWIP_DEBUGF(TCP_INPUT_DEBUG,
1189 ("tcp_receive: received in-order FIN, binning ooseq queue\n"));
1190 /* Received in-order FIN means anything that was received
1191 * out of order must now have been received in-order, so
1192 * bin the ooseq queue */
1193 while (pcb->ooseq != NULL) {
1194 struct tcp_seg *old_ooseq = pcb->ooseq;
1195 pcb->ooseq = pcb->ooseq->next;
1196 tcp_seg_free(old_ooseq);
1201 /* Remove all segments on ooseq that are covered by inseg already.
1202 * FIN is copied from ooseq to inseg if present. */
1204 TCP_SEQ_GEQ(seqno + tcplen,
1205 next->tcphdr->seqno + next->len)) {
1206 /* inseg cannot have FIN here (already processed above) */
1207 if (TCPH_FLAGS(next->tcphdr) & TCP_FIN &&
1208 (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) == 0) {
1209 TCPH_FLAGS_SET(inseg.tcphdr,
1210 TCPH_FLAGS(inseg.tcphdr) | TCP_FIN);
1211 tcplen = TCP_TCPLEN(&inseg);
1217 /* Now trim right side of inseg if it overlaps with the first
1218 * segment on ooseq */
1220 TCP_SEQ_GT(seqno + tcplen,
1221 next->tcphdr->seqno)) {
1222 /* inseg cannot have FIN here (already processed above) */
1223 inseg.len = (u16_t)(next->tcphdr->seqno - seqno);
1224 if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) {
1227 pbuf_realloc(inseg.p, inseg.len);
1228 tcplen = TCP_TCPLEN(&inseg);
1229 LWIP_ASSERT("tcp_receive: segment not trimmed correctly to ooseq queue\n",
1230 (seqno + tcplen) == next->tcphdr->seqno);
1235 #endif /* TCP_QUEUE_OOSEQ */
1237 pcb->rcv_nxt = seqno + tcplen;
1239 /* Update the receiver's (our) window. */
1240 LWIP_ASSERT("tcp_receive: tcplen > rcv_wnd\n", pcb->rcv_wnd >= tcplen);
1241 pcb->rcv_wnd -= tcplen;
1243 tcp_update_rcv_ann_wnd(pcb);
1245 /* If there is data in the segment, we make preparations to
1246 pass this up to the application. The ->recv_data variable
1247 is used for holding the pbuf that goes to the
1248 application. The code for reassembling out-of-sequence data
1249 chains its data on this pbuf as well.
1251 If the segment was a FIN, we set the TF_GOT_FIN flag that will
1252 be used to indicate to the application that the remote side has
1253 closed its end of the connection. */
1254 if (inseg.p->tot_len > 0) {
1255 recv_data = inseg.p;
1256 /* Since this pbuf now is the responsibility of the
1257 application, we delete our reference to it so that we won't
1258 (mistakingly) deallocate it. */
1261 if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
1262 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN.\n"));
1263 recv_flags |= TF_GOT_FIN;
1267 /* We now check if we have segments on the ->ooseq queue that
1268 are now in sequence. */
1269 while (pcb->ooseq != NULL &&
1270 pcb->ooseq->tcphdr->seqno == pcb->rcv_nxt) {
1273 seqno = pcb->ooseq->tcphdr->seqno;
1275 pcb->rcv_nxt += TCP_TCPLEN(cseg);
1276 LWIP_ASSERT("tcp_receive: ooseq tcplen > rcv_wnd\n",
1277 pcb->rcv_wnd >= TCP_TCPLEN(cseg));
1278 pcb->rcv_wnd -= TCP_TCPLEN(cseg);
1280 tcp_update_rcv_ann_wnd(pcb);
1282 if (cseg->p->tot_len > 0) {
1283 /* Chain this pbuf onto the pbuf that we will pass to
1286 pbuf_cat(recv_data, cseg->p);
1288 recv_data = cseg->p;
1292 if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) {
1293 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN.\n"));
1294 recv_flags |= TF_GOT_FIN;
1295 if (pcb->state == ESTABLISHED) { /* force passive close or we can move to active close */
1296 pcb->state = CLOSE_WAIT;
1300 pcb->ooseq = cseg->next;
1303 #endif /* TCP_QUEUE_OOSEQ */
1306 /* Acknowledge the segment(s). */
1310 /* We get here if the incoming segment is out-of-sequence. */
1311 tcp_send_empty_ack(pcb);
1313 /* We queue the segment on the ->ooseq queue. */
1314 if (pcb->ooseq == NULL) {
1315 pcb->ooseq = tcp_seg_copy(&inseg);
1317 /* If the queue is not empty, we walk through the queue and
1318 try to find a place where the sequence number of the
1319 incoming segment is between the sequence numbers of the
1320 previous and the next segment on the ->ooseq queue. That is
1321 the place where we put the incoming segment. If needed, we
1322 trim the second edges of the previous and the incoming
1323 segment so that it will fit into the sequence.
1325 If the incoming segment has the same sequence number as a
1326 segment on the ->ooseq queue, we discard the segment that
1327 contains less data. */
1330 for(next = pcb->ooseq; next != NULL; next = next->next) {
1331 if (seqno == next->tcphdr->seqno) {
1332 /* The sequence number of the incoming segment is the
1333 same as the sequence number of the segment on
1334 ->ooseq. We check the lengths to see which one to
1336 if (inseg.len > next->len) {
1337 /* The incoming segment is larger than the old
1338 segment. We replace some segments with the new
1340 cseg = tcp_seg_copy(&inseg);
1347 tcp_oos_insert_segment(cseg, next);
1351 /* Either the lenghts are the same or the incoming
1352 segment was smaller than the old one; in either
1353 case, we ditch the incoming segment. */
1358 if (TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {
1359 /* The sequence number of the incoming segment is lower
1360 than the sequence number of the first segment on the
1361 queue. We put the incoming segment first on the
1363 cseg = tcp_seg_copy(&inseg);
1366 tcp_oos_insert_segment(cseg, next);
1371 /*if (TCP_SEQ_LT(prev->tcphdr->seqno, seqno) &&
1372 TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {*/
1373 if (TCP_SEQ_BETWEEN(seqno, prev->tcphdr->seqno+1, next->tcphdr->seqno-1)) {
1374 /* The sequence number of the incoming segment is in
1375 between the sequence numbers of the previous and
1376 the next segment on ->ooseq. We trim trim the previous
1377 segment, delete next segments that included in received segment
1378 and trim received, if needed. */
1379 cseg = tcp_seg_copy(&inseg);
1381 if (TCP_SEQ_GT(prev->tcphdr->seqno + prev->len, seqno)) {
1382 /* We need to trim the prev segment. */
1383 prev->len = (u16_t)(seqno - prev->tcphdr->seqno);
1384 pbuf_realloc(prev->p, prev->len);
1387 tcp_oos_insert_segment(cseg, next);
1392 /* If the "next" segment is the last segment on the
1393 ooseq queue, we add the incoming segment to the end
1395 if (next->next == NULL &&
1396 TCP_SEQ_GT(seqno, next->tcphdr->seqno)) {
1397 if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) {
1398 /* segment "next" already contains all data */
1401 next->next = tcp_seg_copy(&inseg);
1402 if (next->next != NULL) {
1403 if (TCP_SEQ_GT(next->tcphdr->seqno + next->len, seqno)) {
1404 /* We need to trim the last segment. */
1405 next->len = (u16_t)(seqno - next->tcphdr->seqno);
1406 pbuf_realloc(next->p, next->len);
1415 #endif /* TCP_QUEUE_OOSEQ */
1419 /* The incoming segment is not withing the window. */
1420 tcp_send_empty_ack(pcb);
1423 /* Segments with length 0 is taken care of here. Segments that
1424 fall out of the window are ACKed. */
1425 /*if (TCP_SEQ_GT(pcb->rcv_nxt, seqno) ||
1426 TCP_SEQ_GEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {*/
1427 if(!TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd-1)){
1434 * Parses the options contained in the incoming segment.
1436 * Called from tcp_listen_input() and tcp_process().
1437 * Currently, only the MSS option is supported!
1439 * @param pcb the tcp_pcb for which a segment arrived
1442 tcp_parseopt(struct tcp_pcb *pcb)
1447 #if LWIP_TCP_TIMESTAMPS
1451 opts = (u8_t *)tcphdr + TCP_HLEN;
1453 /* Parse the TCP MSS option, if present. */
1454 if(TCPH_HDRLEN(tcphdr) > 0x5) {
1455 max_c = (TCPH_HDRLEN(tcphdr) - 5) << 2;
1456 for (c = 0; c < max_c; ) {
1460 /* End of options. */
1461 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: EOL\n"));
1466 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: NOP\n"));
1469 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: MSS\n"));
1470 if (opts[c + 1] != 0x04 || c + 0x04 > max_c) {
1472 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
1475 /* An MSS option with the right option length. */
1476 mss = (opts[c + 2] << 8) | opts[c + 3];
1477 /* Limit the mss to the configured TCP_MSS and prevent division by zero */
1478 pcb->mss = ((mss > TCP_MSS) || (mss == 0)) ? TCP_MSS : mss;
1479 /* Advance to next option */
1482 #if LWIP_TCP_TIMESTAMPS
1484 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: TS\n"));
1485 if (opts[c + 1] != 0x0A || c + 0x0A > max_c) {
1487 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
1490 /* TCP timestamp option with valid length */
1491 tsval = (opts[c+2]) | (opts[c+3] << 8) |
1492 (opts[c+4] << 16) | (opts[c+5] << 24);
1493 if (flags & TCP_SYN) {
1494 pcb->ts_recent = ntohl(tsval);
1495 pcb->flags |= TF_TIMESTAMP;
1496 } else if (TCP_SEQ_BETWEEN(pcb->ts_lastacksent, seqno, seqno+tcplen)) {
1497 pcb->ts_recent = ntohl(tsval);
1499 /* Advance to next option */
1504 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: other\n"));
1505 if (opts[c + 1] == 0) {
1506 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
1507 /* If the length field is zero, the options are malformed
1508 and we don't process them further. */
1511 /* All other options have a length field, so that we easily
1512 can skip past them. */
1519 #endif /* LWIP_TCP */