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 /* These variables are global to all functions involved in the input
60 processing of TCP segments. They are set by the tcp_input()
62 static struct tcp_seg inseg
;
63 static struct tcp_hdr
*tcphdr
;
64 static struct ip_hdr
*iphdr
;
65 static u32_t seqno
, ackno
;
69 static u8_t recv_flags
;
70 static struct pbuf
*recv_data
;
72 struct tcp_pcb
*tcp_input_pcb
;
74 /* Forward declarations. */
75 static err_t
tcp_process(struct tcp_pcb
*pcb
);
76 static void tcp_receive(struct tcp_pcb
*pcb
);
77 static void tcp_parseopt(struct tcp_pcb
*pcb
);
79 static err_t
tcp_listen_input(struct tcp_pcb_listen
*pcb
);
80 static err_t
tcp_timewait_input(struct tcp_pcb
*pcb
);
83 * The initial input processing of TCP. It verifies the TCP header, demultiplexes
84 * the segment between the PCBs and passes it on to tcp_process(), which implements
85 * the TCP finite state machine. This function is called by the IP layer (in
88 * @param p received TCP segment to process (p->payload pointing to the IP header)
89 * @param inp network interface on which this segment was received
92 tcp_input(struct pbuf
*p
, struct netif
*inp
)
94 struct tcp_pcb
*pcb
, *prev
;
95 struct tcp_pcb_listen
*lpcb
;
97 struct tcp_pcb
*lpcb_prev
= NULL
;
98 struct tcp_pcb_listen
*lpcb_any
= NULL
;
105 TCP_STATS_INC(tcp
.recv
);
106 snmp_inc_tcpinsegs();
108 iphdr
= (struct ip_hdr
*)p
->payload
;
109 tcphdr
= (struct tcp_hdr
*)((u8_t
*)p
->payload
+ IPH_HL(iphdr
) * 4);
111 LWIP_DEBUGF(TCP_DEBUG
, ("tcp_input: called\n"));
114 tcp_debug_print(tcphdr
);
117 /* remove header from payload */
118 if (pbuf_header(p
, -((s16_t
)(IPH_HL(iphdr
) * 4))) || (p
->tot_len
< sizeof(struct tcp_hdr
)))
120 /* drop short packets */
121 LWIP_DEBUGF(TCP_INPUT_DEBUG
, ("tcp_input: short packet (%"U16_F
" bytes) discarded\n", p
->tot_len
));
122 TCP_STATS_INC(tcp
.lenerr
);
123 TCP_STATS_INC(tcp
.drop
);
124 snmp_inc_tcpinerrs();
129 /* Don't even process incoming broadcasts/multicasts. */
130 if (ip_addr_isbroadcast(¤t_iphdr_dest
, inp
) ||
131 ip_addr_ismulticast(¤t_iphdr_dest
)) {
132 TCP_STATS_INC(tcp
.proterr
);
133 TCP_STATS_INC(tcp
.drop
);
134 snmp_inc_tcpinerrs();
139 #if CHECKSUM_CHECK_TCP
140 /* Verify TCP checksum. */
141 if (inet_chksum_pseudo(p
, ip_current_src_addr(), ip_current_dest_addr(),
142 IP_PROTO_TCP
, p
->tot_len
) != 0) {
143 LWIP_DEBUGF(TCP_INPUT_DEBUG
, ("tcp_input: packet discarded due to failing checksum 0x%04"X16_F
"\n",
144 inet_chksum_pseudo(p
, ip_current_src_addr(), ip_current_dest_addr(),
145 IP_PROTO_TCP
, p
->tot_len
)));
147 tcp_debug_print(tcphdr
);
148 #endif /* TCP_DEBUG */
149 TCP_STATS_INC(tcp
.chkerr
);
150 TCP_STATS_INC(tcp
.drop
);
151 snmp_inc_tcpinerrs();
157 /* Move the payload pointer in the pbuf so that it points to the
158 TCP data instead of the TCP header. */
159 hdrlen
= TCPH_HDRLEN(tcphdr
);
160 if(pbuf_header(p
, -(hdrlen
* 4))){
161 /* drop short packets */
162 LWIP_DEBUGF(TCP_INPUT_DEBUG
, ("tcp_input: short packet\n"));
163 TCP_STATS_INC(tcp
.lenerr
);
164 TCP_STATS_INC(tcp
.drop
);
165 snmp_inc_tcpinerrs();
170 /* Convert fields in TCP header to host byte order. */
171 tcphdr
->src
= ntohs(tcphdr
->src
);
172 tcphdr
->dest
= ntohs(tcphdr
->dest
);
173 seqno
= tcphdr
->seqno
= ntohl(tcphdr
->seqno
);
174 ackno
= tcphdr
->ackno
= ntohl(tcphdr
->ackno
);
175 tcphdr
->wnd
= ntohs(tcphdr
->wnd
);
177 flags
= TCPH_FLAGS(tcphdr
);
178 tcplen
= p
->tot_len
+ ((flags
& (TCP_FIN
| TCP_SYN
)) ? 1 : 0);
180 /* Demultiplex an incoming segment. First, we check if it is destined
181 for an active connection. */
185 for(pcb
= tcp_active_pcbs
; pcb
!= NULL
; pcb
= pcb
->next
)
187 LWIP_ASSERT("tcp_input: active pcb->state != CLOSED", pcb
->state
!= CLOSED
);
188 LWIP_ASSERT("tcp_input: active pcb->state != TIME-WAIT", pcb
->state
!= TIME_WAIT
);
189 LWIP_ASSERT("tcp_input: active pcb->state != LISTEN", pcb
->state
!= LISTEN
);
190 if (pcb
->remote_port
== tcphdr
->src
&&
191 pcb
->local_port
== tcphdr
->dest
&&
192 ip_addr_cmp(&(pcb
->remote_ip
), ¤t_iphdr_src
) &&
193 ip_addr_cmp(&(pcb
->local_ip
), ¤t_iphdr_dest
))
196 /* Move this PCB to the front of the list so that subsequent
197 lookups will be faster (we exploit locality in TCP segment
199 LWIP_ASSERT("tcp_input: pcb->next != pcb (before cache)", pcb
->next
!= pcb
);
202 prev
->next
= pcb
->next
;
203 pcb
->next
= tcp_active_pcbs
;
204 tcp_active_pcbs
= pcb
;
206 LWIP_ASSERT("tcp_input: pcb->next != pcb (after cache)", pcb
->next
!= pcb
);
214 /* If it did not go to an active connection, we check the connections
215 in the TIME-WAIT state. */
216 for(pcb
= tcp_tw_pcbs
; pcb
!= NULL
; pcb
= pcb
->next
)
218 LWIP_ASSERT("tcp_input: TIME-WAIT pcb->state == TIME-WAIT", pcb
->state
== TIME_WAIT
);
219 if (pcb
->remote_port
== tcphdr
->src
&&
220 pcb
->local_port
== tcphdr
->dest
&&
221 ip_addr_cmp(&(pcb
->remote_ip
), ¤t_iphdr_src
) &&
222 ip_addr_cmp(&(pcb
->local_ip
), ¤t_iphdr_dest
))
224 /* We don't really care enough to move this PCB to the front
225 of the list since we are not very likely to receive that
226 many segments for connections in TIME-WAIT. */
227 LWIP_DEBUGF(TCP_INPUT_DEBUG
, ("tcp_input: packed for TIME_WAITing connection.\n"));
228 tcp_timewait_input(pcb
);
234 /* Finally, if we still did not get a match, we check all PCBs that
235 are LISTENing for incoming connections. */
237 for(lpcb
= tcp_listen_pcbs
.listen_pcbs
; lpcb
!= NULL
; lpcb
= lpcb
->next
)
239 if (lpcb
->local_port
== tcphdr
->dest
)
242 if (ip_addr_cmp(&(lpcb
->local_ip
), ¤t_iphdr_dest
)) {
243 /* found an exact match */
245 } else if(ip_addr_isany(&(lpcb
->local_ip
))) {
246 /* found an ANY-match */
251 if (ip_addr_cmp(&(lpcb
->local_ip
), ¤t_iphdr_dest
) ||
252 ip_addr_isany(&(lpcb
->local_ip
)))
257 #endif /* SO_REUSE */
259 prev
= (struct tcp_pcb
*)lpcb
;
262 /* first try specific local IP */
264 /* only pass to ANY if no specific local IP has been found */
268 #endif /* SO_REUSE */
271 /* Move this PCB to the front of the list so that subsequent
272 lookups will be faster (we exploit locality in TCP segment
276 ((struct tcp_pcb_listen
*)prev
)->next
= lpcb
->next
;
277 /* our successor is the remainder of the listening list */
278 lpcb
->next
= tcp_listen_pcbs
.listen_pcbs
;
279 /* put this listening pcb at the head of the listening list */
280 tcp_listen_pcbs
.listen_pcbs
= lpcb
;
283 LWIP_DEBUGF(TCP_DEBUG
, ("tcp_input: packed for LISTENing connection\n"));
285 tcp_listen_input(lpcb
);
292 LWIP_DEBUGF(TCP_INPUT_DEBUG
, ("+-+-+-+-+-+-+-+-+-+-+-+-+-+- tcp_input: flags "));
293 tcp_debug_print_flags(TCPH_FLAGS(tcphdr
));
294 LWIP_DEBUGF(TCP_INPUT_DEBUG
, ("-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n"));
295 #endif /* TCP_INPUT_DEBUG */
300 LWIP_DEBUGF(TCP_DEBUG
, ("tcp_input: pcb->id = %d is for active connection\n", pcb
->identifier
));
301 /* The incoming segment belongs to a connection. */
304 tcp_debug_print_state(pcb
->state
);
305 #endif /* TCP_DEBUG */
306 #endif /* TCP_INPUT_DEBUG */
308 /* Set up a tcp_seg structure. */
310 inseg
.len
= p
->tot_len
;
311 inseg
.dataptr
= p
->payload
;
313 inseg
.tcphdr
= tcphdr
;
318 /* If there is data which was previously "refused" by upper layer */
319 if (pcb
->refused_data
!= NULL
)
321 /* Notify again application with data previously received. */
322 LWIP_DEBUGF(TCP_INPUT_DEBUG
, ("tcp_input: notify kept packet\n"));
323 TCP_EVENT_RECV(pcb
, pcb
->refused_data
, ERR_OK
, err
);
325 pcb
->refused_data
= NULL
;
329 /* if err == ERR_ABRT, 'pcb' is already deallocated */
330 /* drop incoming packets, because pcb is "full" */
331 LWIP_DEBUGF(TCP_INPUT_DEBUG
, ("tcp_input: drop incoming packets, because pcb is \"full\"\n"));
332 TCP_STATS_INC(tcp
.drop
);
333 snmp_inc_tcpinerrs();
339 err
= tcp_process(pcb
);
340 /* A return value of ERR_ABRT means that tcp_abort() was called
341 and that the pcb has been freed. If so, we don't do anything. */
344 if (recv_flags
& TF_RESET
)
346 /* TF_RESET means that the connection was reset by the other
347 end. We then call the error callback to inform the
348 application that the connection is dead before we
349 deallocate the PCB. */
350 TCP_EVENT_ERR(pcb
->errf
, pcb
->callback_arg
, ERR_RST
);
351 tcp_pcb_remove(&tcp_active_pcbs
, pcb
);
352 memp_free(MEMP_TCP_PCB
, pcb
);
354 else if (recv_flags
& TF_CLOSED
)
356 /* The connection has been closed and we will deallocate the
358 tcp_pcb_remove(&tcp_active_pcbs
, pcb
);
359 memp_free(MEMP_TCP_PCB
, pcb
);
364 /* If the application has registered a "sent" function to be
365 called when new send buffer space is available, we call it
369 TCP_EVENT_SENT(pcb
, pcb
->acked
, err
);
376 if (recv_data
!= NULL
)
378 if (pcb
->flags
& TF_RXCLOSED
)
380 /* received data although already closed -> abort (send RST) to
381 notify the remote host that not all data has been processed */
382 pbuf_free(recv_data
);
388 recv_data
->flags
|= PBUF_FLAG_PUSH
;
391 /* Notify application that data has been received. */
392 TCP_EVENT_RECV(pcb
, recv_data
, ERR_OK
, err
);
398 /* If the upper layer can't receive this data, store it */
401 pcb
->refused_data
= recv_data
;
402 LWIP_DEBUGF(TCP_INPUT_DEBUG
, ("tcp_input: keep incoming packet, because pcb is \"full\"\n"));
406 /* If a FIN segment was received, we call the callback
407 function with a NULL buffer to indicate EOF. */
408 if (recv_flags
& TF_GOT_FIN
)
410 /* correct rcv_wnd as the application won't call tcp_recved()
411 for the FIN's seqno */
412 if (pcb
->rcv_wnd
!= TCP_WND
)
417 TCP_EVENT_CLOSED(pcb
, err
);
425 tcp_input_pcb
= NULL
;
426 /* Try to send something out. */
430 tcp_debug_print_state(pcb
->state
);
431 #endif /* TCP_DEBUG */
432 #endif /* TCP_INPUT_DEBUG */
435 /* Jump target if pcb has been aborted in a callback (by calling tcp_abort()).
436 Below this line, 'pcb' may not be dereferenced! */
438 tcp_input_pcb
= NULL
;
441 /* give up our reference to inseg.p */
451 /* If no matching PCB was found, send a TCP RST (reset) to the
453 LWIP_DEBUGF(TCP_RST_DEBUG
, ("tcp_input: no PCB match found, resetting.\n"));
454 if (!(TCPH_FLAGS(tcphdr
) & TCP_RST
)) {
455 TCP_STATS_INC(tcp
.proterr
);
456 TCP_STATS_INC(tcp
.drop
);
457 tcp_rst(ackno
, seqno
+ tcplen
,
458 ip_current_dest_addr(), ip_current_src_addr(),
459 tcphdr
->dest
, tcphdr
->src
);
464 LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane());
465 PERF_STOP("tcp_input");
469 * Called by tcp_input() when a segment arrives for a listening
470 * connection (from tcp_input()).
472 * @param pcb the tcp_pcb_listen for which a segment arrived
473 * @return ERR_OK if the segment was processed
474 * another err_t on error
476 * @note the return value is not (yet?) used in tcp_input()
477 * @note the segment which arrived is saved in global variables, therefore only the pcb
478 * involved is passed as a parameter to this function
481 tcp_listen_input(struct tcp_pcb_listen
*pcb
)
483 struct tcp_pcb
*npcb
;
486 /* In the LISTEN state, we check for incoming SYN segments,
487 creates a new PCB, and responds with a SYN|ACK. */
488 if (flags
& TCP_ACK
) {
489 /* For incoming segments with the ACK flag set, respond with a
491 LWIP_DEBUGF(TCP_RST_DEBUG
, ("tcp_listen_input: ACK in LISTEN, sending reset\n"));
492 tcp_rst(ackno
+ 1, seqno
+ tcplen
,
493 ip_current_dest_addr(), ip_current_src_addr(),
494 tcphdr
->dest
, tcphdr
->src
);
495 } else if (flags
& TCP_SYN
) {
496 LWIP_DEBUGF(TCP_DEBUG
, ("TCP connection request %"U16_F
" -> %"U16_F
".\n", tcphdr
->src
, tcphdr
->dest
));
497 #if TCP_LISTEN_BACKLOG
498 if (pcb
->accepts_pending
>= pcb
->backlog
) {
499 LWIP_DEBUGF(TCP_DEBUG
, ("tcp_listen_input: listen backlog exceeded for port %"U16_F
"\n", tcphdr
->dest
));
502 #endif /* TCP_LISTEN_BACKLOG */
503 npcb
= tcp_alloc(pcb
->prio
);
504 /* If a new PCB could not be created (probably due to lack of memory),
505 we don't do anything, but rely on the sender will retransmit the
506 SYN at a time when we have more memory available. */
508 LWIP_DEBUGF(TCP_DEBUG
, ("tcp_listen_input: could not allocate PCB\n"));
509 TCP_STATS_INC(tcp
.memerr
);
512 #if TCP_LISTEN_BACKLOG
513 pcb
->accepts_pending
++;
514 #endif /* TCP_LISTEN_BACKLOG */
515 /* Set up the new PCB. */
516 ip_addr_copy(npcb
->local_ip
, current_iphdr_dest
);
517 npcb
->local_port
= pcb
->local_port
;
518 ip_addr_copy(npcb
->remote_ip
, current_iphdr_src
);
519 npcb
->remote_port
= tcphdr
->src
;
520 npcb
->state
= SYN_RCVD
;
521 npcb
->rcv_nxt
= seqno
+ 1;
522 npcb
->rcv_ann_right_edge
= npcb
->rcv_nxt
;
523 npcb
->snd_wnd
= tcphdr
->wnd
;
524 npcb
->ssthresh
= npcb
->snd_wnd
;
525 npcb
->snd_wl1
= seqno
- 1;/* initialise to seqno-1 to force window update */
526 npcb
->callback_arg
= pcb
->callback_arg
;
527 #if LWIP_CALLBACK_API
528 npcb
->accept
= pcb
->accept
;
529 #endif /* LWIP_CALLBACK_API */
530 /* inherit socket options */
531 npcb
->so_options
= pcb
->so_options
& SOF_INHERITED
;
533 /* Register the new PCB so that we can begin receiving segments
535 TCP_REG(&tcp_active_pcbs
, npcb
);
537 npcb
->identifier
= 21912;
538 LWIP_DEBUGF(TCP_DEBUG
, ("TCP new pcb created with %"U16_F
" -> %"U16_F
".\n", npcb
->local_port
, npcb
->remote_port
));
540 /* Parse any options in the SYN. */
542 #if TCP_CALCULATE_EFF_SEND_MSS
543 npcb
->mss
= tcp_eff_send_mss(npcb
->mss
, &(npcb
->remote_ip
));
544 #endif /* TCP_CALCULATE_EFF_SEND_MSS */
546 snmp_inc_tcppassiveopens();
548 /* Send a SYN|ACK together with the MSS option. */
549 rc
= tcp_enqueue_flags(npcb
, TCP_SYN
| TCP_ACK
);
551 tcp_abandon(npcb
, 0);
554 return tcp_output(npcb
);
560 * Called by tcp_input() when a segment arrives for a connection in
563 * @param pcb the tcp_pcb for which a segment arrived
565 * @note the segment which arrived is saved in global variables, therefore only the pcb
566 * involved is passed as a parameter to this function
569 tcp_timewait_input(struct tcp_pcb
*pcb
)
571 /* RFC 1337: in TIME_WAIT, ignore RST and ACK FINs + any 'acceptable' segments */
572 /* RFC 793 3.9 Event Processing - Segment Arrives:
573 * - first check sequence number - we skip that one in TIME_WAIT (always
574 * acceptable since we only send ACKs)
575 * - second check the RST bit (... return) */
576 if (flags
& TCP_RST
) {
579 /* - fourth, check the SYN bit, */
580 if (flags
& TCP_SYN
) {
581 /* If an incoming segment is not acceptable, an acknowledgment
582 should be sent in reply */
583 if (TCP_SEQ_BETWEEN(seqno
, pcb
->rcv_nxt
, pcb
->rcv_nxt
+pcb
->rcv_wnd
)) {
584 /* If the SYN is in the window it is an error, send a reset */
585 tcp_rst(ackno
, seqno
+ tcplen
, ip_current_dest_addr(), ip_current_src_addr(),
586 tcphdr
->dest
, tcphdr
->src
);
589 } else if (flags
& TCP_FIN
) {
590 /* - eighth, check the FIN bit: Remain in the TIME-WAIT state.
591 Restart the 2 MSL time-wait timeout.*/
592 pcb
->tmr
= tcp_ticks
;
596 /* Acknowledge data, FIN or out-of-window SYN */
597 pcb
->flags
|= TF_ACK_NOW
;
598 return tcp_output(pcb
);
604 * Implements the TCP state machine. Called by tcp_input. In some
605 * states tcp_receive() is called to receive data. The tcp_seg
606 * argument will be freed by the caller (tcp_input()) unless the
607 * recv_data pointer in the pcb is set.
609 * @param pcb the tcp_pcb for which a segment arrived
611 * @note the segment which arrived is saved in global variables, therefore only the pcb
612 * involved is passed as a parameter to this function
615 tcp_process(struct tcp_pcb
*pcb
)
617 struct tcp_seg
*rseg
;
623 LWIP_DEBUGF(TCP_DEBUG
, ("[tcp_process] called\n"));
625 /* Process incoming RST segments. */
626 if (flags
& TCP_RST
) {
627 /* First, determine if the reset is acceptable. */
628 if (pcb
->state
== SYN_SENT
) {
629 if (ackno
== pcb
->snd_nxt
) {
633 if (TCP_SEQ_BETWEEN(seqno
, pcb
->rcv_nxt
,
634 pcb
->rcv_nxt
+pcb
->rcv_wnd
)) {
640 LWIP_DEBUGF(TCP_INPUT_DEBUG
, ("tcp_process: Connection RESET\n"));
641 LWIP_ASSERT("tcp_input: pcb->state != CLOSED", pcb
->state
!= CLOSED
);
642 recv_flags
|= TF_RESET
;
643 pcb
->flags
&= ~TF_ACK_DELAY
;
646 LWIP_DEBUGF(TCP_INPUT_DEBUG
, ("tcp_process: unacceptable reset seqno %"U32_F
" rcv_nxt %"U32_F
"\n",
647 seqno
, pcb
->rcv_nxt
));
648 LWIP_DEBUGF(TCP_DEBUG
, ("tcp_process: unacceptable reset seqno %"U32_F
" rcv_nxt %"U32_F
"\n",
649 seqno
, pcb
->rcv_nxt
));
654 if ((flags
& TCP_SYN
) && (pcb
->state
!= SYN_SENT
&& pcb
->state
!= SYN_RCVD
)) {
655 /* Cope with new connection attempt after remote end crashed */
660 if ((pcb
->flags
& TF_RXCLOSED
) == 0) {
661 /* Update the PCB (in)activity timer unless rx is closed (see tcp_shutdown) */
662 pcb
->tmr
= tcp_ticks
;
664 pcb
->keep_cnt_sent
= 0;
668 /* Do different things depending on the TCP state. */
669 switch (pcb
->state
) {
671 LWIP_DEBUGF(TCP_INPUT_DEBUG
, ("SYN-SENT: ackno %"U32_F
" pcb->snd_nxt %"U32_F
" unacked %"U32_F
"\n", ackno
,
672 pcb
->snd_nxt
, ntohl(pcb
->unacked
->tcphdr
->seqno
)));
673 /* received SYN ACK with expected sequence number? */
674 if ((flags
& TCP_ACK
) && (flags
& TCP_SYN
)
675 && ackno
== ntohl(pcb
->unacked
->tcphdr
->seqno
) + 1) {
677 pcb
->rcv_nxt
= seqno
+ 1;
678 pcb
->rcv_ann_right_edge
= pcb
->rcv_nxt
;
679 pcb
->lastack
= ackno
;
680 pcb
->snd_wnd
= tcphdr
->wnd
;
681 pcb
->snd_wl1
= seqno
- 1; /* initialise to seqno - 1 to force window update */
682 pcb
->state
= ESTABLISHED
;
684 LWIP_DEBUGF(TCP_DEBUG
,
685 ("[tcp_process] (SYN_SENT) TCP connection established %"U16_F
" -> %"U16_F
", %"U16_F
"\n",
686 pcb
->local_port
, pcb
->remote_port
, pcb
->identifier
));
688 #if TCP_CALCULATE_EFF_SEND_MSS
689 pcb
->mss
= tcp_eff_send_mss(pcb
->mss
, &(pcb
->remote_ip
));
690 #endif /* TCP_CALCULATE_EFF_SEND_MSS */
692 /* Set ssthresh again after changing pcb->mss (already set in tcp_connect
693 * but for the default value of pcb->mss) */
694 pcb
->ssthresh
= pcb
->mss
* 10;
696 pcb
->cwnd
= ((pcb
->cwnd
== 1) ? (pcb
->mss
* 2) : pcb
->mss
);
697 LWIP_ASSERT("pcb->snd_queuelen > 0", (pcb
->snd_queuelen
> 0));
699 LWIP_DEBUGF(TCP_QLEN_DEBUG
, ("tcp_process: SYN-SENT --queuelen %"U16_F
"\n", (u16_t
)pcb
->snd_queuelen
));
701 pcb
->unacked
= rseg
->next
;
703 /* If there's nothing left to acknowledge, stop the retransmit
704 timer, otherwise reset it to start again */
705 if(pcb
->unacked
== NULL
)
714 /* Call the user specified function to call when sucessfully
716 TCP_EVENT_CONNECTED(pcb
, ERR_OK
, err
);
717 if (err
== ERR_ABRT
) {
722 /* received ACK? possibly a half-open connection */
723 else if (flags
& TCP_ACK
) {
724 /* send a RST to bring the other side in a non-synchronized state. */
725 tcp_rst(ackno
, seqno
+ tcplen
, ip_current_dest_addr(), ip_current_src_addr(),
726 tcphdr
->dest
, tcphdr
->src
);
730 if (flags
& TCP_ACK
) {
731 /* expected ACK number? */
732 if (TCP_SEQ_BETWEEN(ackno
, pcb
->lastack
+1, pcb
->snd_nxt
)) {
734 pcb
->state
= ESTABLISHED
;
735 LWIP_DEBUGF(TCP_DEBUG
,
736 ("[tcp_process] (SYN_RCVD) TCP connection established %"U16_F
" -> %"U16_F
" for %"U16_F
"\n",
737 inseg
.tcphdr
->src
, inseg
.tcphdr
->dest
, pcb
->identifier
));
738 LWIP_DEBUGF(TCP_DEBUG
,
739 ("[tcp_process] (SYN_RCVD) TCP local port = %"U16_F
" and ID = %"U16_F
"\n",
740 pcb
->local_port
, pcb
->identifier
));
742 #if LWIP_CALLBACK_API
743 LWIP_ASSERT("pcb->accept != NULL", pcb
->accept
!= NULL
);
745 /* Call the accept function. */
746 TCP_EVENT_ACCEPT(pcb
, ERR_OK
, err
);
748 /* If the accept function returns with an error, we abort
750 /* Already aborted? */
751 if (err
!= ERR_ABRT
) {
756 old_cwnd
= pcb
->cwnd
;
757 /* If there was any data contained within this ACK,
758 * we'd better pass it on to the application as well. */
761 /* Prevent ACK for SYN to generate a sent event */
762 if (pcb
->acked
!= 0) {
766 pcb
->cwnd
= ((old_cwnd
== 1) ? (pcb
->mss
* 2) : pcb
->mss
);
768 if (recv_flags
& TF_GOT_FIN
) {
770 pcb
->state
= CLOSE_WAIT
;
773 /* incorrect ACK number, send RST */
774 tcp_rst(ackno
, seqno
+ tcplen
, ip_current_dest_addr(), ip_current_src_addr(),
775 tcphdr
->dest
, tcphdr
->src
);
777 } else if ((flags
& TCP_SYN
) && (seqno
== pcb
->rcv_nxt
- 1)) {
778 /* Looks like another copy of the SYN - retransmit our SYN-ACK */
786 if (recv_flags
& TF_GOT_FIN
) { /* passive close */
788 pcb
->state
= CLOSE_WAIT
;
793 if (recv_flags
& TF_GOT_FIN
) {
794 if ((flags
& TCP_ACK
) && (ackno
== pcb
->snd_nxt
)) {
795 LWIP_DEBUGF(TCP_DEBUG
,
796 ("TCP connection closed: FIN_WAIT_1 %"U16_F
" -> %"U16_F
".\n", inseg
.tcphdr
->src
, inseg
.tcphdr
->dest
));
799 TCP_RMV(&tcp_active_pcbs
, pcb
);
800 pcb
->state
= TIME_WAIT
;
801 TCP_REG(&tcp_tw_pcbs
, pcb
);
804 pcb
->state
= CLOSING
;
806 } else if ((flags
& TCP_ACK
) && (ackno
== pcb
->snd_nxt
)) {
807 pcb
->state
= FIN_WAIT_2
;
812 if (recv_flags
& TF_GOT_FIN
) {
813 LWIP_DEBUGF(TCP_DEBUG
, ("TCP connection closed: FIN_WAIT_2 %"U16_F
" -> %"U16_F
".\n", inseg
.tcphdr
->src
, inseg
.tcphdr
->dest
));
816 TCP_RMV(&tcp_active_pcbs
, pcb
);
817 pcb
->state
= TIME_WAIT
;
818 TCP_REG(&tcp_tw_pcbs
, pcb
);
823 if (flags
& TCP_ACK
&& ackno
== pcb
->snd_nxt
) {
824 LWIP_DEBUGF(TCP_DEBUG
, ("TCP connection closed: CLOSING %"U16_F
" -> %"U16_F
".\n", inseg
.tcphdr
->src
, inseg
.tcphdr
->dest
));
826 TCP_RMV(&tcp_active_pcbs
, pcb
);
827 pcb
->state
= TIME_WAIT
;
828 TCP_REG(&tcp_tw_pcbs
, pcb
);
833 if (flags
& TCP_ACK
&& ackno
== pcb
->snd_nxt
) {
834 LWIP_DEBUGF(TCP_DEBUG
, ("TCP connection closed: LAST_ACK %"U16_F
" -> %"U16_F
".\n", inseg
.tcphdr
->src
, inseg
.tcphdr
->dest
));
835 /* bugfix #21699: don't set pcb->state to CLOSED here or we risk leaking segments */
836 recv_flags
|= TF_CLOSED
;
847 * Insert segment into the list (segments covered with new one will be deleted)
849 * Called from tcp_receive()
852 tcp_oos_insert_segment(struct tcp_seg
*cseg
, struct tcp_seg
*next
)
854 struct tcp_seg
*old_seg
;
856 if (TCPH_FLAGS(cseg
->tcphdr
) & TCP_FIN
) {
857 /* received segment overlaps all following segments */
862 /* delete some following segments
863 oos queue may have segments with FIN flag */
865 TCP_SEQ_GEQ((seqno
+ cseg
->len
),
866 (next
->tcphdr
->seqno
+ next
->len
))) {
867 /* cseg with FIN already processed */
868 if (TCPH_FLAGS(next
->tcphdr
) & TCP_FIN
) {
869 TCPH_SET_FLAG(cseg
->tcphdr
, TCP_FIN
);
873 tcp_seg_free(old_seg
);
876 TCP_SEQ_GT(seqno
+ cseg
->len
, next
->tcphdr
->seqno
)) {
877 /* We need to trim the incoming segment. */
878 cseg
->len
= (u16_t
)(next
->tcphdr
->seqno
- seqno
);
879 pbuf_realloc(cseg
->p
, cseg
->len
);
884 #endif /* TCP_QUEUE_OOSEQ */
887 * Called by tcp_process. Checks if the given segment is an ACK for outstanding
888 * data, and if so frees the memory of the buffered data. Next, is places the
889 * segment on any of the receive queues (pcb->recved or pcb->ooseq). If the segment
890 * is buffered, the pbuf is referenced by pbuf_ref so that it will not be freed until
891 * i it has been removed from the buffer.
893 * If the incoming segment constitutes an ACK for a segment that was used for RTT
894 * estimation, the RTT is estimated here as well.
896 * Called from tcp_process().
899 tcp_receive(struct tcp_pcb
*pcb
)
901 struct tcp_seg
*next
;
903 struct tcp_seg
*prev
, *cseg
;
904 #endif /* TCP_QUEUE_OOSEQ */
908 u32_t right_wnd_edge
;
910 int found_dupack
= 0;
912 if (flags
& TCP_ACK
) {
913 right_wnd_edge
= pcb
->snd_wnd
+ pcb
->snd_wl2
;
916 if (TCP_SEQ_LT(pcb
->snd_wl1
, seqno
) ||
917 (pcb
->snd_wl1
== seqno
&& TCP_SEQ_LT(pcb
->snd_wl2
, ackno
)) ||
918 (pcb
->snd_wl2
== ackno
&& tcphdr
->wnd
> pcb
->snd_wnd
)) {
919 pcb
->snd_wnd
= tcphdr
->wnd
;
920 pcb
->snd_wl1
= seqno
;
921 pcb
->snd_wl2
= ackno
;
922 if (pcb
->snd_wnd
> 0 && pcb
->persist_backoff
> 0) {
923 pcb
->persist_backoff
= 0;
925 LWIP_DEBUGF(TCP_WND_DEBUG
, ("tcp_receive: window update %"U16_F
"\n", pcb
->snd_wnd
));
928 if (pcb
->snd_wnd
!= tcphdr
->wnd
) {
929 LWIP_DEBUGF(TCP_WND_DEBUG
,
930 ("tcp_receive: no window update lastack %"U32_F
" ackno %"
931 U32_F
" wl1 %"U32_F
" seqno %"U32_F
" wl2 %"U32_F
"\n",
932 pcb
->lastack
, ackno
, pcb
->snd_wl1
, seqno
, pcb
->snd_wl2
));
934 #endif /* TCP_WND_DEBUG */
937 /* (From Stevens TCP/IP Illustrated Vol II, p970.) Its only a
939 * 1) It doesn't ACK new data
940 * 2) length of received packet is zero (i.e. no payload)
941 * 3) the advertised window hasn't changed
942 * 4) There is outstanding unacknowledged data (retransmission timer running)
943 * 5) The ACK is == biggest ACK sequence number so far seen (snd_una)
945 * If it passes all five, should process as a dupack:
946 * a) dupacks < 3: do nothing
947 * b) dupacks == 3: fast retransmit
948 * c) dupacks > 3: increase cwnd
950 * If it only passes 1-3, should reset dupack counter (and add to
951 * stats, which we don't do in lwIP)
953 * If it only passes 1, should reset dupack counter
958 if (TCP_SEQ_LEQ(ackno
, pcb
->lastack
)) {
963 if (pcb
->snd_wl2
+ pcb
->snd_wnd
== right_wnd_edge
){
965 if (pcb
->rtime
>= 0) {
967 if (pcb
->lastack
== ackno
) {
969 if (pcb
->dupacks
+ 1 > pcb
->dupacks
)
971 if (pcb
->dupacks
> 3) {
972 /* Inflate the congestion window, but not if it means that
973 the value overflows. */
974 if ((u16_t
)(pcb
->cwnd
+ pcb
->mss
) > pcb
->cwnd
) {
975 pcb
->cwnd
+= pcb
->mss
;
977 } else if (pcb
->dupacks
== 3) {
978 /* Do fast retransmit */
979 tcp_rexmit_fast(pcb
);
985 /* If Clause (1) or more is true, but not a duplicate ack, reset
986 * count of consecutive duplicate acks */
990 } else if (TCP_SEQ_BETWEEN(ackno
, pcb
->lastack
+1, pcb
->snd_nxt
)){
991 /* We come here when the ACK acknowledges new data. */
993 /* Reset the "IN Fast Retransmit" flag, since we are no longer
994 in fast retransmit. Also reset the congestion window to the
995 slow start threshold. */
996 if (pcb
->flags
& TF_INFR
) {
997 pcb
->flags
&= ~TF_INFR
;
998 pcb
->cwnd
= pcb
->ssthresh
;
1001 /* Reset the number of retransmissions. */
1004 /* Reset the retransmission time-out. */
1005 pcb
->rto
= (pcb
->sa
>> 3) + pcb
->sv
;
1007 /* Update the send buffer space. Diff between the two can never exceed 64K? */
1008 pcb
->acked
= (u16_t
)(ackno
- pcb
->lastack
);
1010 pcb
->snd_buf
+= pcb
->acked
;
1012 /* Reset the fast retransmit variables. */
1014 pcb
->lastack
= ackno
;
1016 /* Update the congestion control variables (cwnd and
1018 if (pcb
->state
>= ESTABLISHED
) {
1019 if (pcb
->cwnd
< pcb
->ssthresh
) {
1020 if ((u16_t
)(pcb
->cwnd
+ pcb
->mss
) > pcb
->cwnd
) {
1021 pcb
->cwnd
+= pcb
->mss
;
1023 LWIP_DEBUGF(TCP_CWND_DEBUG
, ("tcp_receive: slow start cwnd %"U16_F
"\n", pcb
->cwnd
));
1025 u16_t new_cwnd
= (pcb
->cwnd
+ pcb
->mss
* pcb
->mss
/ pcb
->cwnd
);
1026 if (new_cwnd
> pcb
->cwnd
) {
1027 pcb
->cwnd
= new_cwnd
;
1029 LWIP_DEBUGF(TCP_CWND_DEBUG
, ("tcp_receive: congestion avoidance cwnd %"U16_F
"\n", pcb
->cwnd
));
1032 LWIP_DEBUGF(TCP_INPUT_DEBUG
, ("tcp_receive: ACK for %"U32_F
", unacked->seqno %"U32_F
":%"U32_F
"\n",
1034 pcb
->unacked
!= NULL
?
1035 ntohl(pcb
->unacked
->tcphdr
->seqno
): 0,
1036 pcb
->unacked
!= NULL
?
1037 ntohl(pcb
->unacked
->tcphdr
->seqno
) + TCP_TCPLEN(pcb
->unacked
): 0));
1039 /* Remove segment from the unacknowledged list if the incoming
1040 ACK acknowlegdes them. */
1041 while (pcb
->unacked
!= NULL
&&
1042 TCP_SEQ_LEQ(ntohl(pcb
->unacked
->tcphdr
->seqno
) +
1043 TCP_TCPLEN(pcb
->unacked
), ackno
)) {
1044 LWIP_DEBUGF(TCP_INPUT_DEBUG
, ("tcp_receive: removing %"U32_F
":%"U32_F
" from pcb->unacked\n",
1045 ntohl(pcb
->unacked
->tcphdr
->seqno
),
1046 ntohl(pcb
->unacked
->tcphdr
->seqno
) +
1047 TCP_TCPLEN(pcb
->unacked
)));
1049 next
= pcb
->unacked
;
1050 pcb
->unacked
= pcb
->unacked
->next
;
1052 LWIP_DEBUGF(TCP_QLEN_DEBUG
, ("tcp_receive: queuelen %"U16_F
" ... ", (u16_t
)pcb
->snd_queuelen
));
1053 LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb
->snd_queuelen
>= pbuf_clen(next
->p
)));
1054 /* Prevent ACK for FIN to generate a sent event */
1055 if ((pcb
->acked
!= 0) && ((TCPH_FLAGS(next
->tcphdr
) & TCP_FIN
) != 0)) {
1059 pcb
->snd_queuelen
-= pbuf_clen(next
->p
);
1062 LWIP_DEBUGF(TCP_QLEN_DEBUG
, ("%"U16_F
" (after freeing unacked)\n", (u16_t
)pcb
->snd_queuelen
));
1063 if (pcb
->snd_queuelen
!= 0) {
1064 LWIP_ASSERT("tcp_receive: valid queue length", pcb
->unacked
!= NULL
||
1065 pcb
->unsent
!= NULL
);
1069 /* If there's nothing left to acknowledge, stop the retransmit
1070 timer, otherwise reset it to start again */
1071 if(pcb
->unacked
== NULL
)
1078 /* Fix bug bug #21582: out of sequence ACK, didn't really ack anything */
1082 /* We go through the ->unsent list to see if any of the segments
1083 on the list are acknowledged by the ACK. This may seem
1084 strange since an "unsent" segment shouldn't be acked. The
1085 rationale is that lwIP puts all outstanding segments on the
1086 ->unsent list after a retransmission, so these segments may
1087 in fact have been sent once. */
1088 while (pcb
->unsent
!= NULL
&&
1089 TCP_SEQ_BETWEEN(ackno
, ntohl(pcb
->unsent
->tcphdr
->seqno
) +
1090 TCP_TCPLEN(pcb
->unsent
), pcb
->snd_nxt
)) {
1091 LWIP_DEBUGF(TCP_INPUT_DEBUG
, ("tcp_receive: removing %"U32_F
":%"U32_F
" from pcb->unsent\n",
1092 ntohl(pcb
->unsent
->tcphdr
->seqno
), ntohl(pcb
->unsent
->tcphdr
->seqno
) +
1093 TCP_TCPLEN(pcb
->unsent
)));
1096 pcb
->unsent
= pcb
->unsent
->next
;
1097 LWIP_DEBUGF(TCP_QLEN_DEBUG
, ("tcp_receive: queuelen %"U16_F
" ... ", (u16_t
)pcb
->snd_queuelen
));
1098 LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb
->snd_queuelen
>= pbuf_clen(next
->p
)));
1099 /* Prevent ACK for FIN to generate a sent event */
1100 if ((pcb
->acked
!= 0) && ((TCPH_FLAGS(next
->tcphdr
) & TCP_FIN
) != 0)) {
1103 pcb
->snd_queuelen
-= pbuf_clen(next
->p
);
1105 LWIP_DEBUGF(TCP_QLEN_DEBUG
, ("%"U16_F
" (after freeing unsent)\n", (u16_t
)pcb
->snd_queuelen
));
1106 if (pcb
->snd_queuelen
!= 0) {
1107 LWIP_ASSERT("tcp_receive: valid queue length",
1108 pcb
->unacked
!= NULL
|| pcb
->unsent
!= NULL
);
1111 /* End of ACK for new data processing. */
1113 LWIP_DEBUGF(TCP_RTO_DEBUG
, ("tcp_receive: pcb->rttest %"U32_F
" rtseq %"U32_F
" ackno %"U32_F
"\n",
1114 pcb
->rttest
, pcb
->rtseq
, ackno
));
1116 /* RTT estimation calculations. This is done by checking if the
1117 incoming segment acknowledges the segment we use to take a
1118 round-trip time measurement. */
1119 if (pcb
->rttest
&& TCP_SEQ_LT(pcb
->rtseq
, ackno
)) {
1120 /* diff between this shouldn't exceed 32K since this are tcp timer ticks
1121 and a round-trip shouldn't be that long... */
1122 m
= (s16_t
)(tcp_ticks
- pcb
->rttest
);
1124 LWIP_DEBUGF(TCP_RTO_DEBUG
, ("tcp_receive: experienced rtt %"U16_F
" ticks (%"U16_F
" msec).\n",
1125 m
, m
* TCP_SLOW_INTERVAL
));
1127 /* This is taken directly from VJs original code in his paper */
1128 m
= m
- (pcb
->sa
>> 3);
1133 m
= m
- (pcb
->sv
>> 2);
1135 pcb
->rto
= (pcb
->sa
>> 3) + pcb
->sv
;
1137 LWIP_DEBUGF(TCP_RTO_DEBUG
, ("tcp_receive: RTO %"U16_F
" (%"U16_F
" milliseconds)\n",
1138 pcb
->rto
, pcb
->rto
* TCP_SLOW_INTERVAL
));
1144 /* If the incoming segment contains data, we must process it
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 /* KJM following line changed to use p->payload rather than inseg->p->payload
1226 inseg
.dataptr
= p
->payload
;
1227 inseg
.len
-= (u16_t
)(pcb
->rcv_nxt
- seqno
);
1228 inseg
.tcphdr
->seqno
= seqno
= pcb
->rcv_nxt
;
1231 if (TCP_SEQ_LT(seqno
, pcb
->rcv_nxt
)){
1232 /* the whole segment is < rcv_nxt */
1233 /* must be a duplicate of a packet that has already been correctly handled */
1235 LWIP_DEBUGF(TCP_INPUT_DEBUG
, ("tcp_receive: duplicate seqno %"U32_F
"\n", seqno
));
1240 /* The sequence number must be within the window (above rcv_nxt
1241 and below rcv_nxt + rcv_wnd) in order to be further
1243 if (TCP_SEQ_BETWEEN(seqno
, pcb
->rcv_nxt
,
1244 pcb
->rcv_nxt
+ pcb
->rcv_wnd
- 1)){
1245 if (pcb
->rcv_nxt
== seqno
) {
1246 /* The incoming segment is the next in sequence. We check if
1247 we have to trim the end of the segment and update rcv_nxt
1248 and pass the data to the application. */
1249 tcplen
= TCP_TCPLEN(&inseg
);
1251 if (tcplen
> pcb
->rcv_wnd
) {
1252 LWIP_DEBUGF(TCP_INPUT_DEBUG
,
1253 ("tcp_receive: other end overran receive window"
1254 "seqno %"U32_F
" len %"U16_F
" right edge %"U32_F
"\n",
1255 seqno
, tcplen
, pcb
->rcv_nxt
+ pcb
->rcv_wnd
));
1256 if (TCPH_FLAGS(inseg
.tcphdr
) & TCP_FIN
) {
1257 /* Must remove the FIN from the header as we're trimming
1258 * that byte of sequence-space from the packet */
1259 TCPH_FLAGS_SET(inseg
.tcphdr
, TCPH_FLAGS(inseg
.tcphdr
) &~ TCP_FIN
);
1261 /* Adjust length of segment to fit in the window. */
1262 inseg
.len
= pcb
->rcv_wnd
;
1263 if (TCPH_FLAGS(inseg
.tcphdr
) & TCP_SYN
) {
1266 pbuf_realloc(inseg
.p
, inseg
.len
);
1267 tcplen
= TCP_TCPLEN(&inseg
);
1268 LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n",
1269 (seqno
+ tcplen
) == (pcb
->rcv_nxt
+ pcb
->rcv_wnd
));
1272 /* Received in-sequence data, adjust ooseq data if:
1273 - FIN has been received or
1274 - inseq overlaps with ooseq */
1275 if (pcb
->ooseq
!= NULL
) {
1276 if (TCPH_FLAGS(inseg
.tcphdr
) & TCP_FIN
) {
1277 LWIP_DEBUGF(TCP_INPUT_DEBUG
,
1278 ("tcp_receive: received in-order FIN, binning ooseq queue\n"));
1279 /* Received in-order FIN means anything that was received
1280 * out of order must now have been received in-order, so
1281 * bin the ooseq queue */
1282 while (pcb
->ooseq
!= NULL
) {
1283 struct tcp_seg
*old_ooseq
= pcb
->ooseq
;
1284 pcb
->ooseq
= pcb
->ooseq
->next
;
1285 tcp_seg_free(old_ooseq
);
1290 /* Remove all segments on ooseq that are covered by inseg already.
1291 * FIN is copied from ooseq to inseg if present. */
1293 TCP_SEQ_GEQ(seqno
+ tcplen
,
1294 next
->tcphdr
->seqno
+ next
->len
)) {
1295 /* inseg cannot have FIN here (already processed above) */
1296 if (TCPH_FLAGS(next
->tcphdr
) & TCP_FIN
&&
1297 (TCPH_FLAGS(inseg
.tcphdr
) & TCP_SYN
) == 0) {
1298 TCPH_SET_FLAG(inseg
.tcphdr
, TCP_FIN
);
1299 tcplen
= TCP_TCPLEN(&inseg
);
1305 /* Now trim right side of inseg if it overlaps with the first
1306 * segment on ooseq */
1308 TCP_SEQ_GT(seqno
+ tcplen
,
1309 next
->tcphdr
->seqno
)) {
1310 /* inseg cannot have FIN here (already processed above) */
1311 inseg
.len
= (u16_t
)(next
->tcphdr
->seqno
- seqno
);
1312 if (TCPH_FLAGS(inseg
.tcphdr
) & TCP_SYN
) {
1315 pbuf_realloc(inseg
.p
, inseg
.len
);
1316 tcplen
= TCP_TCPLEN(&inseg
);
1317 LWIP_ASSERT("tcp_receive: segment not trimmed correctly to ooseq queue\n",
1318 (seqno
+ tcplen
) == next
->tcphdr
->seqno
);
1323 #endif /* TCP_QUEUE_OOSEQ */
1325 pcb
->rcv_nxt
= seqno
+ tcplen
;
1327 /* Update the receiver's (our) window. */
1328 LWIP_ASSERT("tcp_receive: tcplen > rcv_wnd\n", pcb
->rcv_wnd
>= tcplen
);
1329 pcb
->rcv_wnd
-= tcplen
;
1331 tcp_update_rcv_ann_wnd(pcb
);
1333 /* If there is data in the segment, we make preparations to
1334 pass this up to the application. The ->recv_data variable
1335 is used for holding the pbuf that goes to the
1336 application. The code for reassembling out-of-sequence data
1337 chains its data on this pbuf as well.
1339 If the segment was a FIN, we set the TF_GOT_FIN flag that will
1340 be used to indicate to the application that the remote side has
1341 closed its end of the connection. */
1342 if (inseg
.p
->tot_len
> 0) {
1343 recv_data
= inseg
.p
;
1344 /* Since this pbuf now is the responsibility of the
1345 application, we delete our reference to it so that we won't
1346 (mistakingly) deallocate it. */
1349 if (TCPH_FLAGS(inseg
.tcphdr
) & TCP_FIN
) {
1350 LWIP_DEBUGF(TCP_INPUT_DEBUG
, ("tcp_receive: received FIN.\n"));
1351 recv_flags
|= TF_GOT_FIN
;
1355 /* We now check if we have segments on the ->ooseq queue that
1356 are now in sequence. */
1357 while (pcb
->ooseq
!= NULL
&&
1358 pcb
->ooseq
->tcphdr
->seqno
== pcb
->rcv_nxt
) {
1361 seqno
= pcb
->ooseq
->tcphdr
->seqno
;
1363 pcb
->rcv_nxt
+= TCP_TCPLEN(cseg
);
1364 LWIP_ASSERT("tcp_receive: ooseq tcplen > rcv_wnd\n",
1365 pcb
->rcv_wnd
>= TCP_TCPLEN(cseg
));
1366 pcb
->rcv_wnd
-= TCP_TCPLEN(cseg
);
1368 tcp_update_rcv_ann_wnd(pcb
);
1370 if (cseg
->p
->tot_len
> 0) {
1371 /* Chain this pbuf onto the pbuf that we will pass to
1374 pbuf_cat(recv_data
, cseg
->p
);
1376 recv_data
= cseg
->p
;
1380 if (TCPH_FLAGS(cseg
->tcphdr
) & TCP_FIN
) {
1381 LWIP_DEBUGF(TCP_INPUT_DEBUG
, ("tcp_receive: dequeued FIN.\n"));
1382 recv_flags
|= TF_GOT_FIN
;
1383 if (pcb
->state
== ESTABLISHED
) { /* force passive close or we can move to active close */
1384 pcb
->state
= CLOSE_WAIT
;
1388 pcb
->ooseq
= cseg
->next
;
1391 #endif /* TCP_QUEUE_OOSEQ */
1394 /* Acknowledge the segment(s). */
1398 /* We get here if the incoming segment is out-of-sequence. */
1399 tcp_send_empty_ack(pcb
);
1401 /* We queue the segment on the ->ooseq queue. */
1402 if (pcb
->ooseq
== NULL
) {
1403 pcb
->ooseq
= tcp_seg_copy(&inseg
);
1405 /* If the queue is not empty, we walk through the queue and
1406 try to find a place where the sequence number of the
1407 incoming segment is between the sequence numbers of the
1408 previous and the next segment on the ->ooseq queue. That is
1409 the place where we put the incoming segment. If needed, we
1410 trim the second edges of the previous and the incoming
1411 segment so that it will fit into the sequence.
1413 If the incoming segment has the same sequence number as a
1414 segment on the ->ooseq queue, we discard the segment that
1415 contains less data. */
1418 for(next
= pcb
->ooseq
; next
!= NULL
; next
= next
->next
) {
1419 if (seqno
== next
->tcphdr
->seqno
) {
1420 /* The sequence number of the incoming segment is the
1421 same as the sequence number of the segment on
1422 ->ooseq. We check the lengths to see which one to
1424 if (inseg
.len
> next
->len
) {
1425 /* The incoming segment is larger than the old
1426 segment. We replace some segments with the new
1428 cseg
= tcp_seg_copy(&inseg
);
1435 tcp_oos_insert_segment(cseg
, next
);
1439 /* Either the lenghts are the same or the incoming
1440 segment was smaller than the old one; in either
1441 case, we ditch the incoming segment. */
1446 if (TCP_SEQ_LT(seqno
, next
->tcphdr
->seqno
)) {
1447 /* The sequence number of the incoming segment is lower
1448 than the sequence number of the first segment on the
1449 queue. We put the incoming segment first on the
1451 cseg
= tcp_seg_copy(&inseg
);
1454 tcp_oos_insert_segment(cseg
, next
);
1459 /*if (TCP_SEQ_LT(prev->tcphdr->seqno, seqno) &&
1460 TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {*/
1461 if (TCP_SEQ_BETWEEN(seqno
, prev
->tcphdr
->seqno
+1, next
->tcphdr
->seqno
-1)) {
1462 /* The sequence number of the incoming segment is in
1463 between the sequence numbers of the previous and
1464 the next segment on ->ooseq. We trim trim the previous
1465 segment, delete next segments that included in received segment
1466 and trim received, if needed. */
1467 cseg
= tcp_seg_copy(&inseg
);
1469 if (TCP_SEQ_GT(prev
->tcphdr
->seqno
+ prev
->len
, seqno
)) {
1470 /* We need to trim the prev segment. */
1471 prev
->len
= (u16_t
)(seqno
- prev
->tcphdr
->seqno
);
1472 pbuf_realloc(prev
->p
, prev
->len
);
1475 tcp_oos_insert_segment(cseg
, next
);
1480 /* If the "next" segment is the last segment on the
1481 ooseq queue, we add the incoming segment to the end
1483 if (next
->next
== NULL
&&
1484 TCP_SEQ_GT(seqno
, next
->tcphdr
->seqno
)) {
1485 if (TCPH_FLAGS(next
->tcphdr
) & TCP_FIN
) {
1486 /* segment "next" already contains all data */
1489 next
->next
= tcp_seg_copy(&inseg
);
1490 if (next
->next
!= NULL
) {
1491 if (TCP_SEQ_GT(next
->tcphdr
->seqno
+ next
->len
, seqno
)) {
1492 /* We need to trim the last segment. */
1493 next
->len
= (u16_t
)(seqno
- next
->tcphdr
->seqno
);
1494 pbuf_realloc(next
->p
, next
->len
);
1496 /* check if the remote side overruns our receive window */
1497 if ((u32_t
)tcplen
+ seqno
> pcb
->rcv_nxt
+ (u32_t
)pcb
->rcv_wnd
) {
1498 LWIP_DEBUGF(TCP_INPUT_DEBUG
,
1499 ("tcp_receive: other end overran receive window"
1500 "seqno %"U32_F
" len %"U16_F
" right edge %"U32_F
"\n",
1501 seqno
, tcplen
, pcb
->rcv_nxt
+ pcb
->rcv_wnd
));
1502 if (TCPH_FLAGS(next
->next
->tcphdr
) & TCP_FIN
) {
1503 /* Must remove the FIN from the header as we're trimming
1504 * that byte of sequence-space from the packet */
1505 TCPH_FLAGS_SET(next
->next
->tcphdr
, TCPH_FLAGS(next
->next
->tcphdr
) &~ TCP_FIN
);
1507 /* Adjust length of segment to fit in the window. */
1508 next
->next
->len
= pcb
->rcv_nxt
+ pcb
->rcv_wnd
- seqno
;
1509 pbuf_realloc(next
->next
->p
, next
->next
->len
);
1510 tcplen
= TCP_TCPLEN(next
->next
);
1511 LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n",
1512 (seqno
+ tcplen
) == (pcb
->rcv_nxt
+ pcb
->rcv_wnd
));
1521 #endif /* TCP_QUEUE_OOSEQ */
1525 /* The incoming segment is not withing the window. */
1526 tcp_send_empty_ack(pcb
);
1529 /* Segments with length 0 is taken care of here. Segments that
1530 fall out of the window are ACKed. */
1531 /*if (TCP_SEQ_GT(pcb->rcv_nxt, seqno) ||
1532 TCP_SEQ_GEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {*/
1533 if(!TCP_SEQ_BETWEEN(seqno
, pcb
->rcv_nxt
, pcb
->rcv_nxt
+ pcb
->rcv_wnd
-1)){
1540 * Parses the options contained in the incoming segment.
1542 * Called from tcp_listen_input() and tcp_process().
1543 * Currently, only the MSS option is supported!
1545 * @param pcb the tcp_pcb for which a segment arrived
1548 tcp_parseopt(struct tcp_pcb
*pcb
)
1553 #if LWIP_TCP_TIMESTAMPS
1557 opts
= (u8_t
*)tcphdr
+ TCP_HLEN
;
1559 /* Parse the TCP MSS option, if present. */
1560 if(TCPH_HDRLEN(tcphdr
) > 0x5) {
1561 max_c
= (TCPH_HDRLEN(tcphdr
) - 5) << 2;
1562 for (c
= 0; c
< max_c
; ) {
1566 /* End of options. */
1567 LWIP_DEBUGF(TCP_INPUT_DEBUG
, ("tcp_parseopt: EOL\n"));
1572 LWIP_DEBUGF(TCP_INPUT_DEBUG
, ("tcp_parseopt: NOP\n"));
1575 LWIP_DEBUGF(TCP_INPUT_DEBUG
, ("tcp_parseopt: MSS\n"));
1576 if (opts
[c
+ 1] != 0x04 || c
+ 0x04 > max_c
) {
1578 LWIP_DEBUGF(TCP_INPUT_DEBUG
, ("tcp_parseopt: bad length\n"));
1581 /* An MSS option with the right option length. */
1582 mss
= (opts
[c
+ 2] << 8) | opts
[c
+ 3];
1583 /* Limit the mss to the configured TCP_MSS and prevent division by zero */
1584 pcb
->mss
= ((mss
> TCP_MSS
) || (mss
== 0)) ? TCP_MSS
: mss
;
1585 /* Advance to next option */
1588 #if LWIP_TCP_TIMESTAMPS
1590 LWIP_DEBUGF(TCP_INPUT_DEBUG
, ("tcp_parseopt: TS\n"));
1591 if (opts
[c
+ 1] != 0x0A || c
+ 0x0A > max_c
) {
1593 LWIP_DEBUGF(TCP_INPUT_DEBUG
, ("tcp_parseopt: bad length\n"));
1596 /* TCP timestamp option with valid length */
1597 tsval
= (opts
[c
+2]) | (opts
[c
+3] << 8) |
1598 (opts
[c
+4] << 16) | (opts
[c
+5] << 24);
1599 if (flags
& TCP_SYN
) {
1600 pcb
->ts_recent
= ntohl(tsval
);
1601 pcb
->flags
|= TF_TIMESTAMP
;
1602 } else if (TCP_SEQ_BETWEEN(pcb
->ts_lastacksent
, seqno
, seqno
+tcplen
)) {
1603 pcb
->ts_recent
= ntohl(tsval
);
1605 /* Advance to next option */
1610 LWIP_DEBUGF(TCP_INPUT_DEBUG
, ("tcp_parseopt: other\n"));
1611 if (opts
[c
+ 1] == 0) {
1612 LWIP_DEBUGF(TCP_INPUT_DEBUG
, ("tcp_parseopt: bad length\n"));
1613 /* If the length field is zero, the options are malformed
1614 and we don't process them further. */
1617 /* All other options have a length field, so that we easily
1618 can skip past them. */
1625 #endif /* LWIP_TCP */