Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
lwip_tcp_in.c
00001 /** 00002 * @file 00003 * Transmission Control Protocol, incoming traffic 00004 * 00005 * The input processing functions of the TCP layer. 00006 * 00007 * These functions are generally called in the order (ip_input() ->) 00008 * tcp_input() -> * tcp_process() -> tcp_receive() (-> application). 00009 * 00010 */ 00011 00012 /* 00013 * Copyright (c) 2001-2004 Swedish Institute of Computer Science. 00014 * All rights reserved. 00015 * 00016 * Redistribution and use in source and binary forms, with or without modification, 00017 * are permitted provided that the following conditions are met: 00018 * 00019 * 1. Redistributions of source code must retain the above copyright notice, 00020 * this list of conditions and the following disclaimer. 00021 * 2. Redistributions in binary form must reproduce the above copyright notice, 00022 * this list of conditions and the following disclaimer in the documentation 00023 * and/or other materials provided with the distribution. 00024 * 3. The name of the author may not be used to endorse or promote products 00025 * derived from this software without specific prior written permission. 00026 * 00027 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 00028 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 00029 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 00030 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00031 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 00032 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00033 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00034 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 00035 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 00036 * OF SUCH DAMAGE. 00037 * 00038 * This file is part of the lwIP TCP/IP stack. 00039 * 00040 * Author: Adam Dunkels <adam@sics.se> 00041 * 00042 */ 00043 00044 #include "lwip/opt.h" 00045 00046 #if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ 00047 00048 #include "lwip/priv/tcp_priv.h" 00049 #include "lwip/def.h" 00050 #include "lwip/ip_addr.h" 00051 #include "lwip/netif.h" 00052 #include "lwip/mem.h" 00053 #include "lwip/memp.h" 00054 #include "lwip/inet_chksum.h" 00055 #include "lwip/stats.h" 00056 #include "lwip/ip6.h" 00057 #include "lwip/ip6_addr.h" 00058 #if LWIP_ND6_TCP_REACHABILITY_HINTS 00059 #include "lwip/nd6.h" 00060 #endif /* LWIP_ND6_TCP_REACHABILITY_HINTS */ 00061 00062 #include <string.h> 00063 00064 #ifdef LWIP_HOOK_FILENAME 00065 #include LWIP_HOOK_FILENAME 00066 #endif 00067 00068 /** Initial CWND calculation as defined RFC 2581 */ 00069 #define LWIP_TCP_CALC_INITIAL_CWND(mss) ((tcpwnd_size_t)LWIP_MIN((4U * (mss)), LWIP_MAX((2U * (mss)), 4380U))) 00070 00071 /* These variables are global to all functions involved in the input 00072 processing of TCP segments. They are set by the tcp_input() 00073 function. */ 00074 static struct tcp_seg inseg; 00075 static struct tcp_hdr *tcphdr; 00076 static u16_t tcphdr_optlen; 00077 static u16_t tcphdr_opt1len; 00078 static u8_t *tcphdr_opt2; 00079 static u16_t tcp_optidx; 00080 static u32_t seqno, ackno; 00081 static tcpwnd_size_t recv_acked; 00082 static u16_t tcplen; 00083 static u8_t flags; 00084 00085 static u8_t recv_flags; 00086 static struct pbuf *recv_data; 00087 00088 struct tcp_pcb *tcp_input_pcb; 00089 00090 /* Forward declarations. */ 00091 static err_t tcp_process(struct tcp_pcb *pcb); 00092 static void tcp_receive(struct tcp_pcb *pcb); 00093 static void tcp_parseopt(struct tcp_pcb *pcb); 00094 00095 static void tcp_listen_input(struct tcp_pcb_listen *pcb); 00096 static void tcp_timewait_input(struct tcp_pcb *pcb); 00097 00098 static int tcp_input_delayed_close(struct tcp_pcb *pcb); 00099 00100 #if LWIP_TCP_SACK_OUT 00101 static void tcp_add_sack(struct tcp_pcb *pcb, u32_t left, u32_t right); 00102 static void tcp_remove_sacks_lt(struct tcp_pcb *pcb, u32_t seq); 00103 #if defined(TCP_OOSEQ_BYTES_LIMIT) || defined(TCP_OOSEQ_PBUFS_LIMIT) 00104 static void tcp_remove_sacks_gt(struct tcp_pcb *pcb, u32_t seq); 00105 #endif /* TCP_OOSEQ_BYTES_LIMIT || TCP_OOSEQ_PBUFS_LIMIT */ 00106 #endif /* LWIP_TCP_SACK_OUT */ 00107 00108 /** 00109 * The initial input processing of TCP. It verifies the TCP header, demultiplexes 00110 * the segment between the PCBs and passes it on to tcp_process(), which implements 00111 * the TCP finite state machine. This function is called by the IP layer (in 00112 * ip_input()). 00113 * 00114 * @param p received TCP segment to process (p->payload pointing to the TCP header) 00115 * @param inp network interface on which this segment was received 00116 */ 00117 void 00118 tcp_input(struct pbuf *p, struct netif *inp) 00119 { 00120 struct tcp_pcb *pcb, *prev; 00121 struct tcp_pcb_listen *lpcb; 00122 #if SO_REUSE 00123 struct tcp_pcb *lpcb_prev = NULL; 00124 struct tcp_pcb_listen *lpcb_any = NULL; 00125 #endif /* SO_REUSE */ 00126 u8_t hdrlen_bytes; 00127 err_t err; 00128 00129 LWIP_UNUSED_ARG(inp); 00130 LWIP_ASSERT_CORE_LOCKED(); 00131 LWIP_ASSERT("tcp_input: invalid pbuf", p != NULL); 00132 00133 PERF_START; 00134 00135 TCP_STATS_INC(tcp.recv); 00136 MIB2_STATS_INC(mib2.tcpinsegs); 00137 00138 tcphdr = (struct tcp_hdr *)p->payload; 00139 00140 #if TCP_INPUT_DEBUG 00141 tcp_debug_print(tcphdr); 00142 #endif 00143 00144 /* Check that TCP header fits in payload */ 00145 if (p->len < TCP_HLEN) { 00146 /* drop short packets */ 00147 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet (%"U16_F" bytes) discarded\n", p->tot_len)); 00148 TCP_STATS_INC(tcp.lenerr); 00149 goto dropped; 00150 } 00151 00152 /* Don't even process incoming broadcasts/multicasts. */ 00153 if (ip_addr_isbroadcast(ip_current_dest_addr(), ip_current_netif()) || 00154 ip_addr_ismulticast(ip_current_dest_addr())) { 00155 TCP_STATS_INC(tcp.proterr); 00156 goto dropped; 00157 } 00158 00159 #if CHECKSUM_CHECK_TCP 00160 IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_TCP) { 00161 /* Verify TCP checksum. */ 00162 u16_t chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len, 00163 ip_current_src_addr(), ip_current_dest_addr()); 00164 if (chksum != 0) { 00165 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packet discarded due to failing checksum 0x%04"X16_F"\n", 00166 chksum)); 00167 tcp_debug_print(tcphdr); 00168 TCP_STATS_INC(tcp.chkerr); 00169 goto dropped; 00170 } 00171 } 00172 #endif /* CHECKSUM_CHECK_TCP */ 00173 00174 /* sanity-check header length */ 00175 hdrlen_bytes = TCPH_HDRLEN_BYTES(tcphdr); 00176 if ((hdrlen_bytes < TCP_HLEN) || (hdrlen_bytes > p->tot_len)) { 00177 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: invalid header length (%"U16_F")\n", (u16_t)hdrlen_bytes)); 00178 TCP_STATS_INC(tcp.lenerr); 00179 goto dropped; 00180 } 00181 00182 /* Move the payload pointer in the pbuf so that it points to the 00183 TCP data instead of the TCP header. */ 00184 tcphdr_optlen = (u16_t)(hdrlen_bytes - TCP_HLEN); 00185 tcphdr_opt2 = NULL; 00186 if (p->len >= hdrlen_bytes) { 00187 /* all options are in the first pbuf */ 00188 tcphdr_opt1len = tcphdr_optlen; 00189 pbuf_remove_header(p, hdrlen_bytes); /* cannot fail */ 00190 } else { 00191 u16_t opt2len; 00192 /* TCP header fits into first pbuf, options don't - data is in the next pbuf */ 00193 /* there must be a next pbuf, due to hdrlen_bytes sanity check above */ 00194 LWIP_ASSERT("p->next != NULL", p->next != NULL); 00195 00196 /* advance over the TCP header (cannot fail) */ 00197 pbuf_remove_header(p, TCP_HLEN); 00198 00199 /* determine how long the first and second parts of the options are */ 00200 tcphdr_opt1len = p->len; 00201 opt2len = (u16_t)(tcphdr_optlen - tcphdr_opt1len); 00202 00203 /* options continue in the next pbuf: set p to zero length and hide the 00204 options in the next pbuf (adjusting p->tot_len) */ 00205 pbuf_remove_header(p, tcphdr_opt1len); 00206 00207 /* check that the options fit in the second pbuf */ 00208 if (opt2len > p->next->len) { 00209 /* drop short packets */ 00210 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: options overflow second pbuf (%"U16_F" bytes)\n", p->next->len)); 00211 TCP_STATS_INC(tcp.lenerr); 00212 goto dropped; 00213 } 00214 00215 /* remember the pointer to the second part of the options */ 00216 tcphdr_opt2 = (u8_t *)p->next->payload; 00217 00218 /* advance p->next to point after the options, and manually 00219 adjust p->tot_len to keep it consistent with the changed p->next */ 00220 pbuf_remove_header(p->next, opt2len); 00221 p->tot_len = (u16_t)(p->tot_len - opt2len); 00222 00223 LWIP_ASSERT("p->len == 0", p->len == 0); 00224 LWIP_ASSERT("p->tot_len == p->next->tot_len", p->tot_len == p->next->tot_len); 00225 } 00226 00227 /* Convert fields in TCP header to host byte order. */ 00228 tcphdr->src = lwip_ntohs(tcphdr->src); 00229 tcphdr->dest = lwip_ntohs(tcphdr->dest); 00230 seqno = tcphdr->seqno = lwip_ntohl(tcphdr->seqno); 00231 ackno = tcphdr->ackno = lwip_ntohl(tcphdr->ackno); 00232 tcphdr->wnd = lwip_ntohs(tcphdr->wnd); 00233 00234 flags = TCPH_FLAGS(tcphdr); 00235 tcplen = p->tot_len; 00236 if (flags & (TCP_FIN | TCP_SYN)) { 00237 tcplen++; 00238 if (tcplen < p->tot_len) { 00239 /* u16_t overflow, cannot handle this */ 00240 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: length u16_t overflow, cannot handle this\n")); 00241 TCP_STATS_INC(tcp.lenerr); 00242 goto dropped; 00243 } 00244 } 00245 00246 /* Demultiplex an incoming segment. First, we check if it is destined 00247 for an active connection. */ 00248 prev = NULL; 00249 00250 for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { 00251 LWIP_ASSERT("tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED); 00252 LWIP_ASSERT("tcp_input: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT); 00253 LWIP_ASSERT("tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN); 00254 00255 /* check if PCB is bound to specific netif */ 00256 if ((pcb->netif_idx != NETIF_NO_INDEX) && 00257 (pcb->netif_idx != netif_get_index(ip_data.current_input_netif))) { 00258 prev = pcb; 00259 continue; 00260 } 00261 00262 if (pcb->remote_port == tcphdr->src && 00263 pcb->local_port == tcphdr->dest && 00264 ip_addr_cmp(&pcb->remote_ip, ip_current_src_addr()) && 00265 ip_addr_cmp(&pcb->local_ip, ip_current_dest_addr())) { 00266 /* Move this PCB to the front of the list so that subsequent 00267 lookups will be faster (we exploit locality in TCP segment 00268 arrivals). */ 00269 LWIP_ASSERT("tcp_input: pcb->next != pcb (before cache)", pcb->next != pcb); 00270 if (prev != NULL) { 00271 prev->next = pcb->next; 00272 pcb->next = tcp_active_pcbs; 00273 tcp_active_pcbs = pcb; 00274 } else { 00275 TCP_STATS_INC(tcp.cachehit); 00276 } 00277 LWIP_ASSERT("tcp_input: pcb->next != pcb (after cache)", pcb->next != pcb); 00278 break; 00279 } 00280 prev = pcb; 00281 } 00282 00283 if (pcb == NULL) { 00284 /* If it did not go to an active connection, we check the connections 00285 in the TIME-WAIT state. */ 00286 for (pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { 00287 LWIP_ASSERT("tcp_input: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT); 00288 00289 /* check if PCB is bound to specific netif */ 00290 if ((pcb->netif_idx != NETIF_NO_INDEX) && 00291 (pcb->netif_idx != netif_get_index(ip_data.current_input_netif))) { 00292 continue; 00293 } 00294 00295 if (pcb->remote_port == tcphdr->src && 00296 pcb->local_port == tcphdr->dest && 00297 ip_addr_cmp(&pcb->remote_ip, ip_current_src_addr()) && 00298 ip_addr_cmp(&pcb->local_ip, ip_current_dest_addr())) { 00299 /* We don't really care enough to move this PCB to the front 00300 of the list since we are not very likely to receive that 00301 many segments for connections in TIME-WAIT. */ 00302 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for TIME_WAITing connection.\n")); 00303 #ifdef LWIP_HOOK_TCP_INPACKET_PCB 00304 if (LWIP_HOOK_TCP_INPACKET_PCB(pcb, tcphdr, tcphdr_optlen, tcphdr_opt1len, 00305 tcphdr_opt2, p) == ERR_OK) 00306 #endif 00307 { 00308 tcp_timewait_input(pcb); 00309 } 00310 pbuf_free(p); 00311 return; 00312 } 00313 } 00314 00315 /* Finally, if we still did not get a match, we check all PCBs that 00316 are LISTENing for incoming connections. */ 00317 prev = NULL; 00318 for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { 00319 /* check if PCB is bound to specific netif */ 00320 if ((lpcb->netif_idx != NETIF_NO_INDEX) && 00321 (lpcb->netif_idx != netif_get_index(ip_data.current_input_netif))) { 00322 prev = (struct tcp_pcb *)lpcb; 00323 continue; 00324 } 00325 00326 if (lpcb->local_port == tcphdr->dest) { 00327 if (IP_IS_ANY_TYPE_VAL(lpcb->local_ip)) { 00328 /* found an ANY TYPE (IPv4/IPv6) match */ 00329 #if SO_REUSE 00330 lpcb_any = lpcb; 00331 lpcb_prev = prev; 00332 #else /* SO_REUSE */ 00333 break; 00334 #endif /* SO_REUSE */ 00335 } else if (IP_ADDR_PCB_VERSION_MATCH_EXACT(lpcb, ip_current_dest_addr())) { 00336 if (ip_addr_cmp(&lpcb->local_ip, ip_current_dest_addr())) { 00337 /* found an exact match */ 00338 break; 00339 } else if (ip_addr_isany(&lpcb->local_ip)) { 00340 /* found an ANY-match */ 00341 #if SO_REUSE 00342 lpcb_any = lpcb; 00343 lpcb_prev = prev; 00344 #else /* SO_REUSE */ 00345 break; 00346 #endif /* SO_REUSE */ 00347 } 00348 } 00349 } 00350 prev = (struct tcp_pcb *)lpcb; 00351 } 00352 #if SO_REUSE 00353 /* first try specific local IP */ 00354 if (lpcb == NULL) { 00355 /* only pass to ANY if no specific local IP has been found */ 00356 lpcb = lpcb_any; 00357 prev = lpcb_prev; 00358 } 00359 #endif /* SO_REUSE */ 00360 if (lpcb != NULL) { 00361 /* Move this PCB to the front of the list so that subsequent 00362 lookups will be faster (we exploit locality in TCP segment 00363 arrivals). */ 00364 if (prev != NULL) { 00365 ((struct tcp_pcb_listen *)prev)->next = lpcb->next; 00366 /* our successor is the remainder of the listening list */ 00367 lpcb->next = tcp_listen_pcbs.listen_pcbs; 00368 /* put this listening pcb at the head of the listening list */ 00369 tcp_listen_pcbs.listen_pcbs = lpcb; 00370 } else { 00371 TCP_STATS_INC(tcp.cachehit); 00372 } 00373 00374 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for LISTENing connection.\n")); 00375 #ifdef LWIP_HOOK_TCP_INPACKET_PCB 00376 if (LWIP_HOOK_TCP_INPACKET_PCB((struct tcp_pcb *)lpcb, tcphdr, tcphdr_optlen, 00377 tcphdr_opt1len, tcphdr_opt2, p) == ERR_OK) 00378 #endif 00379 { 00380 tcp_listen_input(lpcb); 00381 } 00382 pbuf_free(p); 00383 return; 00384 } 00385 } 00386 00387 #if TCP_INPUT_DEBUG 00388 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("+-+-+-+-+-+-+-+-+-+-+-+-+-+- tcp_input: flags ")); 00389 tcp_debug_print_flags(TCPH_FLAGS(tcphdr)); 00390 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n")); 00391 #endif /* TCP_INPUT_DEBUG */ 00392 00393 00394 #ifdef LWIP_HOOK_TCP_INPACKET_PCB 00395 if ((pcb != NULL) && LWIP_HOOK_TCP_INPACKET_PCB(pcb, tcphdr, tcphdr_optlen, 00396 tcphdr_opt1len, tcphdr_opt2, p) != ERR_OK) { 00397 pbuf_free(p); 00398 return; 00399 } 00400 #endif 00401 if (pcb != NULL) { 00402 /* The incoming segment belongs to a connection. */ 00403 #if TCP_INPUT_DEBUG 00404 tcp_debug_print_state(pcb->state); 00405 #endif /* TCP_INPUT_DEBUG */ 00406 00407 /* Set up a tcp_seg structure. */ 00408 inseg.next = NULL; 00409 inseg.len = p->tot_len; 00410 inseg.p = p; 00411 inseg.tcphdr = tcphdr; 00412 00413 recv_data = NULL; 00414 recv_flags = 0; 00415 recv_acked = 0; 00416 00417 if (flags & TCP_PSH) { 00418 p->flags |= PBUF_FLAG_PUSH; 00419 } 00420 00421 /* If there is data which was previously "refused" by upper layer */ 00422 if (pcb->refused_data != NULL) { 00423 if ((tcp_process_refused_data(pcb) == ERR_ABRT) || 00424 ((pcb->refused_data != NULL) && (tcplen > 0))) { 00425 /* pcb has been aborted or refused data is still refused and the new 00426 segment contains data */ 00427 if (pcb->rcv_ann_wnd == 0) { 00428 /* this is a zero-window probe, we respond to it with current RCV.NXT 00429 and drop the data segment */ 00430 tcp_send_empty_ack(pcb); 00431 } 00432 TCP_STATS_INC(tcp.drop); 00433 MIB2_STATS_INC(mib2.tcpinerrs); 00434 goto aborted; 00435 } 00436 } 00437 tcp_input_pcb = pcb; 00438 err = tcp_process(pcb); 00439 /* A return value of ERR_ABRT means that tcp_abort() was called 00440 and that the pcb has been freed. If so, we don't do anything. */ 00441 if (err != ERR_ABRT) { 00442 if (recv_flags & TF_RESET) { 00443 /* TF_RESET means that the connection was reset by the other 00444 end. We then call the error callback to inform the 00445 application that the connection is dead before we 00446 deallocate the PCB. */ 00447 TCP_EVENT_ERR(pcb->state, pcb->errf, pcb->callback_arg, ERR_RST); 00448 tcp_pcb_remove(&tcp_active_pcbs, pcb); 00449 tcp_free(pcb); 00450 } else { 00451 err = ERR_OK; 00452 /* If the application has registered a "sent" function to be 00453 called when new send buffer space is available, we call it 00454 now. */ 00455 if (recv_acked > 0) { 00456 u16_t acked16; 00457 #if LWIP_WND_SCALE 00458 /* recv_acked is u32_t but the sent callback only takes a u16_t, 00459 so we might have to call it multiple times. */ 00460 u32_t acked = recv_acked; 00461 while (acked > 0) { 00462 acked16 = (u16_t)LWIP_MIN(acked, 0xffffu); 00463 acked -= acked16; 00464 #else 00465 { 00466 acked16 = recv_acked; 00467 #endif 00468 TCP_EVENT_SENT(pcb, (u16_t)acked16, err); 00469 if (err == ERR_ABRT) { 00470 goto aborted; 00471 } 00472 } 00473 recv_acked = 0; 00474 } 00475 if (tcp_input_delayed_close(pcb)) { 00476 goto aborted; 00477 } 00478 #if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE 00479 while (recv_data != NULL) { 00480 struct pbuf *rest = NULL; 00481 pbuf_split_64k(recv_data, &rest); 00482 #else /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ 00483 if (recv_data != NULL) { 00484 #endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ 00485 00486 LWIP_ASSERT("pcb->refused_data == NULL", pcb->refused_data == NULL); 00487 if (pcb->flags & TF_RXCLOSED) { 00488 /* received data although already closed -> abort (send RST) to 00489 notify the remote host that not all data has been processed */ 00490 pbuf_free(recv_data); 00491 #if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE 00492 if (rest != NULL) { 00493 pbuf_free(rest); 00494 } 00495 #endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ 00496 tcp_abort(pcb); 00497 goto aborted; 00498 } 00499 00500 /* Notify application that data has been received. */ 00501 TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err); 00502 if (err == ERR_ABRT) { 00503 #if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE 00504 if (rest != NULL) { 00505 pbuf_free(rest); 00506 } 00507 #endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ 00508 goto aborted; 00509 } 00510 00511 /* If the upper layer can't receive this data, store it */ 00512 if (err != ERR_OK) { 00513 #if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE 00514 if (rest != NULL) { 00515 pbuf_cat(recv_data, rest); 00516 } 00517 #endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ 00518 pcb->refused_data = recv_data; 00519 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: keep incoming packet, because pcb is \"full\"\n")); 00520 #if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE 00521 break; 00522 } else { 00523 /* Upper layer received the data, go on with the rest if > 64K */ 00524 recv_data = rest; 00525 #endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ 00526 } 00527 } 00528 00529 /* If a FIN segment was received, we call the callback 00530 function with a NULL buffer to indicate EOF. */ 00531 if (recv_flags & TF_GOT_FIN) { 00532 if (pcb->refused_data != NULL) { 00533 /* Delay this if we have refused data. */ 00534 pcb->refused_data->flags |= PBUF_FLAG_TCP_FIN; 00535 } else { 00536 /* correct rcv_wnd as the application won't call tcp_recved() 00537 for the FIN's seqno */ 00538 if (pcb->rcv_wnd != TCP_WND_MAX(pcb)) { 00539 pcb->rcv_wnd++; 00540 } 00541 TCP_EVENT_CLOSED(pcb, err); 00542 if (err == ERR_ABRT) { 00543 goto aborted; 00544 } 00545 } 00546 } 00547 00548 tcp_input_pcb = NULL; 00549 if (tcp_input_delayed_close(pcb)) { 00550 goto aborted; 00551 } 00552 /* Try to send something out. */ 00553 tcp_output(pcb); 00554 #if TCP_INPUT_DEBUG 00555 #if TCP_DEBUG 00556 tcp_debug_print_state(pcb->state); 00557 #endif /* TCP_DEBUG */ 00558 #endif /* TCP_INPUT_DEBUG */ 00559 } 00560 } 00561 /* Jump target if pcb has been aborted in a callback (by calling tcp_abort()). 00562 Below this line, 'pcb' may not be dereferenced! */ 00563 aborted: 00564 tcp_input_pcb = NULL; 00565 recv_data = NULL; 00566 00567 /* give up our reference to inseg.p */ 00568 if (inseg.p != NULL) { 00569 pbuf_free(inseg.p); 00570 inseg.p = NULL; 00571 } 00572 } else { 00573 /* If no matching PCB was found, send a TCP RST (reset) to the 00574 sender. */ 00575 LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_input: no PCB match found, resetting.\n")); 00576 if (!(TCPH_FLAGS(tcphdr) & TCP_RST)) { 00577 TCP_STATS_INC(tcp.proterr); 00578 TCP_STATS_INC(tcp.drop); 00579 tcp_rst(NULL, ackno, seqno + tcplen, ip_current_dest_addr(), 00580 ip_current_src_addr(), tcphdr->dest, tcphdr->src); 00581 } 00582 pbuf_free(p); 00583 } 00584 00585 LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane()); 00586 PERF_STOP("tcp_input"); 00587 return; 00588 dropped: 00589 TCP_STATS_INC(tcp.drop); 00590 MIB2_STATS_INC(mib2.tcpinerrs); 00591 pbuf_free(p); 00592 } 00593 00594 /** Called from tcp_input to check for TF_CLOSED flag. This results in closing 00595 * and deallocating a pcb at the correct place to ensure noone references it 00596 * any more. 00597 * @returns 1 if the pcb has been closed and deallocated, 0 otherwise 00598 */ 00599 static int 00600 tcp_input_delayed_close(struct tcp_pcb *pcb) 00601 { 00602 LWIP_ASSERT("tcp_input_delayed_close: invalid pcb", pcb != NULL); 00603 00604 if (recv_flags & TF_CLOSED) { 00605 /* The connection has been closed and we will deallocate the 00606 PCB. */ 00607 if (!(pcb->flags & TF_RXCLOSED)) { 00608 /* Connection closed although the application has only shut down the 00609 tx side: call the PCB's err callback and indicate the closure to 00610 ensure the application doesn't continue using the PCB. */ 00611 TCP_EVENT_ERR(pcb->state, pcb->errf, pcb->callback_arg, ERR_CLSD); 00612 } 00613 tcp_pcb_remove(&tcp_active_pcbs, pcb); 00614 tcp_free(pcb); 00615 return 1; 00616 } 00617 return 0; 00618 } 00619 00620 /** 00621 * Called by tcp_input() when a segment arrives for a listening 00622 * connection (from tcp_input()). 00623 * 00624 * @param pcb the tcp_pcb_listen for which a segment arrived 00625 * 00626 * @note the segment which arrived is saved in global variables, therefore only the pcb 00627 * involved is passed as a parameter to this function 00628 */ 00629 static void 00630 tcp_listen_input(struct tcp_pcb_listen *pcb) 00631 { 00632 struct tcp_pcb *npcb; 00633 u32_t iss; 00634 err_t rc; 00635 00636 if (flags & TCP_RST) { 00637 /* An incoming RST should be ignored. Return. */ 00638 return; 00639 } 00640 00641 LWIP_ASSERT("tcp_listen_input: invalid pcb", pcb != NULL); 00642 00643 /* In the LISTEN state, we check for incoming SYN segments, 00644 creates a new PCB, and responds with a SYN|ACK. */ 00645 if (flags & TCP_ACK) { 00646 /* For incoming segments with the ACK flag set, respond with a 00647 RST. */ 00648 LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_listen_input: ACK in LISTEN, sending reset\n")); 00649 tcp_rst((const struct tcp_pcb *)pcb, ackno, seqno + tcplen, ip_current_dest_addr(), 00650 ip_current_src_addr(), tcphdr->dest, tcphdr->src); 00651 } else if (flags & TCP_SYN) { 00652 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection request %"U16_F" -> %"U16_F".\n", tcphdr->src, tcphdr->dest)); 00653 #if TCP_LISTEN_BACKLOG 00654 if (pcb->accepts_pending >= pcb->backlog) { 00655 LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: listen backlog exceeded for port %"U16_F"\n", tcphdr->dest)); 00656 return; 00657 } 00658 #endif /* TCP_LISTEN_BACKLOG */ 00659 npcb = tcp_alloc(pcb->prio); 00660 /* If a new PCB could not be created (probably due to lack of memory), 00661 we don't do anything, but rely on the sender will retransmit the 00662 SYN at a time when we have more memory available. */ 00663 if (npcb == NULL) { 00664 err_t err; 00665 LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: could not allocate PCB\n")); 00666 TCP_STATS_INC(tcp.memerr); 00667 TCP_EVENT_ACCEPT(pcb, NULL, pcb->callback_arg, ERR_MEM, err); 00668 LWIP_UNUSED_ARG(err); /* err not useful here */ 00669 return; 00670 } 00671 #if TCP_LISTEN_BACKLOG 00672 pcb->accepts_pending++; 00673 tcp_set_flags(npcb, TF_BACKLOGPEND); 00674 #endif /* TCP_LISTEN_BACKLOG */ 00675 /* Set up the new PCB. */ 00676 ip_addr_copy(npcb->local_ip, *ip_current_dest_addr()); 00677 ip_addr_copy(npcb->remote_ip, *ip_current_src_addr()); 00678 npcb->local_port = pcb->local_port; 00679 npcb->remote_port = tcphdr->src; 00680 npcb->state = SYN_RCVD; 00681 npcb->rcv_nxt = seqno + 1; 00682 npcb->rcv_ann_right_edge = npcb->rcv_nxt; 00683 iss = tcp_next_iss(npcb); 00684 npcb->snd_wl2 = iss; 00685 npcb->snd_nxt = iss; 00686 npcb->lastack = iss; 00687 npcb->snd_lbb = iss; 00688 npcb->snd_wl1 = seqno - 1;/* initialise to seqno-1 to force window update */ 00689 npcb->callback_arg = pcb->callback_arg; 00690 #if LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG 00691 npcb->listener = pcb; 00692 #endif /* LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG */ 00693 /* inherit socket options */ 00694 npcb->so_options = pcb->so_options & SOF_INHERITED; 00695 npcb->netif_idx = pcb->netif_idx; 00696 /* Register the new PCB so that we can begin receiving segments 00697 for it. */ 00698 TCP_REG_ACTIVE(npcb); 00699 00700 /* Parse any options in the SYN. */ 00701 tcp_parseopt(npcb); 00702 npcb->snd_wnd = tcphdr->wnd; 00703 npcb->snd_wnd_max = npcb->snd_wnd; 00704 00705 #if TCP_CALCULATE_EFF_SEND_MSS 00706 struct netif *netif; 00707 netif = netif_get_by_index(npcb->netif_idx); 00708 if(netif == NULL) { 00709 netif = ip_route(&npcb->local_ip, &npcb->remote_ip); 00710 } 00711 npcb->mss = tcp_eff_send_mss_netif(npcb->mss, netif, &npcb->remote_ip); 00712 #endif /* TCP_CALCULATE_EFF_SEND_MSS */ 00713 00714 MIB2_STATS_INC(mib2.tcppassiveopens); 00715 00716 #if LWIP_TCP_PCB_NUM_EXT_ARGS 00717 if (tcp_ext_arg_invoke_callbacks_passive_open(pcb, npcb) != ERR_OK) { 00718 tcp_abandon(npcb, 0); 00719 return; 00720 } 00721 #endif 00722 00723 /* Send a SYN|ACK together with the MSS option. */ 00724 rc = tcp_enqueue_flags(npcb, TCP_SYN | TCP_ACK); 00725 if (rc != ERR_OK) { 00726 tcp_abandon(npcb, 0); 00727 return; 00728 } 00729 tcp_output(npcb); 00730 } 00731 return; 00732 } 00733 00734 /** 00735 * Called by tcp_input() when a segment arrives for a connection in 00736 * TIME_WAIT. 00737 * 00738 * @param pcb the tcp_pcb for which a segment arrived 00739 * 00740 * @note the segment which arrived is saved in global variables, therefore only the pcb 00741 * involved is passed as a parameter to this function 00742 */ 00743 static void 00744 tcp_timewait_input(struct tcp_pcb *pcb) 00745 { 00746 /* RFC 1337: in TIME_WAIT, ignore RST and ACK FINs + any 'acceptable' segments */ 00747 /* RFC 793 3.9 Event Processing - Segment Arrives: 00748 * - first check sequence number - we skip that one in TIME_WAIT (always 00749 * acceptable since we only send ACKs) 00750 * - second check the RST bit (... return) */ 00751 if (flags & TCP_RST) { 00752 return; 00753 } 00754 00755 LWIP_ASSERT("tcp_timewait_input: invalid pcb", pcb != NULL); 00756 00757 /* - fourth, check the SYN bit, */ 00758 if (flags & TCP_SYN) { 00759 /* If an incoming segment is not acceptable, an acknowledgment 00760 should be sent in reply */ 00761 if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd)) { 00762 /* If the SYN is in the window it is an error, send a reset */ 00763 tcp_rst(pcb, ackno, seqno + tcplen, ip_current_dest_addr(), 00764 ip_current_src_addr(), tcphdr->dest, tcphdr->src); 00765 return; 00766 } 00767 } else if (flags & TCP_FIN) { 00768 /* - eighth, check the FIN bit: Remain in the TIME-WAIT state. 00769 Restart the 2 MSL time-wait timeout.*/ 00770 pcb->tmr = tcp_ticks; 00771 } 00772 00773 if ((tcplen > 0)) { 00774 /* Acknowledge data, FIN or out-of-window SYN */ 00775 tcp_ack_now(pcb); 00776 tcp_output(pcb); 00777 } 00778 return; 00779 } 00780 00781 /** 00782 * Implements the TCP state machine. Called by tcp_input. In some 00783 * states tcp_receive() is called to receive data. The tcp_seg 00784 * argument will be freed by the caller (tcp_input()) unless the 00785 * recv_data pointer in the pcb is set. 00786 * 00787 * @param pcb the tcp_pcb for which a segment arrived 00788 * 00789 * @note the segment which arrived is saved in global variables, therefore only the pcb 00790 * involved is passed as a parameter to this function 00791 */ 00792 static err_t 00793 tcp_process(struct tcp_pcb *pcb) 00794 { 00795 struct tcp_seg *rseg; 00796 u8_t acceptable = 0; 00797 err_t err; 00798 00799 err = ERR_OK; 00800 00801 LWIP_ASSERT("tcp_process: invalid pcb", pcb != NULL); 00802 00803 /* Process incoming RST segments. */ 00804 if (flags & TCP_RST) { 00805 /* First, determine if the reset is acceptable. */ 00806 if (pcb->state == SYN_SENT) { 00807 /* "In the SYN-SENT state (a RST received in response to an initial SYN), 00808 the RST is acceptable if the ACK field acknowledges the SYN." */ 00809 if (ackno == pcb->snd_nxt) { 00810 acceptable = 1; 00811 } 00812 } else { 00813 /* "In all states except SYN-SENT, all reset (RST) segments are validated 00814 by checking their SEQ-fields." */ 00815 if (seqno == pcb->rcv_nxt) { 00816 acceptable = 1; 00817 } else if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, 00818 pcb->rcv_nxt + pcb->rcv_wnd)) { 00819 /* If the sequence number is inside the window, we send a challenge ACK 00820 and wait for a re-send with matching sequence number. 00821 This follows RFC 5961 section 3.2 and addresses CVE-2004-0230 00822 (RST spoofing attack), which is present in RFC 793 RST handling. */ 00823 tcp_ack_now(pcb); 00824 } 00825 } 00826 00827 if (acceptable) { 00828 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: Connection RESET\n")); 00829 LWIP_ASSERT("tcp_input: pcb->state != CLOSED", pcb->state != CLOSED); 00830 recv_flags |= TF_RESET; 00831 tcp_clear_flags(pcb, TF_ACK_DELAY); 00832 return ERR_RST; 00833 } else { 00834 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n", 00835 seqno, pcb->rcv_nxt)); 00836 LWIP_DEBUGF(TCP_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n", 00837 seqno, pcb->rcv_nxt)); 00838 return ERR_OK; 00839 } 00840 } 00841 00842 if ((flags & TCP_SYN) && (pcb->state != SYN_SENT && pcb->state != SYN_RCVD)) { 00843 /* Cope with new connection attempt after remote end crashed */ 00844 tcp_ack_now(pcb); 00845 return ERR_OK; 00846 } 00847 00848 if ((pcb->flags & TF_RXCLOSED) == 0) { 00849 /* Update the PCB (in)activity timer unless rx is closed (see tcp_shutdown) */ 00850 pcb->tmr = tcp_ticks; 00851 } 00852 pcb->keep_cnt_sent = 0; 00853 pcb->persist_probe = 0; 00854 00855 tcp_parseopt(pcb); 00856 00857 /* Do different things depending on the TCP state. */ 00858 switch (pcb->state) { 00859 case SYN_SENT: 00860 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %"U32_F" pcb->snd_nxt %"U32_F" unacked %"U32_F"\n", ackno, 00861 pcb->snd_nxt, lwip_ntohl(pcb->unacked->tcphdr->seqno))); 00862 /* received SYN ACK with expected sequence number? */ 00863 if ((flags & TCP_ACK) && (flags & TCP_SYN) 00864 && (ackno == pcb->lastack + 1)) { 00865 pcb->rcv_nxt = seqno + 1; 00866 pcb->rcv_ann_right_edge = pcb->rcv_nxt; 00867 pcb->lastack = ackno; 00868 pcb->snd_wnd = tcphdr->wnd; 00869 pcb->snd_wnd_max = pcb->snd_wnd; 00870 pcb->snd_wl1 = seqno - 1; /* initialise to seqno - 1 to force window update */ 00871 pcb->state = ESTABLISHED; 00872 00873 #if TCP_CALCULATE_EFF_SEND_MSS 00874 struct netif *netif; 00875 netif = netif_get_by_index(pcb->netif_idx); 00876 if(netif == NULL) { 00877 netif = ip_route(&pcb->local_ip, &pcb->remote_ip); 00878 } 00879 pcb->mss = tcp_eff_send_mss_netif(pcb->mss, netif, &pcb->remote_ip); 00880 #endif /* TCP_CALCULATE_EFF_SEND_MSS */ 00881 00882 pcb->cwnd = LWIP_TCP_CALC_INITIAL_CWND(pcb->mss); 00883 LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_process (SENT): cwnd %"TCPWNDSIZE_F 00884 " ssthresh %"TCPWNDSIZE_F"\n", 00885 pcb->cwnd, pcb->ssthresh)); 00886 LWIP_ASSERT("pcb->snd_queuelen > 0", (pcb->snd_queuelen > 0)); 00887 --pcb->snd_queuelen; 00888 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_process: SYN-SENT --queuelen %"TCPWNDSIZE_F"\n", (tcpwnd_size_t)pcb->snd_queuelen)); 00889 rseg = pcb->unacked; 00890 if (rseg == NULL) { 00891 /* might happen if tcp_output fails in tcp_rexmit_rto() 00892 in which case the segment is on the unsent list */ 00893 rseg = pcb->unsent; 00894 LWIP_ASSERT("no segment to free", rseg != NULL); 00895 pcb->unsent = rseg->next; 00896 } else { 00897 pcb->unacked = rseg->next; 00898 } 00899 tcp_seg_free(rseg); 00900 00901 /* If there's nothing left to acknowledge, stop the retransmit 00902 timer, otherwise reset it to start again */ 00903 if (pcb->unacked == NULL) { 00904 pcb->rtime = -1; 00905 } else { 00906 pcb->rtime = 0; 00907 pcb->nrtx = 0; 00908 } 00909 00910 /* Call the user specified function to call when successfully 00911 * connected. */ 00912 TCP_EVENT_CONNECTED(pcb, ERR_OK, err); 00913 if (err == ERR_ABRT) { 00914 return ERR_ABRT; 00915 } 00916 tcp_ack_now(pcb); 00917 } 00918 /* received ACK? possibly a half-open connection */ 00919 else if (flags & TCP_ACK) { 00920 /* send a RST to bring the other side in a non-synchronized state. */ 00921 tcp_rst(pcb, ackno, seqno + tcplen, ip_current_dest_addr(), 00922 ip_current_src_addr(), tcphdr->dest, tcphdr->src); 00923 /* Resend SYN immediately (don't wait for rto timeout) to establish 00924 connection faster, but do not send more SYNs than we otherwise would 00925 have, or we might get caught in a loop on loopback interfaces. */ 00926 if (pcb->nrtx < TCP_SYNMAXRTX) { 00927 pcb->rtime = 0; 00928 tcp_rexmit_rto(pcb); 00929 } 00930 } 00931 break; 00932 case SYN_RCVD: 00933 if (flags & TCP_ACK) { 00934 /* expected ACK number? */ 00935 if (TCP_SEQ_BETWEEN(ackno, pcb->lastack + 1, pcb->snd_nxt)) { 00936 pcb->state = ESTABLISHED; 00937 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection established %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); 00938 #if LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG 00939 if (pcb->listener == NULL) { 00940 /* listen pcb might be closed by now */ 00941 err = ERR_VAL; 00942 } else 00943 #endif /* LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG */ 00944 { 00945 #if LWIP_CALLBACK_API 00946 LWIP_ASSERT("pcb->listener->accept != NULL", pcb->listener->accept != NULL); 00947 #endif 00948 tcp_backlog_accepted(pcb); 00949 /* Call the accept function. */ 00950 TCP_EVENT_ACCEPT(pcb->listener, pcb, pcb->callback_arg, ERR_OK, err); 00951 } 00952 if (err != ERR_OK) { 00953 /* If the accept function returns with an error, we abort 00954 * the connection. */ 00955 /* Already aborted? */ 00956 if (err != ERR_ABRT) { 00957 tcp_abort(pcb); 00958 } 00959 return ERR_ABRT; 00960 } 00961 /* If there was any data contained within this ACK, 00962 * we'd better pass it on to the application as well. */ 00963 tcp_receive(pcb); 00964 00965 /* Prevent ACK for SYN to generate a sent event */ 00966 if (recv_acked != 0) { 00967 recv_acked--; 00968 } 00969 00970 pcb->cwnd = LWIP_TCP_CALC_INITIAL_CWND(pcb->mss); 00971 LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_process (SYN_RCVD): cwnd %"TCPWNDSIZE_F 00972 " ssthresh %"TCPWNDSIZE_F"\n", 00973 pcb->cwnd, pcb->ssthresh)); 00974 00975 if (recv_flags & TF_GOT_FIN) { 00976 tcp_ack_now(pcb); 00977 pcb->state = CLOSE_WAIT; 00978 } 00979 } else { 00980 /* incorrect ACK number, send RST */ 00981 tcp_rst(pcb, ackno, seqno + tcplen, ip_current_dest_addr(), 00982 ip_current_src_addr(), tcphdr->dest, tcphdr->src); 00983 } 00984 } else if ((flags & TCP_SYN) && (seqno == pcb->rcv_nxt - 1)) { 00985 /* Looks like another copy of the SYN - retransmit our SYN-ACK */ 00986 tcp_rexmit(pcb); 00987 } 00988 break; 00989 case CLOSE_WAIT: 00990 /* FALLTHROUGH */ 00991 case ESTABLISHED: 00992 tcp_receive(pcb); 00993 if (recv_flags & TF_GOT_FIN) { /* passive close */ 00994 tcp_ack_now(pcb); 00995 pcb->state = CLOSE_WAIT; 00996 } 00997 break; 00998 case FIN_WAIT_1: 00999 tcp_receive(pcb); 01000 if (recv_flags & TF_GOT_FIN) { 01001 if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt) && 01002 pcb->unsent == NULL) { 01003 LWIP_DEBUGF(TCP_DEBUG, 01004 ("TCP connection closed: FIN_WAIT_1 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); 01005 tcp_ack_now(pcb); 01006 tcp_pcb_purge(pcb); 01007 TCP_RMV_ACTIVE(pcb); 01008 pcb->state = TIME_WAIT; 01009 TCP_REG(&tcp_tw_pcbs, pcb); 01010 } else { 01011 tcp_ack_now(pcb); 01012 pcb->state = CLOSING; 01013 } 01014 } else if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt) && 01015 pcb->unsent == NULL) { 01016 pcb->state = FIN_WAIT_2; 01017 } 01018 break; 01019 case FIN_WAIT_2: 01020 tcp_receive(pcb); 01021 if (recv_flags & TF_GOT_FIN) { 01022 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: FIN_WAIT_2 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); 01023 tcp_ack_now(pcb); 01024 tcp_pcb_purge(pcb); 01025 TCP_RMV_ACTIVE(pcb); 01026 pcb->state = TIME_WAIT; 01027 TCP_REG(&tcp_tw_pcbs, pcb); 01028 } 01029 break; 01030 case CLOSING: 01031 tcp_receive(pcb); 01032 if ((flags & TCP_ACK) && ackno == pcb->snd_nxt && pcb->unsent == NULL) { 01033 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: CLOSING %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); 01034 tcp_pcb_purge(pcb); 01035 TCP_RMV_ACTIVE(pcb); 01036 pcb->state = TIME_WAIT; 01037 TCP_REG(&tcp_tw_pcbs, pcb); 01038 } 01039 break; 01040 case LAST_ACK: 01041 tcp_receive(pcb); 01042 if ((flags & TCP_ACK) && ackno == pcb->snd_nxt && pcb->unsent == NULL) { 01043 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: LAST_ACK %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); 01044 /* bugfix #21699: don't set pcb->state to CLOSED here or we risk leaking segments */ 01045 recv_flags |= TF_CLOSED; 01046 } 01047 break; 01048 default: 01049 break; 01050 } 01051 return ERR_OK; 01052 } 01053 01054 #if TCP_QUEUE_OOSEQ 01055 /** 01056 * Insert segment into the list (segments covered with new one will be deleted) 01057 * 01058 * Called from tcp_receive() 01059 */ 01060 static void 01061 tcp_oos_insert_segment(struct tcp_seg *cseg, struct tcp_seg *next) 01062 { 01063 struct tcp_seg *old_seg; 01064 01065 LWIP_ASSERT("tcp_oos_insert_segment: invalid cseg", cseg != NULL); 01066 01067 if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) { 01068 /* received segment overlaps all following segments */ 01069 tcp_segs_free(next); 01070 next = NULL; 01071 } else { 01072 /* delete some following segments 01073 oos queue may have segments with FIN flag */ 01074 while (next && 01075 TCP_SEQ_GEQ((seqno + cseg->len), 01076 (next->tcphdr->seqno + next->len))) { 01077 /* cseg with FIN already processed */ 01078 if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) { 01079 TCPH_SET_FLAG(cseg->tcphdr, TCP_FIN); 01080 } 01081 old_seg = next; 01082 next = next->next; 01083 tcp_seg_free(old_seg); 01084 } 01085 if (next && 01086 TCP_SEQ_GT(seqno + cseg->len, next->tcphdr->seqno)) { 01087 /* We need to trim the incoming segment. */ 01088 cseg->len = (u16_t)(next->tcphdr->seqno - seqno); 01089 pbuf_realloc(cseg->p, cseg->len); 01090 } 01091 } 01092 cseg->next = next; 01093 } 01094 #endif /* TCP_QUEUE_OOSEQ */ 01095 01096 /** Remove segments from a list if the incoming ACK acknowledges them */ 01097 static struct tcp_seg * 01098 tcp_free_acked_segments(struct tcp_pcb *pcb, struct tcp_seg *seg_list, const char *dbg_list_name, 01099 struct tcp_seg *dbg_other_seg_list) 01100 { 01101 struct tcp_seg *next; 01102 u16_t clen; 01103 01104 LWIP_UNUSED_ARG(dbg_list_name); 01105 LWIP_UNUSED_ARG(dbg_other_seg_list); 01106 01107 while (seg_list != NULL && 01108 TCP_SEQ_LEQ(lwip_ntohl(seg_list->tcphdr->seqno) + 01109 TCP_TCPLEN(seg_list), ackno)) { 01110 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->%s\n", 01111 lwip_ntohl(seg_list->tcphdr->seqno), 01112 lwip_ntohl(seg_list->tcphdr->seqno) + TCP_TCPLEN(seg_list), 01113 dbg_list_name)); 01114 01115 next = seg_list; 01116 seg_list = seg_list->next; 01117 01118 clen = pbuf_clen(next->p); 01119 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"TCPWNDSIZE_F" ... ", 01120 (tcpwnd_size_t)pcb->snd_queuelen)); 01121 LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= clen)); 01122 01123 pcb->snd_queuelen = (u16_t)(pcb->snd_queuelen - clen); 01124 recv_acked = (tcpwnd_size_t)(recv_acked + next->len); 01125 tcp_seg_free(next); 01126 01127 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"TCPWNDSIZE_F" (after freeing %s)\n", 01128 (tcpwnd_size_t)pcb->snd_queuelen, 01129 dbg_list_name)); 01130 if (pcb->snd_queuelen != 0) { 01131 LWIP_ASSERT("tcp_receive: valid queue length", 01132 seg_list != NULL || dbg_other_seg_list != NULL); 01133 } 01134 } 01135 return seg_list; 01136 } 01137 01138 /** 01139 * Called by tcp_process. Checks if the given segment is an ACK for outstanding 01140 * data, and if so frees the memory of the buffered data. Next, it places the 01141 * segment on any of the receive queues (pcb->recved or pcb->ooseq). If the segment 01142 * is buffered, the pbuf is referenced by pbuf_ref so that it will not be freed until 01143 * it has been removed from the buffer. 01144 * 01145 * If the incoming segment constitutes an ACK for a segment that was used for RTT 01146 * estimation, the RTT is estimated here as well. 01147 * 01148 * Called from tcp_process(). 01149 */ 01150 static void 01151 tcp_receive(struct tcp_pcb *pcb) 01152 { 01153 s16_t m; 01154 u32_t right_wnd_edge; 01155 int found_dupack = 0; 01156 01157 LWIP_ASSERT("tcp_receive: invalid pcb", pcb != NULL); 01158 LWIP_ASSERT("tcp_receive: wrong state", pcb->state >= ESTABLISHED); 01159 01160 if (flags & TCP_ACK) { 01161 right_wnd_edge = pcb->snd_wnd + pcb->snd_wl2; 01162 01163 /* Update window. */ 01164 if (TCP_SEQ_LT(pcb->snd_wl1, seqno) || 01165 (pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) || 01166 (pcb->snd_wl2 == ackno && (u32_t)SND_WND_SCALE(pcb, tcphdr->wnd) > pcb->snd_wnd)) { 01167 pcb->snd_wnd = SND_WND_SCALE(pcb, tcphdr->wnd); 01168 /* keep track of the biggest window announced by the remote host to calculate 01169 the maximum segment size */ 01170 if (pcb->snd_wnd_max < pcb->snd_wnd) { 01171 pcb->snd_wnd_max = pcb->snd_wnd; 01172 } 01173 pcb->snd_wl1 = seqno; 01174 pcb->snd_wl2 = ackno; 01175 LWIP_DEBUGF(TCP_WND_DEBUG, ("tcp_receive: window update %"TCPWNDSIZE_F"\n", pcb->snd_wnd)); 01176 #if TCP_WND_DEBUG 01177 } else { 01178 if (pcb->snd_wnd != (tcpwnd_size_t)SND_WND_SCALE(pcb, tcphdr->wnd)) { 01179 LWIP_DEBUGF(TCP_WND_DEBUG, 01180 ("tcp_receive: no window update lastack %"U32_F" ackno %" 01181 U32_F" wl1 %"U32_F" seqno %"U32_F" wl2 %"U32_F"\n", 01182 pcb->lastack, ackno, pcb->snd_wl1, seqno, pcb->snd_wl2)); 01183 } 01184 #endif /* TCP_WND_DEBUG */ 01185 } 01186 01187 /* (From Stevens TCP/IP Illustrated Vol II, p970.) Its only a 01188 * duplicate ack if: 01189 * 1) It doesn't ACK new data 01190 * 2) length of received packet is zero (i.e. no payload) 01191 * 3) the advertised window hasn't changed 01192 * 4) There is outstanding unacknowledged data (retransmission timer running) 01193 * 5) The ACK is == biggest ACK sequence number so far seen (snd_una) 01194 * 01195 * If it passes all five, should process as a dupack: 01196 * a) dupacks < 3: do nothing 01197 * b) dupacks == 3: fast retransmit 01198 * c) dupacks > 3: increase cwnd 01199 * 01200 * If it only passes 1-3, should reset dupack counter (and add to 01201 * stats, which we don't do in lwIP) 01202 * 01203 * If it only passes 1, should reset dupack counter 01204 * 01205 */ 01206 01207 /* Clause 1 */ 01208 if (TCP_SEQ_LEQ(ackno, pcb->lastack)) { 01209 /* Clause 2 */ 01210 if (tcplen == 0) { 01211 /* Clause 3 */ 01212 if (pcb->snd_wl2 + pcb->snd_wnd == right_wnd_edge) { 01213 /* Clause 4 */ 01214 if (pcb->rtime >= 0) { 01215 /* Clause 5 */ 01216 if (pcb->lastack == ackno) { 01217 found_dupack = 1; 01218 if ((u8_t)(pcb->dupacks + 1) > pcb->dupacks) { 01219 ++pcb->dupacks; 01220 } 01221 if (pcb->dupacks > 3) { 01222 /* Inflate the congestion window */ 01223 TCP_WND_INC(pcb->cwnd, pcb->mss); 01224 } 01225 if (pcb->dupacks >= 3) { 01226 /* Do fast retransmit (checked via TF_INFR, not via dupacks count) */ 01227 tcp_rexmit_fast(pcb); 01228 } 01229 } 01230 } 01231 } 01232 } 01233 /* If Clause (1) or more is true, but not a duplicate ack, reset 01234 * count of consecutive duplicate acks */ 01235 if (!found_dupack) { 01236 pcb->dupacks = 0; 01237 } 01238 } else if (TCP_SEQ_BETWEEN(ackno, pcb->lastack + 1, pcb->snd_nxt)) { 01239 /* We come here when the ACK acknowledges new data. */ 01240 tcpwnd_size_t acked; 01241 01242 /* Reset the "IN Fast Retransmit" flag, since we are no longer 01243 in fast retransmit. Also reset the congestion window to the 01244 slow start threshold. */ 01245 if (pcb->flags & TF_INFR) { 01246 tcp_clear_flags(pcb, TF_INFR); 01247 pcb->cwnd = pcb->ssthresh; 01248 pcb->bytes_acked = 0; 01249 } 01250 01251 /* Reset the number of retransmissions. */ 01252 pcb->nrtx = 0; 01253 01254 /* Reset the retransmission time-out. */ 01255 pcb->rto = (s16_t)((pcb->sa >> 3) + pcb->sv); 01256 01257 /* Record how much data this ACK acks */ 01258 acked = (tcpwnd_size_t)(ackno - pcb->lastack); 01259 01260 /* Reset the fast retransmit variables. */ 01261 pcb->dupacks = 0; 01262 pcb->lastack = ackno; 01263 01264 /* Update the congestion control variables (cwnd and 01265 ssthresh). */ 01266 if (pcb->state >= ESTABLISHED) { 01267 if (pcb->cwnd < pcb->ssthresh) { 01268 tcpwnd_size_t increase; 01269 /* limit to 1 SMSS segment during period following RTO */ 01270 u8_t num_seg = (pcb->flags & TF_RTO) ? 1 : 2; 01271 /* RFC 3465, section 2.2 Slow Start */ 01272 increase = LWIP_MIN(acked, (tcpwnd_size_t)(num_seg * pcb->mss)); 01273 TCP_WND_INC(pcb->cwnd, increase); 01274 LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: slow start cwnd %"TCPWNDSIZE_F"\n", pcb->cwnd)); 01275 } else { 01276 /* RFC 3465, section 2.1 Congestion Avoidance */ 01277 TCP_WND_INC(pcb->bytes_acked, acked); 01278 if (pcb->bytes_acked >= pcb->cwnd) { 01279 pcb->bytes_acked = (tcpwnd_size_t)(pcb->bytes_acked - pcb->cwnd); 01280 TCP_WND_INC(pcb->cwnd, pcb->mss); 01281 } 01282 LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: congestion avoidance cwnd %"TCPWNDSIZE_F"\n", pcb->cwnd)); 01283 } 01284 } 01285 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: ACK for %"U32_F", unacked->seqno %"U32_F":%"U32_F"\n", 01286 ackno, 01287 pcb->unacked != NULL ? 01288 lwip_ntohl(pcb->unacked->tcphdr->seqno) : 0, 01289 pcb->unacked != NULL ? 01290 lwip_ntohl(pcb->unacked->tcphdr->seqno) + TCP_TCPLEN(pcb->unacked) : 0)); 01291 01292 /* Remove segment from the unacknowledged list if the incoming 01293 ACK acknowledges them. */ 01294 pcb->unacked = tcp_free_acked_segments(pcb, pcb->unacked, "unacked", pcb->unsent); 01295 /* We go through the ->unsent list to see if any of the segments 01296 on the list are acknowledged by the ACK. This may seem 01297 strange since an "unsent" segment shouldn't be acked. The 01298 rationale is that lwIP puts all outstanding segments on the 01299 ->unsent list after a retransmission, so these segments may 01300 in fact have been sent once. */ 01301 pcb->unsent = tcp_free_acked_segments(pcb, pcb->unsent, "unsent", pcb->unacked); 01302 01303 /* If there's nothing left to acknowledge, stop the retransmit 01304 timer, otherwise reset it to start again */ 01305 if (pcb->unacked == NULL) { 01306 pcb->rtime = -1; 01307 } else { 01308 pcb->rtime = 0; 01309 } 01310 01311 pcb->polltmr = 0; 01312 01313 #if TCP_OVERSIZE 01314 if (pcb->unsent == NULL) { 01315 pcb->unsent_oversize = 0; 01316 } 01317 #endif /* TCP_OVERSIZE */ 01318 01319 #if LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS 01320 if (ip_current_is_v6()) { 01321 /* Inform neighbor reachability of forward progress. */ 01322 nd6_reachability_hint(ip6_current_src_addr()); 01323 } 01324 #endif /* LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS*/ 01325 01326 pcb->snd_buf = (tcpwnd_size_t)(pcb->snd_buf + recv_acked); 01327 /* check if this ACK ends our retransmission of in-flight data */ 01328 if (pcb->flags & TF_RTO) { 01329 /* RTO is done if 01330 1) both queues are empty or 01331 2) unacked is empty and unsent head contains data not part of RTO or 01332 3) unacked head contains data not part of RTO */ 01333 if (pcb->unacked == NULL) { 01334 if ((pcb->unsent == NULL) || 01335 (TCP_SEQ_LEQ(pcb->rto_end, lwip_ntohl(pcb->unsent->tcphdr->seqno)))) { 01336 tcp_clear_flags(pcb, TF_RTO); 01337 } 01338 } else if (TCP_SEQ_LEQ(pcb->rto_end, lwip_ntohl(pcb->unacked->tcphdr->seqno))) { 01339 tcp_clear_flags(pcb, TF_RTO); 01340 } 01341 } 01342 /* End of ACK for new data processing. */ 01343 } else { 01344 /* Out of sequence ACK, didn't really ack anything */ 01345 tcp_send_empty_ack(pcb); 01346 } 01347 01348 LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: pcb->rttest %"U32_F" rtseq %"U32_F" ackno %"U32_F"\n", 01349 pcb->rttest, pcb->rtseq, ackno)); 01350 01351 /* RTT estimation calculations. This is done by checking if the 01352 incoming segment acknowledges the segment we use to take a 01353 round-trip time measurement. */ 01354 if (pcb->rttest && TCP_SEQ_LT(pcb->rtseq, ackno)) { 01355 /* diff between this shouldn't exceed 32K since this are tcp timer ticks 01356 and a round-trip shouldn't be that long... */ 01357 m = (s16_t)(tcp_ticks - pcb->rttest); 01358 01359 LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: experienced rtt %"U16_F" ticks (%"U16_F" msec).\n", 01360 m, (u16_t)(m * TCP_SLOW_INTERVAL))); 01361 01362 /* This is taken directly from VJs original code in his paper */ 01363 m = (s16_t)(m - (pcb->sa >> 3)); 01364 pcb->sa = (s16_t)(pcb->sa + m); 01365 if (m < 0) { 01366 m = (s16_t) - m; 01367 } 01368 m = (s16_t)(m - (pcb->sv >> 2)); 01369 pcb->sv = (s16_t)(pcb->sv + m); 01370 pcb->rto = (s16_t)((pcb->sa >> 3) + pcb->sv); 01371 01372 LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: RTO %"U16_F" (%"U16_F" milliseconds)\n", 01373 pcb->rto, (u16_t)(pcb->rto * TCP_SLOW_INTERVAL))); 01374 01375 pcb->rttest = 0; 01376 } 01377 } 01378 01379 /* If the incoming segment contains data, we must process it 01380 further unless the pcb already received a FIN. 01381 (RFC 793, chapter 3.9, "SEGMENT ARRIVES" in states CLOSE-WAIT, CLOSING, 01382 LAST-ACK and TIME-WAIT: "Ignore the segment text.") */ 01383 if ((tcplen > 0) && (pcb->state < CLOSE_WAIT)) { 01384 /* This code basically does three things: 01385 01386 +) If the incoming segment contains data that is the next 01387 in-sequence data, this data is passed to the application. This 01388 might involve trimming the first edge of the data. The rcv_nxt 01389 variable and the advertised window are adjusted. 01390 01391 +) If the incoming segment has data that is above the next 01392 sequence number expected (->rcv_nxt), the segment is placed on 01393 the ->ooseq queue. This is done by finding the appropriate 01394 place in the ->ooseq queue (which is ordered by sequence 01395 number) and trim the segment in both ends if needed. An 01396 immediate ACK is sent to indicate that we received an 01397 out-of-sequence segment. 01398 01399 +) Finally, we check if the first segment on the ->ooseq queue 01400 now is in sequence (i.e., if rcv_nxt >= ooseq->seqno). If 01401 rcv_nxt > ooseq->seqno, we must trim the first edge of the 01402 segment on ->ooseq before we adjust rcv_nxt. The data in the 01403 segments that are now on sequence are chained onto the 01404 incoming segment so that we only need to call the application 01405 once. 01406 */ 01407 01408 /* First, we check if we must trim the first edge. We have to do 01409 this if the sequence number of the incoming segment is less 01410 than rcv_nxt, and the sequence number plus the length of the 01411 segment is larger than rcv_nxt. */ 01412 /* if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)) { 01413 if (TCP_SEQ_LT(pcb->rcv_nxt, seqno + tcplen)) {*/ 01414 if (TCP_SEQ_BETWEEN(pcb->rcv_nxt, seqno + 1, seqno + tcplen - 1)) { 01415 /* Trimming the first edge is done by pushing the payload 01416 pointer in the pbuf downwards. This is somewhat tricky since 01417 we do not want to discard the full contents of the pbuf up to 01418 the new starting point of the data since we have to keep the 01419 TCP header which is present in the first pbuf in the chain. 01420 01421 What is done is really quite a nasty hack: the first pbuf in 01422 the pbuf chain is pointed to by inseg.p. Since we need to be 01423 able to deallocate the whole pbuf, we cannot change this 01424 inseg.p pointer to point to any of the later pbufs in the 01425 chain. Instead, we point the ->payload pointer in the first 01426 pbuf to data in one of the later pbufs. We also set the 01427 inseg.data pointer to point to the right place. This way, the 01428 ->p pointer will still point to the first pbuf, but the 01429 ->p->payload pointer will point to data in another pbuf. 01430 01431 After we are done with adjusting the pbuf pointers we must 01432 adjust the ->data pointer in the seg and the segment 01433 length.*/ 01434 01435 struct pbuf *p = inseg.p; 01436 u32_t off32 = pcb->rcv_nxt - seqno; 01437 u16_t new_tot_len, off; 01438 LWIP_ASSERT("inseg.p != NULL", inseg.p); 01439 LWIP_ASSERT("insane offset!", (off32 < 0xffff)); 01440 off = (u16_t)off32; 01441 LWIP_ASSERT("pbuf too short!", (((s32_t)inseg.p->tot_len) >= off)); 01442 inseg.len -= off; 01443 new_tot_len = (u16_t)(inseg.p->tot_len - off); 01444 while (p->len < off) { 01445 off -= p->len; 01446 /* all pbufs up to and including this one have len==0, so tot_len is equal */ 01447 p->tot_len = new_tot_len; 01448 p->len = 0; 01449 p = p->next; 01450 } 01451 /* cannot fail... */ 01452 pbuf_remove_header(p, off); 01453 inseg.tcphdr->seqno = seqno = pcb->rcv_nxt; 01454 } else { 01455 if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)) { 01456 /* the whole segment is < rcv_nxt */ 01457 /* must be a duplicate of a packet that has already been correctly handled */ 01458 01459 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: duplicate seqno %"U32_F"\n", seqno)); 01460 tcp_ack_now(pcb); 01461 } 01462 } 01463 01464 /* The sequence number must be within the window (above rcv_nxt 01465 and below rcv_nxt + rcv_wnd) in order to be further 01466 processed. */ 01467 if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, 01468 pcb->rcv_nxt + pcb->rcv_wnd - 1)) { 01469 if (pcb->rcv_nxt == seqno) { 01470 /* The incoming segment is the next in sequence. We check if 01471 we have to trim the end of the segment and update rcv_nxt 01472 and pass the data to the application. */ 01473 tcplen = TCP_TCPLEN(&inseg); 01474 01475 if (tcplen > pcb->rcv_wnd) { 01476 LWIP_DEBUGF(TCP_INPUT_DEBUG, 01477 ("tcp_receive: other end overran receive window" 01478 "seqno %"U32_F" len %"U16_F" right edge %"U32_F"\n", 01479 seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd)); 01480 if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) { 01481 /* Must remove the FIN from the header as we're trimming 01482 * that byte of sequence-space from the packet */ 01483 TCPH_FLAGS_SET(inseg.tcphdr, TCPH_FLAGS(inseg.tcphdr) & ~(unsigned int)TCP_FIN); 01484 } 01485 /* Adjust length of segment to fit in the window. */ 01486 TCPWND_CHECK16(pcb->rcv_wnd); 01487 inseg.len = (u16_t)pcb->rcv_wnd; 01488 if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) { 01489 inseg.len -= 1; 01490 } 01491 pbuf_realloc(inseg.p, inseg.len); 01492 tcplen = TCP_TCPLEN(&inseg); 01493 LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n", 01494 (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd)); 01495 } 01496 #if TCP_QUEUE_OOSEQ 01497 /* Received in-sequence data, adjust ooseq data if: 01498 - FIN has been received or 01499 - inseq overlaps with ooseq */ 01500 if (pcb->ooseq != NULL) { 01501 if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) { 01502 LWIP_DEBUGF(TCP_INPUT_DEBUG, 01503 ("tcp_receive: received in-order FIN, binning ooseq queue\n")); 01504 /* Received in-order FIN means anything that was received 01505 * out of order must now have been received in-order, so 01506 * bin the ooseq queue */ 01507 while (pcb->ooseq != NULL) { 01508 struct tcp_seg *old_ooseq = pcb->ooseq; 01509 pcb->ooseq = pcb->ooseq->next; 01510 tcp_seg_free(old_ooseq); 01511 } 01512 } else { 01513 struct tcp_seg *next = pcb->ooseq; 01514 /* Remove all segments on ooseq that are covered by inseg already. 01515 * FIN is copied from ooseq to inseg if present. */ 01516 while (next && 01517 TCP_SEQ_GEQ(seqno + tcplen, 01518 next->tcphdr->seqno + next->len)) { 01519 struct tcp_seg *tmp; 01520 /* inseg cannot have FIN here (already processed above) */ 01521 if ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0 && 01522 (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) == 0) { 01523 TCPH_SET_FLAG(inseg.tcphdr, TCP_FIN); 01524 tcplen = TCP_TCPLEN(&inseg); 01525 } 01526 tmp = next; 01527 next = next->next; 01528 tcp_seg_free(tmp); 01529 } 01530 /* Now trim right side of inseg if it overlaps with the first 01531 * segment on ooseq */ 01532 if (next && 01533 TCP_SEQ_GT(seqno + tcplen, 01534 next->tcphdr->seqno)) { 01535 /* inseg cannot have FIN here (already processed above) */ 01536 inseg.len = (u16_t)(next->tcphdr->seqno - seqno); 01537 if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) { 01538 inseg.len -= 1; 01539 } 01540 pbuf_realloc(inseg.p, inseg.len); 01541 tcplen = TCP_TCPLEN(&inseg); 01542 LWIP_ASSERT("tcp_receive: segment not trimmed correctly to ooseq queue\n", 01543 (seqno + tcplen) == next->tcphdr->seqno); 01544 } 01545 pcb->ooseq = next; 01546 } 01547 } 01548 #endif /* TCP_QUEUE_OOSEQ */ 01549 01550 pcb->rcv_nxt = seqno + tcplen; 01551 01552 /* Update the receiver's (our) window. */ 01553 LWIP_ASSERT("tcp_receive: tcplen > rcv_wnd\n", pcb->rcv_wnd >= tcplen); 01554 pcb->rcv_wnd -= tcplen; 01555 01556 tcp_update_rcv_ann_wnd(pcb); 01557 01558 /* If there is data in the segment, we make preparations to 01559 pass this up to the application. The ->recv_data variable 01560 is used for holding the pbuf that goes to the 01561 application. The code for reassembling out-of-sequence data 01562 chains its data on this pbuf as well. 01563 01564 If the segment was a FIN, we set the TF_GOT_FIN flag that will 01565 be used to indicate to the application that the remote side has 01566 closed its end of the connection. */ 01567 if (inseg.p->tot_len > 0) { 01568 recv_data = inseg.p; 01569 /* Since this pbuf now is the responsibility of the 01570 application, we delete our reference to it so that we won't 01571 (mistakingly) deallocate it. */ 01572 inseg.p = NULL; 01573 } 01574 if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) { 01575 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN.\n")); 01576 recv_flags |= TF_GOT_FIN; 01577 } 01578 01579 #if TCP_QUEUE_OOSEQ 01580 /* We now check if we have segments on the ->ooseq queue that 01581 are now in sequence. */ 01582 while (pcb->ooseq != NULL && 01583 pcb->ooseq->tcphdr->seqno == pcb->rcv_nxt) { 01584 01585 struct tcp_seg *cseg = pcb->ooseq; 01586 seqno = pcb->ooseq->tcphdr->seqno; 01587 01588 pcb->rcv_nxt += TCP_TCPLEN(cseg); 01589 LWIP_ASSERT("tcp_receive: ooseq tcplen > rcv_wnd\n", 01590 pcb->rcv_wnd >= TCP_TCPLEN(cseg)); 01591 pcb->rcv_wnd -= TCP_TCPLEN(cseg); 01592 01593 tcp_update_rcv_ann_wnd(pcb); 01594 01595 if (cseg->p->tot_len > 0) { 01596 /* Chain this pbuf onto the pbuf that we will pass to 01597 the application. */ 01598 /* With window scaling, this can overflow recv_data->tot_len, but 01599 that's not a problem since we explicitly fix that before passing 01600 recv_data to the application. */ 01601 if (recv_data) { 01602 pbuf_cat(recv_data, cseg->p); 01603 } else { 01604 recv_data = cseg->p; 01605 } 01606 cseg->p = NULL; 01607 } 01608 if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) { 01609 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN.\n")); 01610 recv_flags |= TF_GOT_FIN; 01611 if (pcb->state == ESTABLISHED) { /* force passive close or we can move to active close */ 01612 pcb->state = CLOSE_WAIT; 01613 } 01614 } 01615 01616 pcb->ooseq = cseg->next; 01617 tcp_seg_free(cseg); 01618 } 01619 #if LWIP_TCP_SACK_OUT 01620 if (pcb->flags & TF_SACK) { 01621 if (pcb->ooseq != NULL) { 01622 /* Some segments may have been removed from ooseq, let's remove all SACKs that 01623 describe anything before the new beginning of that list. */ 01624 tcp_remove_sacks_lt(pcb, pcb->ooseq->tcphdr->seqno); 01625 } else if (LWIP_TCP_SACK_VALID(pcb, 0)) { 01626 /* ooseq has been cleared. Nothing to SACK */ 01627 memset(pcb->rcv_sacks, 0, sizeof(pcb->rcv_sacks)); 01628 } 01629 } 01630 #endif /* LWIP_TCP_SACK_OUT */ 01631 #endif /* TCP_QUEUE_OOSEQ */ 01632 01633 01634 /* Acknowledge the segment(s). */ 01635 tcp_ack(pcb); 01636 01637 #if LWIP_TCP_SACK_OUT 01638 if (LWIP_TCP_SACK_VALID(pcb, 0)) { 01639 /* Normally the ACK for the data received could be piggy-backed on a data packet, 01640 but lwIP currently does not support including SACKs in data packets. So we force 01641 it to respond with an empty ACK packet (only if there is at least one SACK to be sent). 01642 NOTE: tcp_send_empty_ack() on success clears the ACK flags (set by tcp_ack()) */ 01643 tcp_send_empty_ack(pcb); 01644 } 01645 #endif /* LWIP_TCP_SACK_OUT */ 01646 01647 #if LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS 01648 if (ip_current_is_v6()) { 01649 /* Inform neighbor reachability of forward progress. */ 01650 nd6_reachability_hint(ip6_current_src_addr()); 01651 } 01652 #endif /* LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS*/ 01653 01654 } else { 01655 /* We get here if the incoming segment is out-of-sequence. */ 01656 01657 #if TCP_QUEUE_OOSEQ 01658 /* We queue the segment on the ->ooseq queue. */ 01659 if (pcb->ooseq == NULL) { 01660 pcb->ooseq = tcp_seg_copy(&inseg); 01661 #if LWIP_TCP_SACK_OUT 01662 if (pcb->flags & TF_SACK) { 01663 /* All the SACKs should be invalid, so we can simply store the most recent one: */ 01664 pcb->rcv_sacks[0].left = seqno; 01665 pcb->rcv_sacks[0].right = seqno + inseg.len; 01666 } 01667 #endif /* LWIP_TCP_SACK_OUT */ 01668 } else { 01669 /* If the queue is not empty, we walk through the queue and 01670 try to find a place where the sequence number of the 01671 incoming segment is between the sequence numbers of the 01672 previous and the next segment on the ->ooseq queue. That is 01673 the place where we put the incoming segment. If needed, we 01674 trim the second edges of the previous and the incoming 01675 segment so that it will fit into the sequence. 01676 01677 If the incoming segment has the same sequence number as a 01678 segment on the ->ooseq queue, we discard the segment that 01679 contains less data. */ 01680 01681 #if LWIP_TCP_SACK_OUT 01682 /* This is the left edge of the lowest possible SACK range. 01683 It may start before the newly received segment (possibly adjusted below). */ 01684 u32_t sackbeg = TCP_SEQ_LT(seqno, pcb->ooseq->tcphdr->seqno) ? seqno : pcb->ooseq->tcphdr->seqno; 01685 #endif /* LWIP_TCP_SACK_OUT */ 01686 struct tcp_seg *next, *prev = NULL; 01687 for (next = pcb->ooseq; next != NULL; next = next->next) { 01688 if (seqno == next->tcphdr->seqno) { 01689 /* The sequence number of the incoming segment is the 01690 same as the sequence number of the segment on 01691 ->ooseq. We check the lengths to see which one to 01692 discard. */ 01693 if (inseg.len > next->len) { 01694 /* The incoming segment is larger than the old 01695 segment. We replace some segments with the new 01696 one. */ 01697 struct tcp_seg *cseg = tcp_seg_copy(&inseg); 01698 if (cseg != NULL) { 01699 if (prev != NULL) { 01700 prev->next = cseg; 01701 } else { 01702 pcb->ooseq = cseg; 01703 } 01704 tcp_oos_insert_segment(cseg, next); 01705 } 01706 break; 01707 } else { 01708 /* Either the lengths are the same or the incoming 01709 segment was smaller than the old one; in either 01710 case, we ditch the incoming segment. */ 01711 break; 01712 } 01713 } else { 01714 if (prev == NULL) { 01715 if (TCP_SEQ_LT(seqno, next->tcphdr->seqno)) { 01716 /* The sequence number of the incoming segment is lower 01717 than the sequence number of the first segment on the 01718 queue. We put the incoming segment first on the 01719 queue. */ 01720 struct tcp_seg *cseg = tcp_seg_copy(&inseg); 01721 if (cseg != NULL) { 01722 pcb->ooseq = cseg; 01723 tcp_oos_insert_segment(cseg, next); 01724 } 01725 break; 01726 } 01727 } else { 01728 /*if (TCP_SEQ_LT(prev->tcphdr->seqno, seqno) && 01729 TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {*/ 01730 if (TCP_SEQ_BETWEEN(seqno, prev->tcphdr->seqno + 1, next->tcphdr->seqno - 1)) { 01731 /* The sequence number of the incoming segment is in 01732 between the sequence numbers of the previous and 01733 the next segment on ->ooseq. We trim trim the previous 01734 segment, delete next segments that included in received segment 01735 and trim received, if needed. */ 01736 struct tcp_seg *cseg = tcp_seg_copy(&inseg); 01737 if (cseg != NULL) { 01738 if (TCP_SEQ_GT(prev->tcphdr->seqno + prev->len, seqno)) { 01739 /* We need to trim the prev segment. */ 01740 prev->len = (u16_t)(seqno - prev->tcphdr->seqno); 01741 pbuf_realloc(prev->p, prev->len); 01742 } 01743 prev->next = cseg; 01744 tcp_oos_insert_segment(cseg, next); 01745 } 01746 break; 01747 } 01748 } 01749 01750 #if LWIP_TCP_SACK_OUT 01751 /* The new segment goes after the 'next' one. If there is a "hole" in sequence numbers 01752 between 'prev' and the beginning of 'next', we want to move sackbeg. */ 01753 if (prev != NULL && prev->tcphdr->seqno + prev->len != next->tcphdr->seqno) { 01754 sackbeg = next->tcphdr->seqno; 01755 } 01756 #endif /* LWIP_TCP_SACK_OUT */ 01757 01758 /* We don't use 'prev' below, so let's set it to current 'next'. 01759 This way even if we break the loop below, 'prev' will be pointing 01760 at the segment right in front of the newly added one. */ 01761 prev = next; 01762 01763 /* If the "next" segment is the last segment on the 01764 ooseq queue, we add the incoming segment to the end 01765 of the list. */ 01766 if (next->next == NULL && 01767 TCP_SEQ_GT(seqno, next->tcphdr->seqno)) { 01768 if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) { 01769 /* segment "next" already contains all data */ 01770 break; 01771 } 01772 next->next = tcp_seg_copy(&inseg); 01773 if (next->next != NULL) { 01774 if (TCP_SEQ_GT(next->tcphdr->seqno + next->len, seqno)) { 01775 /* We need to trim the last segment. */ 01776 next->len = (u16_t)(seqno - next->tcphdr->seqno); 01777 pbuf_realloc(next->p, next->len); 01778 } 01779 /* check if the remote side overruns our receive window */ 01780 if (TCP_SEQ_GT((u32_t)tcplen + seqno, pcb->rcv_nxt + (u32_t)pcb->rcv_wnd)) { 01781 LWIP_DEBUGF(TCP_INPUT_DEBUG, 01782 ("tcp_receive: other end overran receive window" 01783 "seqno %"U32_F" len %"U16_F" right edge %"U32_F"\n", 01784 seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd)); 01785 if (TCPH_FLAGS(next->next->tcphdr) & TCP_FIN) { 01786 /* Must remove the FIN from the header as we're trimming 01787 * that byte of sequence-space from the packet */ 01788 TCPH_FLAGS_SET(next->next->tcphdr, TCPH_FLAGS(next->next->tcphdr) & ~TCP_FIN); 01789 } 01790 /* Adjust length of segment to fit in the window. */ 01791 next->next->len = (u16_t)(pcb->rcv_nxt + pcb->rcv_wnd - seqno); 01792 pbuf_realloc(next->next->p, next->next->len); 01793 tcplen = TCP_TCPLEN(next->next); 01794 LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n", 01795 (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd)); 01796 } 01797 } 01798 break; 01799 } 01800 } 01801 } 01802 01803 #if LWIP_TCP_SACK_OUT 01804 if (pcb->flags & TF_SACK) { 01805 if (prev == NULL) { 01806 /* The new segment is at the beginning. sackbeg should already be set properly. 01807 We need to find the right edge. */ 01808 next = pcb->ooseq; 01809 } else if (prev->next != NULL) { 01810 /* The new segment was added after 'prev'. If there is a "hole" between 'prev' and 'prev->next', 01811 we need to move sackbeg. After that we should find the right edge. */ 01812 next = prev->next; 01813 if (prev->tcphdr->seqno + prev->len != next->tcphdr->seqno) { 01814 sackbeg = next->tcphdr->seqno; 01815 } 01816 } else { 01817 next = NULL; 01818 } 01819 if (next != NULL) { 01820 u32_t sackend = next->tcphdr->seqno; 01821 for ( ; (next != NULL) && (sackend == next->tcphdr->seqno); next = next->next) { 01822 sackend += next->len; 01823 } 01824 tcp_add_sack(pcb, sackbeg, sackend); 01825 } 01826 } 01827 #endif /* LWIP_TCP_SACK_OUT */ 01828 } 01829 #if defined(TCP_OOSEQ_BYTES_LIMIT) || defined(TCP_OOSEQ_PBUFS_LIMIT) 01830 { 01831 /* Check that the data on ooseq doesn't exceed one of the limits 01832 and throw away everything above that limit. */ 01833 #ifdef TCP_OOSEQ_BYTES_LIMIT 01834 const u32_t ooseq_max_blen = TCP_OOSEQ_BYTES_LIMIT(pcb); 01835 u32_t ooseq_blen = 0; 01836 #endif 01837 #ifdef TCP_OOSEQ_PBUFS_LIMIT 01838 const u16_t ooseq_max_qlen = TCP_OOSEQ_PBUFS_LIMIT(pcb); 01839 u16_t ooseq_qlen = 0; 01840 #endif 01841 struct tcp_seg *next, *prev = NULL; 01842 for (next = pcb->ooseq; next != NULL; prev = next, next = next->next) { 01843 struct pbuf *p = next->p; 01844 int stop_here = 0; 01845 #ifdef TCP_OOSEQ_BYTES_LIMIT 01846 ooseq_blen += p->tot_len; 01847 if (ooseq_blen > ooseq_max_blen) { 01848 stop_here = 1; 01849 } 01850 #endif 01851 #ifdef TCP_OOSEQ_PBUFS_LIMIT 01852 ooseq_qlen += pbuf_clen(p); 01853 if (ooseq_qlen > ooseq_max_qlen) { 01854 stop_here = 1; 01855 } 01856 #endif 01857 if (stop_here) { 01858 #if LWIP_TCP_SACK_OUT 01859 if (pcb->flags & TF_SACK) { 01860 /* Let's remove all SACKs from next's seqno up. */ 01861 tcp_remove_sacks_gt(pcb, next->tcphdr->seqno); 01862 } 01863 #endif /* LWIP_TCP_SACK_OUT */ 01864 /* too much ooseq data, dump this and everything after it */ 01865 tcp_segs_free(next); 01866 if (prev == NULL) { 01867 /* first ooseq segment is too much, dump the whole queue */ 01868 pcb->ooseq = NULL; 01869 } else { 01870 /* just dump 'next' and everything after it */ 01871 prev->next = NULL; 01872 } 01873 break; 01874 } 01875 } 01876 } 01877 #endif /* TCP_OOSEQ_BYTES_LIMIT || TCP_OOSEQ_PBUFS_LIMIT */ 01878 #endif /* TCP_QUEUE_OOSEQ */ 01879 01880 /* We send the ACK packet after we've (potentially) dealt with SACKs, 01881 so they can be included in the acknowledgment. */ 01882 tcp_send_empty_ack(pcb); 01883 } 01884 } else { 01885 /* The incoming segment is not within the window. */ 01886 tcp_send_empty_ack(pcb); 01887 } 01888 } else { 01889 /* Segments with length 0 is taken care of here. Segments that 01890 fall out of the window are ACKed. */ 01891 if (!TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd - 1)) { 01892 tcp_ack_now(pcb); 01893 } 01894 } 01895 } 01896 01897 static u8_t 01898 tcp_get_next_optbyte(void) 01899 { 01900 u16_t optidx = tcp_optidx++; 01901 if ((tcphdr_opt2 == NULL) || (optidx < tcphdr_opt1len)) { 01902 u8_t *opts = (u8_t *)tcphdr + TCP_HLEN; 01903 return opts[optidx]; 01904 } else { 01905 u8_t idx = (u8_t)(optidx - tcphdr_opt1len); 01906 return tcphdr_opt2[idx]; 01907 } 01908 } 01909 01910 /** 01911 * Parses the options contained in the incoming segment. 01912 * 01913 * Called from tcp_listen_input() and tcp_process(). 01914 * Currently, only the MSS option is supported! 01915 * 01916 * @param pcb the tcp_pcb for which a segment arrived 01917 */ 01918 static void 01919 tcp_parseopt(struct tcp_pcb *pcb) 01920 { 01921 u8_t data; 01922 u16_t mss; 01923 #if LWIP_TCP_TIMESTAMPS 01924 u32_t tsval; 01925 #endif 01926 01927 LWIP_ASSERT("tcp_parseopt: invalid pcb", pcb != NULL); 01928 01929 /* Parse the TCP MSS option, if present. */ 01930 if (tcphdr_optlen != 0) { 01931 for (tcp_optidx = 0; tcp_optidx < tcphdr_optlen; ) { 01932 u8_t opt = tcp_get_next_optbyte(); 01933 switch (opt) { 01934 case LWIP_TCP_OPT_EOL: 01935 /* End of options. */ 01936 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: EOL\n")); 01937 return; 01938 case LWIP_TCP_OPT_NOP: 01939 /* NOP option. */ 01940 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: NOP\n")); 01941 break; 01942 case LWIP_TCP_OPT_MSS: 01943 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: MSS\n")); 01944 if (tcp_get_next_optbyte() != LWIP_TCP_OPT_LEN_MSS || (tcp_optidx - 2 + LWIP_TCP_OPT_LEN_MSS) > tcphdr_optlen) { 01945 /* Bad length */ 01946 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n")); 01947 return; 01948 } 01949 /* An MSS option with the right option length. */ 01950 mss = (u16_t)(tcp_get_next_optbyte() << 8); 01951 mss |= tcp_get_next_optbyte(); 01952 /* Limit the mss to the configured TCP_MSS and prevent division by zero */ 01953 pcb->mss = ((mss > TCP_MSS) || (mss == 0)) ? TCP_MSS : mss; 01954 break; 01955 #if LWIP_WND_SCALE 01956 case LWIP_TCP_OPT_WS: 01957 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: WND_SCALE\n")); 01958 if (tcp_get_next_optbyte() != LWIP_TCP_OPT_LEN_WS || (tcp_optidx - 2 + LWIP_TCP_OPT_LEN_WS) > tcphdr_optlen) { 01959 /* Bad length */ 01960 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n")); 01961 return; 01962 } 01963 /* An WND_SCALE option with the right option length. */ 01964 data = tcp_get_next_optbyte(); 01965 /* If syn was received with wnd scale option, 01966 activate wnd scale opt, but only if this is not a retransmission */ 01967 if ((flags & TCP_SYN) && !(pcb->flags & TF_WND_SCALE)) { 01968 pcb->snd_scale = data; 01969 if (pcb->snd_scale > 14U) { 01970 pcb->snd_scale = 14U; 01971 } 01972 pcb->rcv_scale = TCP_RCV_SCALE; 01973 tcp_set_flags(pcb, TF_WND_SCALE); 01974 /* window scaling is enabled, we can use the full receive window */ 01975 LWIP_ASSERT("window not at default value", pcb->rcv_wnd == TCPWND_MIN16(TCP_WND)); 01976 LWIP_ASSERT("window not at default value", pcb->rcv_ann_wnd == TCPWND_MIN16(TCP_WND)); 01977 pcb->rcv_wnd = pcb->rcv_ann_wnd = TCP_WND; 01978 } 01979 break; 01980 #endif /* LWIP_WND_SCALE */ 01981 #if LWIP_TCP_TIMESTAMPS 01982 case LWIP_TCP_OPT_TS: 01983 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: TS\n")); 01984 if (tcp_get_next_optbyte() != LWIP_TCP_OPT_LEN_TS || (tcp_optidx - 2 + LWIP_TCP_OPT_LEN_TS) > tcphdr_optlen) { 01985 /* Bad length */ 01986 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n")); 01987 return; 01988 } 01989 /* TCP timestamp option with valid length */ 01990 tsval = tcp_get_next_optbyte(); 01991 tsval |= (tcp_get_next_optbyte() << 8); 01992 tsval |= (tcp_get_next_optbyte() << 16); 01993 tsval |= (tcp_get_next_optbyte() << 24); 01994 if (flags & TCP_SYN) { 01995 pcb->ts_recent = lwip_ntohl(tsval); 01996 /* Enable sending timestamps in every segment now that we know 01997 the remote host supports it. */ 01998 tcp_set_flags(pcb, TF_TIMESTAMP); 01999 } else if (TCP_SEQ_BETWEEN(pcb->ts_lastacksent, seqno, seqno + tcplen)) { 02000 pcb->ts_recent = lwip_ntohl(tsval); 02001 } 02002 /* Advance to next option (6 bytes already read) */ 02003 tcp_optidx += LWIP_TCP_OPT_LEN_TS - 6; 02004 break; 02005 #endif /* LWIP_TCP_TIMESTAMPS */ 02006 #if LWIP_TCP_SACK_OUT 02007 case LWIP_TCP_OPT_SACK_PERM: 02008 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: SACK_PERM\n")); 02009 if (tcp_get_next_optbyte() != LWIP_TCP_OPT_LEN_SACK_PERM || (tcp_optidx - 2 + LWIP_TCP_OPT_LEN_SACK_PERM) > tcphdr_optlen) { 02010 /* Bad length */ 02011 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n")); 02012 return; 02013 } 02014 /* TCP SACK_PERM option with valid length */ 02015 if (flags & TCP_SYN) { 02016 /* We only set it if we receive it in a SYN (or SYN+ACK) packet */ 02017 tcp_set_flags(pcb, TF_SACK); 02018 } 02019 break; 02020 #endif /* LWIP_TCP_SACK_OUT */ 02021 default: 02022 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: other\n")); 02023 data = tcp_get_next_optbyte(); 02024 if (data < 2) { 02025 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n")); 02026 /* If the length field is zero, the options are malformed 02027 and we don't process them further. */ 02028 return; 02029 } 02030 /* All other options have a length field, so that we easily 02031 can skip past them. */ 02032 tcp_optidx += data - 2; 02033 } 02034 } 02035 } 02036 } 02037 02038 void 02039 tcp_trigger_input_pcb_close(void) 02040 { 02041 recv_flags |= TF_CLOSED; 02042 } 02043 02044 #if LWIP_TCP_SACK_OUT 02045 /** 02046 * Called by tcp_receive() to add new SACK entry. 02047 * 02048 * The new SACK entry will be placed at the beginning of rcv_sacks[], as the newest one. 02049 * Existing SACK entries will be "pushed back", to preserve their order. 02050 * This is the behavior described in RFC 2018, section 4. 02051 * 02052 * @param pcb the tcp_pcb for which a segment arrived 02053 * @param left the left side of the SACK (the first sequence number) 02054 * @param right the right side of the SACK (the first sequence number past this SACK) 02055 */ 02056 static void 02057 tcp_add_sack(struct tcp_pcb *pcb, u32_t left, u32_t right) 02058 { 02059 u8_t i; 02060 u8_t unused_idx; 02061 02062 if ((pcb->flags & TF_SACK) == 0 || !TCP_SEQ_LT(left, right)) { 02063 return; 02064 } 02065 02066 /* First, let's remove all SACKs that are no longer needed (because they overlap with the newest one), 02067 while moving all other SACKs forward. 02068 We run this loop for all entries, until we find the first invalid one. 02069 There is no point checking after that. */ 02070 for (i = unused_idx = 0; (i < LWIP_TCP_MAX_SACK_NUM) && LWIP_TCP_SACK_VALID(pcb, i); ++i) { 02071 /* We only want to use SACK at [i] if it doesn't overlap with left:right range. 02072 It does not overlap if its right side is before the newly added SACK, 02073 or if its left side is after the newly added SACK. 02074 NOTE: The equality should not really happen, but it doesn't hurt. */ 02075 if (TCP_SEQ_LEQ(pcb->rcv_sacks[i].right, left) || TCP_SEQ_LEQ(right, pcb->rcv_sacks[i].left)) { 02076 if (unused_idx != i) { 02077 /* We don't need to copy if it's already in the right spot */ 02078 pcb->rcv_sacks[unused_idx] = pcb->rcv_sacks[i]; 02079 } 02080 ++unused_idx; 02081 } 02082 } 02083 02084 /* Now 'unused_idx' is the index of the first invalid SACK entry, 02085 anywhere between 0 (no valid entries) and LWIP_TCP_MAX_SACK_NUM (all entries are valid). 02086 We want to clear this and all following SACKs. 02087 However, we will be adding another one in the front (and shifting everything else back). 02088 So let's just iterate from the back, and set each entry to the one to the left if it's valid, 02089 or to 0 if it is not. */ 02090 for (i = LWIP_TCP_MAX_SACK_NUM - 1; i > 0; --i) { 02091 /* [i] is the index we are setting, and the value should be at index [i-1], 02092 or 0 if that index is unused (>= unused_idx). */ 02093 if (i - 1 >= unused_idx) { 02094 /* [i-1] is unused. Let's clear [i]. */ 02095 pcb->rcv_sacks[i].left = pcb->rcv_sacks[i].right = 0; 02096 } else { 02097 pcb->rcv_sacks[i] = pcb->rcv_sacks[i - 1]; 02098 } 02099 } 02100 02101 /* And now we can store the newest SACK */ 02102 pcb->rcv_sacks[0].left = left; 02103 pcb->rcv_sacks[0].right = right; 02104 } 02105 02106 /** 02107 * Called to remove a range of SACKs. 02108 * 02109 * SACK entries will be removed or adjusted to not acknowledge any sequence 02110 * numbers that are less than 'seq' passed. It not only invalidates entries, 02111 * but also moves all entries that are still valid to the beginning. 02112 * 02113 * @param pcb the tcp_pcb to modify 02114 * @param seq the lowest sequence number to keep in SACK entries 02115 */ 02116 static void 02117 tcp_remove_sacks_lt(struct tcp_pcb *pcb, u32_t seq) 02118 { 02119 u8_t i; 02120 u8_t unused_idx; 02121 02122 /* We run this loop for all entries, until we find the first invalid one. 02123 There is no point checking after that. */ 02124 for (i = unused_idx = 0; (i < LWIP_TCP_MAX_SACK_NUM) && LWIP_TCP_SACK_VALID(pcb, i); ++i) { 02125 /* We only want to use SACK at index [i] if its right side is > 'seq'. */ 02126 if (TCP_SEQ_GT(pcb->rcv_sacks[i].right, seq)) { 02127 if (unused_idx != i) { 02128 /* We only copy it if it's not in the right spot already. */ 02129 pcb->rcv_sacks[unused_idx] = pcb->rcv_sacks[i]; 02130 } 02131 /* NOTE: It is possible that its left side is < 'seq', in which case we should adjust it. */ 02132 if (TCP_SEQ_LT(pcb->rcv_sacks[unused_idx].left, seq)) { 02133 pcb->rcv_sacks[unused_idx].left = seq; 02134 } 02135 ++unused_idx; 02136 } 02137 } 02138 02139 /* We also need to invalidate everything from 'unused_idx' till the end */ 02140 for (i = unused_idx; i < LWIP_TCP_MAX_SACK_NUM; ++i) { 02141 pcb->rcv_sacks[i].left = pcb->rcv_sacks[i].right = 0; 02142 } 02143 } 02144 02145 #if defined(TCP_OOSEQ_BYTES_LIMIT) || defined(TCP_OOSEQ_PBUFS_LIMIT) 02146 /** 02147 * Called to remove a range of SACKs. 02148 * 02149 * SACK entries will be removed or adjusted to not acknowledge any sequence 02150 * numbers that are greater than (or equal to) 'seq' passed. It not only invalidates entries, 02151 * but also moves all entries that are still valid to the beginning. 02152 * 02153 * @param pcb the tcp_pcb to modify 02154 * @param seq the highest sequence number to keep in SACK entries 02155 */ 02156 static void 02157 tcp_remove_sacks_gt(struct tcp_pcb *pcb, u32_t seq) 02158 { 02159 u8_t i; 02160 u8_t unused_idx; 02161 02162 /* We run this loop for all entries, until we find the first invalid one. 02163 There is no point checking after that. */ 02164 for (i = unused_idx = 0; (i < LWIP_TCP_MAX_SACK_NUM) && LWIP_TCP_SACK_VALID(pcb, i); ++i) { 02165 /* We only want to use SACK at index [i] if its left side is < 'seq'. */ 02166 if (TCP_SEQ_LT(pcb->rcv_sacks[i].left, seq)) { 02167 if (unused_idx != i) { 02168 /* We only copy it if it's not in the right spot already. */ 02169 pcb->rcv_sacks[unused_idx] = pcb->rcv_sacks[i]; 02170 } 02171 /* NOTE: It is possible that its right side is > 'seq', in which case we should adjust it. */ 02172 if (TCP_SEQ_GT(pcb->rcv_sacks[unused_idx].right, seq)) { 02173 pcb->rcv_sacks[unused_idx].right = seq; 02174 } 02175 ++unused_idx; 02176 } 02177 } 02178 02179 /* We also need to invalidate everything from 'unused_idx' till the end */ 02180 for (i = unused_idx; i < LWIP_TCP_MAX_SACK_NUM; ++i) { 02181 pcb->rcv_sacks[i].left = pcb->rcv_sacks[i].right = 0; 02182 } 02183 } 02184 #endif /* TCP_OOSEQ_BYTES_LIMIT || TCP_OOSEQ_PBUFS_LIMIT */ 02185 02186 #endif /* LWIP_TCP_SACK_OUT */ 02187 02188 #endif /* LWIP_TCP */
Generated on Tue Jul 12 2022 13:54:30 by
