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 */
48 #include "lwip/tcp_impl.h"
50 #include "lwip/ip_addr.h"
51 #include "lwip/netif.h"
53 #include "lwip/memp.h"
54 #include "lwip/inet_chksum.h"
55 #include "lwip/stats.h"
56 #include "lwip/snmp.h"
57 #include "arch/perf.h"
59 #include "lwip/ip6_addr.h"
60 #include "lwip/inet_chksum.h"
61 #if LWIP_ND6_TCP_REACHABILITY_HINTS
63 #endif /* LWIP_ND6_TCP_REACHABILITY_HINTS */
65 /* These variables are global to all functions involved in the input
66 processing of TCP segments. They are set by the tcp_input()
68 static struct tcp_seg inseg;
69 static struct tcp_hdr *tcphdr;
70 static u32_t seqno, ackno;
74 static u8_t recv_flags;
75 static struct pbuf *recv_data;
77 struct tcp_pcb *tcp_input_pcb;
79 /* Forward declarations. */
80 static err_t tcp_process(struct tcp_pcb *pcb);
81 static void tcp_receive(struct tcp_pcb *pcb);
82 static void tcp_parseopt(struct tcp_pcb *pcb);
84 static err_t tcp_listen_input(struct tcp_pcb_listen *pcb);
85 static err_t tcp_timewait_input(struct tcp_pcb *pcb);
88 * The initial input processing of TCP. It verifies the TCP header, demultiplexes
89 * the segment between the PCBs and passes it on to tcp_process(), which implements
90 * the TCP finite state machine. This function is called by the IP layer (in
93 * @param p received TCP segment to process (p->payload pointing to the TCP header)
94 * @param inp network interface on which this segment was received
97 tcp_input(struct pbuf *p, struct netif *inp)
99 struct tcp_pcb *pcb, *prev;
100 struct tcp_pcb_listen *lpcb;
102 struct tcp_pcb *lpcb_prev = NULL;
103 struct tcp_pcb_listen *lpcb_any = NULL;
104 #endif /* SO_REUSE */
107 #if CHECKSUM_CHECK_TCP
109 #endif /* CHECKSUM_CHECK_TCP */
113 TCP_STATS_INC(tcp.recv);
114 snmp_inc_tcpinsegs();
116 tcphdr = (struct tcp_hdr *)p->payload;
119 tcp_debug_print(tcphdr);
122 /* Check that TCP header fits in payload */
123 if (p->len < sizeof(struct tcp_hdr)) {
124 /* drop short packets */
125 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet (%"U16_F" bytes) discarded\n", p->tot_len));
126 TCP_STATS_INC(tcp.lenerr);
130 /* Don't even process incoming broadcasts/multicasts. */
131 if ((!ip_current_is_v6() && ip_addr_isbroadcast(ip_current_dest_addr(), inp)) ||
132 ipX_addr_ismulticast(ip_current_is_v6(), ipX_current_dest_addr())) {
133 TCP_STATS_INC(tcp.proterr);
137 #if CHECKSUM_CHECK_TCP
138 /* Verify TCP checksum. */
139 chksum = ipX_chksum_pseudo(ip_current_is_v6(), p, IP_PROTO_TCP, p->tot_len,
140 ipX_current_src_addr(), ipX_current_dest_addr());
142 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packet discarded due to failing checksum 0x%04"X16_F"\n",
144 tcp_debug_print(tcphdr);
145 TCP_STATS_INC(tcp.chkerr);
148 #endif /* CHECKSUM_CHECK_TCP */
150 /* Move the payload pointer in the pbuf so that it points to the
151 TCP data instead of the TCP header. */
152 hdrlen = TCPH_HDRLEN(tcphdr);
153 if(pbuf_header(p, -(hdrlen * 4))){
154 /* drop short packets */
155 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet\n"));
156 TCP_STATS_INC(tcp.lenerr);
160 /* Convert fields in TCP header to host byte order. */
161 tcphdr->src = ntohs(tcphdr->src);
162 tcphdr->dest = ntohs(tcphdr->dest);
163 seqno = tcphdr->seqno = ntohl(tcphdr->seqno);
164 ackno = tcphdr->ackno = ntohl(tcphdr->ackno);
165 tcphdr->wnd = ntohs(tcphdr->wnd);
167 flags = TCPH_FLAGS(tcphdr);
168 tcplen = p->tot_len + ((flags & (TCP_FIN | TCP_SYN)) ? 1 : 0);
170 /* Demultiplex an incoming segment. First, we check if it is destined
171 for an active connection. */
175 for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
176 LWIP_ASSERT("tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED);
177 LWIP_ASSERT("tcp_input: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);
178 LWIP_ASSERT("tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN);
179 if (pcb->remote_port == tcphdr->src &&
180 pcb->local_port == tcphdr->dest &&
181 IP_PCB_IPVER_INPUT_MATCH(pcb) &&
182 ipX_addr_cmp(ip_current_is_v6(), &pcb->remote_ip, ipX_current_src_addr()) &&
183 ipX_addr_cmp(ip_current_is_v6(),&pcb->local_ip, ipX_current_dest_addr())) {
184 /* Move this PCB to the front of the list so that subsequent
185 lookups will be faster (we exploit locality in TCP segment
187 LWIP_ASSERT("tcp_input: pcb->next != pcb (before cache)", pcb->next != pcb);
189 prev->next = pcb->next;
190 pcb->next = tcp_active_pcbs;
191 tcp_active_pcbs = pcb;
193 LWIP_ASSERT("tcp_input: pcb->next != pcb (after cache)", pcb->next != pcb);
200 /* If it did not go to an active connection, we check the connections
201 in the TIME-WAIT state. */
202 for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
203 LWIP_ASSERT("tcp_input: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
204 if (pcb->remote_port == tcphdr->src &&
205 pcb->local_port == tcphdr->dest &&
206 IP_PCB_IPVER_INPUT_MATCH(pcb) &&
207 ipX_addr_cmp(ip_current_is_v6(), &pcb->remote_ip, ipX_current_src_addr()) &&
208 ipX_addr_cmp(ip_current_is_v6(),&pcb->local_ip, ipX_current_dest_addr())) {
209 /* We don't really care enough to move this PCB to the front
210 of the list since we are not very likely to receive that
211 many segments for connections in TIME-WAIT. */
212 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for TIME_WAITing connection.\n"));
213 tcp_timewait_input(pcb);
219 /* Finally, if we still did not get a match, we check all PCBs that
220 are LISTENing for incoming connections. */
222 for(lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
223 if (lpcb->local_port == tcphdr->dest) {
225 if (lpcb->accept_any_ip_version) {
226 /* found an ANY-match */
232 #endif /* SO_REUSE */
234 #endif /* LWIP_IPV6 */
235 if (IP_PCB_IPVER_INPUT_MATCH(lpcb)) {
236 if (ipX_addr_cmp(ip_current_is_v6(), &lpcb->local_ip, ipX_current_dest_addr())) {
237 /* found an exact match */
239 } else if (ipX_addr_isany(ip_current_is_v6(), &lpcb->local_ip)) {
240 /* found an ANY-match */
246 #endif /* SO_REUSE */
250 prev = (struct tcp_pcb *)lpcb;
253 /* first try specific local IP */
255 /* only pass to ANY if no specific local IP has been found */
259 #endif /* SO_REUSE */
261 /* Move this PCB to the front of the list so that subsequent
262 lookups will be faster (we exploit locality in TCP segment
265 ((struct tcp_pcb_listen *)prev)->next = lpcb->next;
266 /* our successor is the remainder of the listening list */
267 lpcb->next = tcp_listen_pcbs.listen_pcbs;
268 /* put this listening pcb at the head of the listening list */
269 tcp_listen_pcbs.listen_pcbs = lpcb;
272 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for LISTENing connection.\n"));
273 tcp_listen_input(lpcb);
280 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("+-+-+-+-+-+-+-+-+-+-+-+-+-+- tcp_input: flags "));
281 tcp_debug_print_flags(TCPH_FLAGS(tcphdr));
282 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n"));
283 #endif /* TCP_INPUT_DEBUG */
287 /* The incoming segment belongs to a connection. */
290 tcp_debug_print_state(pcb->state);
291 #endif /* TCP_DEBUG */
292 #endif /* TCP_INPUT_DEBUG */
294 /* Set up a tcp_seg structure. */
296 inseg.len = p->tot_len;
298 inseg.tcphdr = tcphdr;
303 if (flags & TCP_PSH) {
304 p->flags |= PBUF_FLAG_PUSH;
307 /* If there is data which was previously "refused" by upper layer */
308 if (pcb->refused_data != NULL) {
309 if ((tcp_process_refused_data(pcb) == ERR_ABRT) ||
310 ((pcb->refused_data != NULL) && (tcplen > 0))) {
311 /* pcb has been aborted or refused data is still refused and the new
312 segment contains data */
313 TCP_STATS_INC(tcp.drop);
314 snmp_inc_tcpinerrs();
319 err = tcp_process(pcb);
320 /* A return value of ERR_ABRT means that tcp_abort() was called
321 and that the pcb has been freed. If so, we don't do anything. */
322 if (err != ERR_ABRT) {
323 if (recv_flags & TF_RESET) {
324 /* TF_RESET means that the connection was reset by the other
325 end. We then call the error callback to inform the
326 application that the connection is dead before we
327 deallocate the PCB. */
328 TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_RST);
329 tcp_pcb_remove(&tcp_active_pcbs, pcb);
330 memp_free(MEMP_TCP_PCB, pcb);
331 } else if (recv_flags & TF_CLOSED) {
332 /* The connection has been closed and we will deallocate the
334 if (!(pcb->flags & TF_RXCLOSED)) {
335 /* Connection closed although the application has only shut down the
336 tx side: call the PCB's err callback and indicate the closure to
337 ensure the application doesn't continue using the PCB. */
338 TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_CLSD);
340 tcp_pcb_remove(&tcp_active_pcbs, pcb);
341 memp_free(MEMP_TCP_PCB, pcb);
344 /* If the application has registered a "sent" function to be
345 called when new send buffer space is available, we call it
347 if (pcb->acked > 0) {
348 TCP_EVENT_SENT(pcb, pcb->acked, err);
349 if (err == ERR_ABRT) {
354 if (recv_data != NULL) {
355 LWIP_ASSERT("pcb->refused_data == NULL", pcb->refused_data == NULL);
356 if (pcb->flags & TF_RXCLOSED) {
357 /* received data although already closed -> abort (send RST) to
358 notify the remote host that not all data has been processed */
359 pbuf_free(recv_data);
364 /* Notify application that data has been received. */
365 TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err);
366 if (err == ERR_ABRT) {
370 /* If the upper layer can't receive this data, store it */
372 pcb->refused_data = recv_data;
373 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: keep incoming packet, because pcb is \"full\"\n"));
377 /* If a FIN segment was received, we call the callback
378 function with a NULL buffer to indicate EOF. */
379 if (recv_flags & TF_GOT_FIN) {
380 if (pcb->refused_data != NULL) {
381 /* Delay this if we have refused data. */
382 pcb->refused_data->flags |= PBUF_FLAG_TCP_FIN;
384 /* correct rcv_wnd as the application won't call tcp_recved()
385 for the FIN's seqno */
386 if (pcb->rcv_wnd != TCP_WND) {
389 TCP_EVENT_CLOSED(pcb, err);
390 if (err == ERR_ABRT) {
396 tcp_input_pcb = NULL;
397 /* Try to send something out. */
401 tcp_debug_print_state(pcb->state);
402 #endif /* TCP_DEBUG */
403 #endif /* TCP_INPUT_DEBUG */
406 /* Jump target if pcb has been aborted in a callback (by calling tcp_abort()).
407 Below this line, 'pcb' may not be dereferenced! */
409 tcp_input_pcb = NULL;
412 /* give up our reference to inseg.p */
420 /* If no matching PCB was found, send a TCP RST (reset) to the
422 LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_input: no PCB match found, resetting.\n"));
423 if (!(TCPH_FLAGS(tcphdr) & TCP_RST)) {
424 TCP_STATS_INC(tcp.proterr);
425 TCP_STATS_INC(tcp.drop);
426 tcp_rst(ackno, seqno + tcplen, ipX_current_dest_addr(),
427 ipX_current_src_addr(), tcphdr->dest, tcphdr->src, ip_current_is_v6());
432 LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane());
433 PERF_STOP("tcp_input");
436 TCP_STATS_INC(tcp.drop);
437 snmp_inc_tcpinerrs();
442 * Called by tcp_input() when a segment arrives for a listening
443 * connection (from tcp_input()).
445 * @param pcb the tcp_pcb_listen for which a segment arrived
446 * @return ERR_OK if the segment was processed
447 * another err_t on error
449 * @note the return value is not (yet?) used in tcp_input()
450 * @note the segment which arrived is saved in global variables, therefore only the pcb
451 * involved is passed as a parameter to this function
454 tcp_listen_input(struct tcp_pcb_listen *pcb)
456 struct tcp_pcb *npcb;
459 if (flags & TCP_RST) {
460 /* An incoming RST should be ignored. Return. */
464 /* In the LISTEN state, we check for incoming SYN segments,
465 creates a new PCB, and responds with a SYN|ACK. */
466 if (flags & TCP_ACK) {
467 /* For incoming segments with the ACK flag set, respond with a
469 LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_listen_input: ACK in LISTEN, sending reset\n"));
470 tcp_rst(ackno, seqno + tcplen, ipX_current_dest_addr(),
471 ipX_current_src_addr(), tcphdr->dest, tcphdr->src, ip_current_is_v6());
472 } else if (flags & TCP_SYN) {
473 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection request %"U16_F" -> %"U16_F".\n", tcphdr->src, tcphdr->dest));
474 #if TCP_LISTEN_BACKLOG
475 if (pcb->accepts_pending >= pcb->backlog) {
476 LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: listen backlog exceeded for port %"U16_F"\n", tcphdr->dest));
479 #endif /* TCP_LISTEN_BACKLOG */
480 npcb = tcp_alloc(pcb->prio);
481 /* If a new PCB could not be created (probably due to lack of memory),
482 we don't do anything, but rely on the sender will retransmit the
483 SYN at a time when we have more memory available. */
485 LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: could not allocate PCB\n"));
486 TCP_STATS_INC(tcp.memerr);
489 #if TCP_LISTEN_BACKLOG
490 pcb->accepts_pending++;
491 #endif /* TCP_LISTEN_BACKLOG */
492 /* Set up the new PCB. */
494 PCB_ISIPV6(npcb) = ip_current_is_v6();
495 #endif /* LWIP_IPV6 */
496 ipX_addr_copy(ip_current_is_v6(), npcb->local_ip, *ipX_current_dest_addr());
497 ipX_addr_copy(ip_current_is_v6(), npcb->remote_ip, *ipX_current_src_addr());
498 npcb->local_port = pcb->local_port;
499 npcb->remote_port = tcphdr->src;
500 npcb->state = SYN_RCVD;
501 npcb->rcv_nxt = seqno + 1;
502 npcb->rcv_ann_right_edge = npcb->rcv_nxt;
503 npcb->snd_wnd = tcphdr->wnd;
504 npcb->snd_wnd_max = tcphdr->wnd;
505 npcb->ssthresh = npcb->snd_wnd;
506 npcb->snd_wl1 = seqno - 1;/* initialise to seqno-1 to force window update */
507 npcb->callback_arg = pcb->callback_arg;
508 #if LWIP_CALLBACK_API
509 npcb->accept = pcb->accept;
510 #endif /* LWIP_CALLBACK_API */
511 /* inherit socket options */
512 npcb->so_options = pcb->so_options & SOF_INHERITED;
513 /* Register the new PCB so that we can begin receiving segments
515 TCP_REG_ACTIVE(npcb);
517 /* Parse any options in the SYN. */
519 #if TCP_CALCULATE_EFF_SEND_MSS
520 npcb->mss = tcp_eff_send_mss(npcb->mss, &npcb->local_ip,
521 &npcb->remote_ip, PCB_ISIPV6(npcb));
522 #endif /* TCP_CALCULATE_EFF_SEND_MSS */
524 snmp_inc_tcppassiveopens();
526 /* Send a SYN|ACK together with the MSS option. */
527 rc = tcp_enqueue_flags(npcb, TCP_SYN | TCP_ACK);
529 tcp_abandon(npcb, 0);
532 return tcp_output(npcb);
538 * Called by tcp_input() when a segment arrives for a connection in
541 * @param pcb the tcp_pcb for which a segment arrived
543 * @note the segment which arrived is saved in global variables, therefore only the pcb
544 * involved is passed as a parameter to this function
547 tcp_timewait_input(struct tcp_pcb *pcb)
549 /* RFC 1337: in TIME_WAIT, ignore RST and ACK FINs + any 'acceptable' segments */
550 /* RFC 793 3.9 Event Processing - Segment Arrives:
551 * - first check sequence number - we skip that one in TIME_WAIT (always
552 * acceptable since we only send ACKs)
553 * - second check the RST bit (... return) */
554 if (flags & TCP_RST) {
557 /* - fourth, check the SYN bit, */
558 if (flags & TCP_SYN) {
559 /* If an incoming segment is not acceptable, an acknowledgment
560 should be sent in reply */
561 if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt+pcb->rcv_wnd)) {
562 /* If the SYN is in the window it is an error, send a reset */
563 tcp_rst(ackno, seqno + tcplen, ipX_current_dest_addr(),
564 ipX_current_src_addr(), tcphdr->dest, tcphdr->src, ip_current_is_v6());
567 } else if (flags & TCP_FIN) {
568 /* - eighth, check the FIN bit: Remain in the TIME-WAIT state.
569 Restart the 2 MSL time-wait timeout.*/
570 pcb->tmr = tcp_ticks;
574 /* Acknowledge data, FIN or out-of-window SYN */
575 pcb->flags |= TF_ACK_NOW;
576 return tcp_output(pcb);
582 * Implements the TCP state machine. Called by tcp_input. In some
583 * states tcp_receive() is called to receive data. The tcp_seg
584 * argument will be freed by the caller (tcp_input()) unless the
585 * recv_data pointer in the pcb is set.
587 * @param pcb the tcp_pcb for which a segment arrived
589 * @note the segment which arrived is saved in global variables, therefore only the pcb
590 * involved is passed as a parameter to this function
593 tcp_process(struct tcp_pcb *pcb)
595 struct tcp_seg *rseg;
601 /* Process incoming RST segments. */
602 if (flags & TCP_RST) {
603 /* First, determine if the reset is acceptable. */
604 if (pcb->state == SYN_SENT) {
605 if (ackno == pcb->snd_nxt) {
609 if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt,
610 pcb->rcv_nxt+pcb->rcv_wnd)) {
616 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: Connection RESET\n"));
617 LWIP_ASSERT("tcp_input: pcb->state != CLOSED", pcb->state != CLOSED);
618 recv_flags |= TF_RESET;
619 pcb->flags &= ~TF_ACK_DELAY;
622 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n",
623 seqno, pcb->rcv_nxt));
624 LWIP_DEBUGF(TCP_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n",
625 seqno, pcb->rcv_nxt));
630 if ((flags & TCP_SYN) && (pcb->state != SYN_SENT && pcb->state != SYN_RCVD)) {
631 /* Cope with new connection attempt after remote end crashed */
636 if ((pcb->flags & TF_RXCLOSED) == 0) {
637 /* Update the PCB (in)activity timer unless rx is closed (see tcp_shutdown) */
638 pcb->tmr = tcp_ticks;
640 pcb->keep_cnt_sent = 0;
644 /* Do different things depending on the TCP state. */
645 switch (pcb->state) {
647 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %"U32_F" pcb->snd_nxt %"U32_F" unacked %"U32_F"\n", ackno,
648 pcb->snd_nxt, ntohl(pcb->unacked->tcphdr->seqno)));
649 /* received SYN ACK with expected sequence number? */
650 if ((flags & TCP_ACK) && (flags & TCP_SYN)
651 && ackno == ntohl(pcb->unacked->tcphdr->seqno) + 1) {
653 pcb->rcv_nxt = seqno + 1;
654 pcb->rcv_ann_right_edge = pcb->rcv_nxt;
655 pcb->lastack = ackno;
656 pcb->snd_wnd = tcphdr->wnd;
657 pcb->snd_wnd_max = tcphdr->wnd;
658 pcb->snd_wl1 = seqno - 1; /* initialise to seqno - 1 to force window update */
659 pcb->state = ESTABLISHED;
661 #if TCP_CALCULATE_EFF_SEND_MSS
662 pcb->mss = tcp_eff_send_mss(pcb->mss, &pcb->local_ip, &pcb->remote_ip,
664 #endif /* TCP_CALCULATE_EFF_SEND_MSS */
666 /* Set ssthresh again after changing pcb->mss (already set in tcp_connect
667 * but for the default value of pcb->mss) */
668 pcb->ssthresh = pcb->mss * 10;
670 pcb->cwnd = ((pcb->cwnd == 1) ? (pcb->mss * 2) : pcb->mss);
671 LWIP_ASSERT("pcb->snd_queuelen > 0", (pcb->snd_queuelen > 0));
673 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_process: SYN-SENT --queuelen %"U16_F"\n", (u16_t)pcb->snd_queuelen));
675 pcb->unacked = rseg->next;
678 /* If there's nothing left to acknowledge, stop the retransmit
679 timer, otherwise reset it to start again */
680 if(pcb->unacked == NULL)
687 /* Call the user specified function to call when sucessfully
689 TCP_EVENT_CONNECTED(pcb, ERR_OK, err);
690 if (err == ERR_ABRT) {
695 /* received ACK? possibly a half-open connection */
696 else if (flags & TCP_ACK) {
697 /* send a RST to bring the other side in a non-synchronized state. */
698 tcp_rst(ackno, seqno + tcplen, ipX_current_dest_addr(),
699 ipX_current_src_addr(), tcphdr->dest, tcphdr->src, ip_current_is_v6());
703 if (flags & TCP_ACK) {
704 /* expected ACK number? */
705 if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)) {
707 pcb->state = ESTABLISHED;
708 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection established %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
709 #if LWIP_CALLBACK_API
710 LWIP_ASSERT("pcb->accept != NULL", pcb->accept != NULL);
712 /* Call the accept function. */
713 TCP_EVENT_ACCEPT(pcb, ERR_OK, err);
715 /* If the accept function returns with an error, we abort
717 /* Already aborted? */
718 if (err != ERR_ABRT) {
723 old_cwnd = pcb->cwnd;
724 /* If there was any data contained within this ACK,
725 * we'd better pass it on to the application as well. */
728 /* Prevent ACK for SYN to generate a sent event */
729 if (pcb->acked != 0) {
733 pcb->cwnd = ((old_cwnd == 1) ? (pcb->mss * 2) : pcb->mss);
735 if (recv_flags & TF_GOT_FIN) {
737 pcb->state = CLOSE_WAIT;
740 /* incorrect ACK number, send RST */
741 tcp_rst(ackno, seqno + tcplen, ipX_current_dest_addr(),
742 ipX_current_src_addr(), tcphdr->dest, tcphdr->src, ip_current_is_v6());
744 } else if ((flags & TCP_SYN) && (seqno == pcb->rcv_nxt - 1)) {
745 /* Looks like another copy of the SYN - retransmit our SYN-ACK */
753 if (recv_flags & TF_GOT_FIN) { /* passive close */
755 pcb->state = CLOSE_WAIT;
760 if (recv_flags & TF_GOT_FIN) {
761 if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) {
762 LWIP_DEBUGF(TCP_DEBUG,
763 ("TCP connection closed: FIN_WAIT_1 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
767 pcb->state = TIME_WAIT;
768 TCP_REG(&tcp_tw_pcbs, pcb);
771 pcb->state = CLOSING;
773 } else if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) {
774 pcb->state = FIN_WAIT_2;
779 if (recv_flags & TF_GOT_FIN) {
780 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: FIN_WAIT_2 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
784 pcb->state = TIME_WAIT;
785 TCP_REG(&tcp_tw_pcbs, pcb);
790 if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
791 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: CLOSING %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
794 pcb->state = TIME_WAIT;
795 TCP_REG(&tcp_tw_pcbs, pcb);
800 if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
801 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: LAST_ACK %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
802 /* bugfix #21699: don't set pcb->state to CLOSED here or we risk leaking segments */
803 recv_flags |= TF_CLOSED;
814 * Insert segment into the list (segments covered with new one will be deleted)
816 * Called from tcp_receive()
819 tcp_oos_insert_segment(struct tcp_seg *cseg, struct tcp_seg *next)
821 struct tcp_seg *old_seg;
823 if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) {
824 /* received segment overlaps all following segments */
829 /* delete some following segments
830 oos queue may have segments with FIN flag */
832 TCP_SEQ_GEQ((seqno + cseg->len),
833 (next->tcphdr->seqno + next->len))) {
834 /* cseg with FIN already processed */
835 if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) {
836 TCPH_SET_FLAG(cseg->tcphdr, TCP_FIN);
840 tcp_seg_free(old_seg);
843 TCP_SEQ_GT(seqno + cseg->len, next->tcphdr->seqno)) {
844 /* We need to trim the incoming segment. */
845 cseg->len = (u16_t)(next->tcphdr->seqno - seqno);
846 pbuf_realloc(cseg->p, cseg->len);
851 #endif /* TCP_QUEUE_OOSEQ */
854 * Called by tcp_process. Checks if the given segment is an ACK for outstanding
855 * data, and if so frees the memory of the buffered data. Next, is places the
856 * segment on any of the receive queues (pcb->recved or pcb->ooseq). If the segment
857 * is buffered, the pbuf is referenced by pbuf_ref so that it will not be freed until
858 * it has been removed from the buffer.
860 * If the incoming segment constitutes an ACK for a segment that was used for RTT
861 * estimation, the RTT is estimated here as well.
863 * Called from tcp_process().
866 tcp_receive(struct tcp_pcb *pcb)
868 struct tcp_seg *next;
870 struct tcp_seg *prev, *cseg;
871 #endif /* TCP_QUEUE_OOSEQ */
875 u32_t right_wnd_edge;
877 int found_dupack = 0;
878 #if TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS
881 #endif /* TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS */
883 LWIP_ASSERT("tcp_receive: wrong state", pcb->state >= ESTABLISHED);
885 if (flags & TCP_ACK) {
886 right_wnd_edge = pcb->snd_wnd + pcb->snd_wl2;
889 if (TCP_SEQ_LT(pcb->snd_wl1, seqno) ||
890 (pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) ||
891 (pcb->snd_wl2 == ackno && tcphdr->wnd > pcb->snd_wnd)) {
892 pcb->snd_wnd = tcphdr->wnd;
893 /* keep track of the biggest window announced by the remote host to calculate
894 the maximum segment size */
895 if (pcb->snd_wnd_max < tcphdr->wnd) {
896 pcb->snd_wnd_max = tcphdr->wnd;
898 pcb->snd_wl1 = seqno;
899 pcb->snd_wl2 = ackno;
900 if (pcb->snd_wnd == 0) {
901 if (pcb->persist_backoff == 0) {
902 /* start persist timer */
903 pcb->persist_cnt = 0;
904 pcb->persist_backoff = 1;
906 } else if (pcb->persist_backoff > 0) {
907 /* stop persist timer */
908 pcb->persist_backoff = 0;
910 LWIP_DEBUGF(TCP_WND_DEBUG, ("tcp_receive: window update %"U16_F"\n", pcb->snd_wnd));
913 if (pcb->snd_wnd != tcphdr->wnd) {
914 LWIP_DEBUGF(TCP_WND_DEBUG,
915 ("tcp_receive: no window update lastack %"U32_F" ackno %"
916 U32_F" wl1 %"U32_F" seqno %"U32_F" wl2 %"U32_F"\n",
917 pcb->lastack, ackno, pcb->snd_wl1, seqno, pcb->snd_wl2));
919 #endif /* TCP_WND_DEBUG */
922 /* (From Stevens TCP/IP Illustrated Vol II, p970.) Its only a
924 * 1) It doesn't ACK new data
925 * 2) length of received packet is zero (i.e. no payload)
926 * 3) the advertised window hasn't changed
927 * 4) There is outstanding unacknowledged data (retransmission timer running)
928 * 5) The ACK is == biggest ACK sequence number so far seen (snd_una)
930 * If it passes all five, should process as a dupack:
931 * a) dupacks < 3: do nothing
932 * b) dupacks == 3: fast retransmit
933 * c) dupacks > 3: increase cwnd
935 * If it only passes 1-3, should reset dupack counter (and add to
936 * stats, which we don't do in lwIP)
938 * If it only passes 1, should reset dupack counter
943 if (TCP_SEQ_LEQ(ackno, pcb->lastack)) {
948 if (pcb->snd_wl2 + pcb->snd_wnd == right_wnd_edge){
950 if (pcb->rtime >= 0) {
952 if (pcb->lastack == ackno) {
954 if ((u8_t)(pcb->dupacks + 1) > pcb->dupacks) {
957 if (pcb->dupacks > 3) {
958 /* Inflate the congestion window, but not if it means that
959 the value overflows. */
960 if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {
961 pcb->cwnd += pcb->mss;
963 } else if (pcb->dupacks == 3) {
964 /* Do fast retransmit */
965 tcp_rexmit_fast(pcb);
971 /* If Clause (1) or more is true, but not a duplicate ack, reset
972 * count of consecutive duplicate acks */
976 } else if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)){
977 /* We come here when the ACK acknowledges new data. */
979 /* Reset the "IN Fast Retransmit" flag, since we are no longer
980 in fast retransmit. Also reset the congestion window to the
981 slow start threshold. */
982 if (pcb->flags & TF_INFR) {
983 pcb->flags &= ~TF_INFR;
984 pcb->cwnd = pcb->ssthresh;
987 /* Reset the number of retransmissions. */
990 /* Reset the retransmission time-out. */
991 pcb->rto = (pcb->sa >> 3) + pcb->sv;
993 /* Update the send buffer space. Diff between the two can never exceed 64K? */
994 pcb->acked = (u16_t)(ackno - pcb->lastack);
996 pcb->snd_buf += pcb->acked;
998 /* Reset the fast retransmit variables. */
1000 pcb->lastack = ackno;
1002 /* Update the congestion control variables (cwnd and
1004 if (pcb->state >= ESTABLISHED) {
1005 if (pcb->cwnd < pcb->ssthresh) {
1006 if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {
1007 pcb->cwnd += pcb->mss;
1009 LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: slow start cwnd %"U16_F"\n", pcb->cwnd));
1011 u16_t new_cwnd = (pcb->cwnd + pcb->mss * pcb->mss / pcb->cwnd);
1012 if (new_cwnd > pcb->cwnd) {
1013 pcb->cwnd = new_cwnd;
1015 LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: congestion avoidance cwnd %"U16_F"\n", pcb->cwnd));
1018 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: ACK for %"U32_F", unacked->seqno %"U32_F":%"U32_F"\n",
1020 pcb->unacked != NULL?
1021 ntohl(pcb->unacked->tcphdr->seqno): 0,
1022 pcb->unacked != NULL?
1023 ntohl(pcb->unacked->tcphdr->seqno) + TCP_TCPLEN(pcb->unacked): 0));
1025 /* Remove segment from the unacknowledged list if the incoming
1026 ACK acknowlegdes them. */
1027 while (pcb->unacked != NULL &&
1028 TCP_SEQ_LEQ(ntohl(pcb->unacked->tcphdr->seqno) +
1029 TCP_TCPLEN(pcb->unacked), ackno)) {
1030 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unacked\n",
1031 ntohl(pcb->unacked->tcphdr->seqno),
1032 ntohl(pcb->unacked->tcphdr->seqno) +
1033 TCP_TCPLEN(pcb->unacked)));
1035 next = pcb->unacked;
1036 pcb->unacked = pcb->unacked->next;
1038 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen));
1039 LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p)));
1040 /* Prevent ACK for FIN to generate a sent event */
1041 if ((pcb->acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) {
1045 pcb->snd_queuelen -= pbuf_clen(next->p);
1048 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U16_F" (after freeing unacked)\n", (u16_t)pcb->snd_queuelen));
1049 if (pcb->snd_queuelen != 0) {
1050 LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL ||
1051 pcb->unsent != NULL);
1055 /* If there's nothing left to acknowledge, stop the retransmit
1056 timer, otherwise reset it to start again */
1057 if(pcb->unacked == NULL)
1064 #if LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS
1065 if (PCB_ISIPV6(pcb)) {
1066 /* Inform neighbor reachability of forward progress. */
1067 nd6_reachability_hint(ip6_current_src_addr());
1069 #endif /* LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS*/
1071 /* Fix bug bug #21582: out of sequence ACK, didn't really ack anything */
1075 /* We go through the ->unsent list to see if any of the segments
1076 on the list are acknowledged by the ACK. This may seem
1077 strange since an "unsent" segment shouldn't be acked. The
1078 rationale is that lwIP puts all outstanding segments on the
1079 ->unsent list after a retransmission, so these segments may
1080 in fact have been sent once. */
1081 while (pcb->unsent != NULL &&
1082 TCP_SEQ_BETWEEN(ackno, ntohl(pcb->unsent->tcphdr->seqno) +
1083 TCP_TCPLEN(pcb->unsent), pcb->snd_nxt)) {
1084 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unsent\n",
1085 ntohl(pcb->unsent->tcphdr->seqno), ntohl(pcb->unsent->tcphdr->seqno) +
1086 TCP_TCPLEN(pcb->unsent)));
1089 pcb->unsent = pcb->unsent->next;
1091 if (pcb->unsent == NULL) {
1092 pcb->unsent_oversize = 0;
1094 #endif /* TCP_OVERSIZE */
1095 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen));
1096 LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p)));
1097 /* Prevent ACK for FIN to generate a sent event */
1098 if ((pcb->acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) {
1101 pcb->snd_queuelen -= pbuf_clen(next->p);
1103 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U16_F" (after freeing unsent)\n", (u16_t)pcb->snd_queuelen));
1104 if (pcb->snd_queuelen != 0) {
1105 LWIP_ASSERT("tcp_receive: valid queue length",
1106 pcb->unacked != NULL || pcb->unsent != NULL);
1109 /* End of ACK for new data processing. */
1111 LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: pcb->rttest %"U32_F" rtseq %"U32_F" ackno %"U32_F"\n",
1112 pcb->rttest, pcb->rtseq, ackno));
1114 /* RTT estimation calculations. This is done by checking if the
1115 incoming segment acknowledges the segment we use to take a
1116 round-trip time measurement. */
1117 if (pcb->rttest && TCP_SEQ_LT(pcb->rtseq, ackno)) {
1118 /* diff between this shouldn't exceed 32K since this are tcp timer ticks
1119 and a round-trip shouldn't be that long... */
1120 m = (s16_t)(tcp_ticks - pcb->rttest);
1122 LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: experienced rtt %"U16_F" ticks (%"U16_F" msec).\n",
1123 m, m * TCP_SLOW_INTERVAL));
1125 /* This is taken directly from VJs original code in his paper */
1126 m = m - (pcb->sa >> 3);
1131 m = m - (pcb->sv >> 2);
1133 pcb->rto = (pcb->sa >> 3) + pcb->sv;
1135 LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: RTO %"U16_F" (%"U16_F" milliseconds)\n",
1136 pcb->rto, pcb->rto * TCP_SLOW_INTERVAL));
1142 /* If the incoming segment contains data, we must process it
1143 further unless the pcb already received a FIN.
1144 (RFC 793, chapeter 3.9, "SEGMENT ARRIVES" in states CLOSE-WAIT, CLOSING,
1145 LAST-ACK and TIME-WAIT: "Ignore the segment text.") */
1146 if ((tcplen > 0) && (pcb->state < CLOSE_WAIT)) {
1147 /* This code basically does three things:
1149 +) If the incoming segment contains data that is the next
1150 in-sequence data, this data is passed to the application. This
1151 might involve trimming the first edge of the data. The rcv_nxt
1152 variable and the advertised window are adjusted.
1154 +) If the incoming segment has data that is above the next
1155 sequence number expected (->rcv_nxt), the segment is placed on
1156 the ->ooseq queue. This is done by finding the appropriate
1157 place in the ->ooseq queue (which is ordered by sequence
1158 number) and trim the segment in both ends if needed. An
1159 immediate ACK is sent to indicate that we received an
1160 out-of-sequence segment.
1162 +) Finally, we check if the first segment on the ->ooseq queue
1163 now is in sequence (i.e., if rcv_nxt >= ooseq->seqno). If
1164 rcv_nxt > ooseq->seqno, we must trim the first edge of the
1165 segment on ->ooseq before we adjust rcv_nxt. The data in the
1166 segments that are now on sequence are chained onto the
1167 incoming segment so that we only need to call the application
1171 /* First, we check if we must trim the first edge. We have to do
1172 this if the sequence number of the incoming segment is less
1173 than rcv_nxt, and the sequence number plus the length of the
1174 segment is larger than rcv_nxt. */
1175 /* if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)){
1176 if (TCP_SEQ_LT(pcb->rcv_nxt, seqno + tcplen)) {*/
1177 if (TCP_SEQ_BETWEEN(pcb->rcv_nxt, seqno + 1, seqno + tcplen - 1)){
1178 /* Trimming the first edge is done by pushing the payload
1179 pointer in the pbuf downwards. This is somewhat tricky since
1180 we do not want to discard the full contents of the pbuf up to
1181 the new starting point of the data since we have to keep the
1182 TCP header which is present in the first pbuf in the chain.
1184 What is done is really quite a nasty hack: the first pbuf in
1185 the pbuf chain is pointed to by inseg.p. Since we need to be
1186 able to deallocate the whole pbuf, we cannot change this
1187 inseg.p pointer to point to any of the later pbufs in the
1188 chain. Instead, we point the ->payload pointer in the first
1189 pbuf to data in one of the later pbufs. We also set the
1190 inseg.data pointer to point to the right place. This way, the
1191 ->p pointer will still point to the first pbuf, but the
1192 ->p->payload pointer will point to data in another pbuf.
1194 After we are done with adjusting the pbuf pointers we must
1195 adjust the ->data pointer in the seg and the segment
1198 off = pcb->rcv_nxt - seqno;
1200 LWIP_ASSERT("inseg.p != NULL", inseg.p);
1201 LWIP_ASSERT("insane offset!", (off < 0x7fff));
1202 if (inseg.p->len < off) {
1203 LWIP_ASSERT("pbuf too short!", (((s32_t)inseg.p->tot_len) >= off));
1204 new_tot_len = (u16_t)(inseg.p->tot_len - off);
1205 while (p->len < off) {
1207 /* KJM following line changed (with addition of new_tot_len var)
1209 inseg.p->tot_len -= p->len; */
1210 p->tot_len = new_tot_len;
1214 if(pbuf_header(p, (s16_t)-off)) {
1215 /* Do we need to cope with this failing? Assert for now */
1216 LWIP_ASSERT("pbuf_header failed", 0);
1219 if(pbuf_header(inseg.p, (s16_t)-off)) {
1220 /* Do we need to cope with this failing? Assert for now */
1221 LWIP_ASSERT("pbuf_header failed", 0);
1224 inseg.len -= (u16_t)(pcb->rcv_nxt - seqno);
1225 inseg.tcphdr->seqno = seqno = pcb->rcv_nxt;
1228 if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)){
1229 /* the whole segment is < rcv_nxt */
1230 /* must be a duplicate of a packet that has already been correctly handled */
1232 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: duplicate seqno %"U32_F"\n", seqno));
1237 /* The sequence number must be within the window (above rcv_nxt
1238 and below rcv_nxt + rcv_wnd) in order to be further
1240 if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt,
1241 pcb->rcv_nxt + pcb->rcv_wnd - 1)){
1242 if (pcb->rcv_nxt == seqno) {
1243 /* The incoming segment is the next in sequence. We check if
1244 we have to trim the end of the segment and update rcv_nxt
1245 and pass the data to the application. */
1246 tcplen = TCP_TCPLEN(&inseg);
1248 if (tcplen > pcb->rcv_wnd) {
1249 LWIP_DEBUGF(TCP_INPUT_DEBUG,
1250 ("tcp_receive: other end overran receive window"
1251 "seqno %"U32_F" len %"U16_F" right edge %"U32_F"\n",
1252 seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd));
1253 if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
1254 /* Must remove the FIN from the header as we're trimming
1255 * that byte of sequence-space from the packet */
1256 TCPH_FLAGS_SET(inseg.tcphdr, TCPH_FLAGS(inseg.tcphdr) &~ TCP_FIN);
1258 /* Adjust length of segment to fit in the window. */
1259 inseg.len = pcb->rcv_wnd;
1260 if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) {
1263 pbuf_realloc(inseg.p, inseg.len);
1264 tcplen = TCP_TCPLEN(&inseg);
1265 LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n",
1266 (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd));
1269 /* Received in-sequence data, adjust ooseq data if:
1270 - FIN has been received or
1271 - inseq overlaps with ooseq */
1272 if (pcb->ooseq != NULL) {
1273 if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
1274 LWIP_DEBUGF(TCP_INPUT_DEBUG,
1275 ("tcp_receive: received in-order FIN, binning ooseq queue\n"));
1276 /* Received in-order FIN means anything that was received
1277 * out of order must now have been received in-order, so
1278 * bin the ooseq queue */
1279 while (pcb->ooseq != NULL) {
1280 struct tcp_seg *old_ooseq = pcb->ooseq;
1281 pcb->ooseq = pcb->ooseq->next;
1282 tcp_seg_free(old_ooseq);
1286 /* Remove all segments on ooseq that are covered by inseg already.
1287 * FIN is copied from ooseq to inseg if present. */
1289 TCP_SEQ_GEQ(seqno + tcplen,
1290 next->tcphdr->seqno + next->len)) {
1291 /* inseg cannot have FIN here (already processed above) */
1292 if (TCPH_FLAGS(next->tcphdr) & TCP_FIN &&
1293 (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) == 0) {
1294 TCPH_SET_FLAG(inseg.tcphdr, TCP_FIN);
1295 tcplen = TCP_TCPLEN(&inseg);
1301 /* Now trim right side of inseg if it overlaps with the first
1302 * segment on ooseq */
1304 TCP_SEQ_GT(seqno + tcplen,
1305 next->tcphdr->seqno)) {
1306 /* inseg cannot have FIN here (already processed above) */
1307 inseg.len = (u16_t)(next->tcphdr->seqno - seqno);
1308 if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) {
1311 pbuf_realloc(inseg.p, inseg.len);
1312 tcplen = TCP_TCPLEN(&inseg);
1313 LWIP_ASSERT("tcp_receive: segment not trimmed correctly to ooseq queue\n",
1314 (seqno + tcplen) == next->tcphdr->seqno);
1319 #endif /* TCP_QUEUE_OOSEQ */
1321 pcb->rcv_nxt = seqno + tcplen;
1323 /* Update the receiver's (our) window. */
1324 LWIP_ASSERT("tcp_receive: tcplen > rcv_wnd\n", pcb->rcv_wnd >= tcplen);
1325 pcb->rcv_wnd -= tcplen;
1327 tcp_update_rcv_ann_wnd(pcb);
1329 /* If there is data in the segment, we make preparations to
1330 pass this up to the application. The ->recv_data variable
1331 is used for holding the pbuf that goes to the
1332 application. The code for reassembling out-of-sequence data
1333 chains its data on this pbuf as well.
1335 If the segment was a FIN, we set the TF_GOT_FIN flag that will
1336 be used to indicate to the application that the remote side has
1337 closed its end of the connection. */
1338 if (inseg.p->tot_len > 0) {
1339 recv_data = inseg.p;
1340 /* Since this pbuf now is the responsibility of the
1341 application, we delete our reference to it so that we won't
1342 (mistakingly) deallocate it. */
1345 if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
1346 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN.\n"));
1347 recv_flags |= TF_GOT_FIN;
1351 /* We now check if we have segments on the ->ooseq queue that
1352 are now in sequence. */
1353 while (pcb->ooseq != NULL &&
1354 pcb->ooseq->tcphdr->seqno == pcb->rcv_nxt) {
1357 seqno = pcb->ooseq->tcphdr->seqno;
1359 pcb->rcv_nxt += TCP_TCPLEN(cseg);
1360 LWIP_ASSERT("tcp_receive: ooseq tcplen > rcv_wnd\n",
1361 pcb->rcv_wnd >= TCP_TCPLEN(cseg));
1362 pcb->rcv_wnd -= TCP_TCPLEN(cseg);
1364 tcp_update_rcv_ann_wnd(pcb);
1366 if (cseg->p->tot_len > 0) {
1367 /* Chain this pbuf onto the pbuf that we will pass to
1370 pbuf_cat(recv_data, cseg->p);
1372 recv_data = cseg->p;
1376 if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) {
1377 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN.\n"));
1378 recv_flags |= TF_GOT_FIN;
1379 if (pcb->state == ESTABLISHED) { /* force passive close or we can move to active close */
1380 pcb->state = CLOSE_WAIT;
1384 pcb->ooseq = cseg->next;
1387 #endif /* TCP_QUEUE_OOSEQ */
1390 /* Acknowledge the segment(s). */
1393 #if LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS
1394 if (PCB_ISIPV6(pcb)) {
1395 /* Inform neighbor reachability of forward progress. */
1396 nd6_reachability_hint(ip6_current_src_addr());
1398 #endif /* LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS*/
1401 /* We get here if the incoming segment is out-of-sequence. */
1402 tcp_send_empty_ack(pcb);
1404 /* We queue the segment on the ->ooseq queue. */
1405 if (pcb->ooseq == NULL) {
1406 pcb->ooseq = tcp_seg_copy(&inseg);
1408 /* If the queue is not empty, we walk through the queue and
1409 try to find a place where the sequence number of the
1410 incoming segment is between the sequence numbers of the
1411 previous and the next segment on the ->ooseq queue. That is
1412 the place where we put the incoming segment. If needed, we
1413 trim the second edges of the previous and the incoming
1414 segment so that it will fit into the sequence.
1416 If the incoming segment has the same sequence number as a
1417 segment on the ->ooseq queue, we discard the segment that
1418 contains less data. */
1421 for(next = pcb->ooseq; next != NULL; next = next->next) {
1422 if (seqno == next->tcphdr->seqno) {
1423 /* The sequence number of the incoming segment is the
1424 same as the sequence number of the segment on
1425 ->ooseq. We check the lengths to see which one to
1427 if (inseg.len > next->len) {
1428 /* The incoming segment is larger than the old
1429 segment. We replace some segments with the new
1431 cseg = tcp_seg_copy(&inseg);
1438 tcp_oos_insert_segment(cseg, next);
1442 /* Either the lenghts are the same or the incoming
1443 segment was smaller than the old one; in either
1444 case, we ditch the incoming segment. */
1449 if (TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {
1450 /* The sequence number of the incoming segment is lower
1451 than the sequence number of the first segment on the
1452 queue. We put the incoming segment first on the
1454 cseg = tcp_seg_copy(&inseg);
1457 tcp_oos_insert_segment(cseg, next);
1462 /*if (TCP_SEQ_LT(prev->tcphdr->seqno, seqno) &&
1463 TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {*/
1464 if (TCP_SEQ_BETWEEN(seqno, prev->tcphdr->seqno+1, next->tcphdr->seqno-1)) {
1465 /* The sequence number of the incoming segment is in
1466 between the sequence numbers of the previous and
1467 the next segment on ->ooseq. We trim trim the previous
1468 segment, delete next segments that included in received segment
1469 and trim received, if needed. */
1470 cseg = tcp_seg_copy(&inseg);
1472 if (TCP_SEQ_GT(prev->tcphdr->seqno + prev->len, seqno)) {
1473 /* We need to trim the prev segment. */
1474 prev->len = (u16_t)(seqno - prev->tcphdr->seqno);
1475 pbuf_realloc(prev->p, prev->len);
1478 tcp_oos_insert_segment(cseg, next);
1483 /* If the "next" segment is the last segment on the
1484 ooseq queue, we add the incoming segment to the end
1486 if (next->next == NULL &&
1487 TCP_SEQ_GT(seqno, next->tcphdr->seqno)) {
1488 if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) {
1489 /* segment "next" already contains all data */
1492 next->next = tcp_seg_copy(&inseg);
1493 if (next->next != NULL) {
1494 if (TCP_SEQ_GT(next->tcphdr->seqno + next->len, seqno)) {
1495 /* We need to trim the last segment. */
1496 next->len = (u16_t)(seqno - next->tcphdr->seqno);
1497 pbuf_realloc(next->p, next->len);
1499 /* check if the remote side overruns our receive window */
1500 if ((u32_t)tcplen + seqno > pcb->rcv_nxt + (u32_t)pcb->rcv_wnd) {
1501 LWIP_DEBUGF(TCP_INPUT_DEBUG,
1502 ("tcp_receive: other end overran receive window"
1503 "seqno %"U32_F" len %"U16_F" right edge %"U32_F"\n",
1504 seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd));
1505 if (TCPH_FLAGS(next->next->tcphdr) & TCP_FIN) {
1506 /* Must remove the FIN from the header as we're trimming
1507 * that byte of sequence-space from the packet */
1508 TCPH_FLAGS_SET(next->next->tcphdr, TCPH_FLAGS(next->next->tcphdr) &~ TCP_FIN);
1510 /* Adjust length of segment to fit in the window. */
1511 next->next->len = pcb->rcv_nxt + pcb->rcv_wnd - seqno;
1512 pbuf_realloc(next->next->p, next->next->len);
1513 tcplen = TCP_TCPLEN(next->next);
1514 LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n",
1515 (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd));
1524 #if TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS
1525 /* Check that the data on ooseq doesn't exceed one of the limits
1526 and throw away everything above that limit. */
1530 for(next = pcb->ooseq; next != NULL; prev = next, next = next->next) {
1531 struct pbuf *p = next->p;
1532 ooseq_blen += p->tot_len;
1533 ooseq_qlen += pbuf_clen(p);
1534 if ((ooseq_blen > TCP_OOSEQ_MAX_BYTES) ||
1535 (ooseq_qlen > TCP_OOSEQ_MAX_PBUFS)) {
1536 /* too much ooseq data, dump this and everything after it */
1537 tcp_segs_free(next);
1539 /* first ooseq segment is too much, dump the whole queue */
1542 /* just dump 'next' and everything after it */
1548 #endif /* TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS */
1549 #endif /* TCP_QUEUE_OOSEQ */
1552 /* The incoming segment is not withing the window. */
1553 tcp_send_empty_ack(pcb);
1556 /* Segments with length 0 is taken care of here. Segments that
1557 fall out of the window are ACKed. */
1558 /*if (TCP_SEQ_GT(pcb->rcv_nxt, seqno) ||
1559 TCP_SEQ_GEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {*/
1560 if(!TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd-1)){
1567 * Parses the options contained in the incoming segment.
1569 * Called from tcp_listen_input() and tcp_process().
1570 * Currently, only the MSS option is supported!
1572 * @param pcb the tcp_pcb for which a segment arrived
1575 tcp_parseopt(struct tcp_pcb *pcb)
1580 #if LWIP_TCP_TIMESTAMPS
1584 opts = (u8_t *)tcphdr + TCP_HLEN;
1586 /* Parse the TCP MSS option, if present. */
1587 if(TCPH_HDRLEN(tcphdr) > 0x5) {
1588 max_c = (TCPH_HDRLEN(tcphdr) - 5) << 2;
1589 for (c = 0; c < max_c; ) {
1593 /* End of options. */
1594 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: EOL\n"));
1599 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: NOP\n"));
1602 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: MSS\n"));
1603 if (opts[c + 1] != 0x04 || c + 0x04 > max_c) {
1605 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
1608 /* An MSS option with the right option length. */
1609 mss = (opts[c + 2] << 8) | opts[c + 3];
1610 /* Limit the mss to the configured TCP_MSS and prevent division by zero */
1611 pcb->mss = ((mss > TCP_MSS) || (mss == 0)) ? TCP_MSS : mss;
1612 /* Advance to next option */
1615 #if LWIP_TCP_TIMESTAMPS
1617 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: TS\n"));
1618 if (opts[c + 1] != 0x0A || c + 0x0A > max_c) {
1620 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
1623 /* TCP timestamp option with valid length */
1624 tsval = (opts[c+2]) | (opts[c+3] << 8) |
1625 (opts[c+4] << 16) | (opts[c+5] << 24);
1626 if (flags & TCP_SYN) {
1627 pcb->ts_recent = ntohl(tsval);
1628 pcb->flags |= TF_TIMESTAMP;
1629 } else if (TCP_SEQ_BETWEEN(pcb->ts_lastacksent, seqno, seqno+tcplen)) {
1630 pcb->ts_recent = ntohl(tsval);
1632 /* Advance to next option */
1637 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: other\n"));
1638 if (opts[c + 1] == 0) {
1639 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
1640 /* If the length field is zero, the options are malformed
1641 and we don't process them further. */
1644 /* All other options have a length field, so that we easily
1645 can skip past them. */
1652 #endif /* LWIP_TCP */