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: mbed-os-example-blinky-gr-lychee GR-Boads_Camera_sample GR-Boards_Audio_Recoder GR-Boads_Camera_DisplayApp ... more
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 /** Initial CWND calculation as defined RFC 2581 */ 00063 #define LWIP_TCP_CALC_INITIAL_CWND(mss) LWIP_MIN((4U * (mss)), LWIP_MAX((2U * (mss)), 4380U)); 00064 /** Initial slow start threshold value: we use the full window */ 00065 #define LWIP_TCP_INITIAL_SSTHRESH(pcb) ((pcb)->snd_wnd) 00066 00067 /* These variables are global to all functions involved in the input 00068 processing of TCP segments. They are set by the tcp_input() 00069 function. */ 00070 static struct tcp_seg inseg; 00071 static struct tcp_hdr *tcphdr; 00072 static u16_t tcphdr_optlen; 00073 static u16_t tcphdr_opt1len; 00074 static u8_t* tcphdr_opt2; 00075 static u16_t tcp_optidx; 00076 static u32_t seqno, ackno; 00077 static tcpwnd_size_t recv_acked; 00078 static u16_t tcplen; 00079 static u8_t flags; 00080 00081 static u8_t recv_flags; 00082 static struct pbuf *recv_data; 00083 00084 struct tcp_pcb *tcp_input_pcb; 00085 00086 /* Forward declarations. */ 00087 static err_t tcp_process(struct tcp_pcb *pcb); 00088 static void tcp_receive(struct tcp_pcb *pcb); 00089 static void tcp_parseopt(struct tcp_pcb *pcb); 00090 00091 static void tcp_listen_input(struct tcp_pcb_listen *pcb); 00092 static void tcp_timewait_input(struct tcp_pcb *pcb); 00093 00094 /** 00095 * The initial input processing of TCP. It verifies the TCP header, demultiplexes 00096 * the segment between the PCBs and passes it on to tcp_process(), which implements 00097 * the TCP finite state machine. This function is called by the IP layer (in 00098 * ip_input()). 00099 * 00100 * @param p received TCP segment to process (p->payload pointing to the TCP header) 00101 * @param inp network interface on which this segment was received 00102 */ 00103 void 00104 tcp_input(struct pbuf *p, struct netif *inp) 00105 { 00106 struct tcp_pcb *pcb, *prev; 00107 struct tcp_pcb_listen *lpcb; 00108 #if SO_REUSE 00109 struct tcp_pcb *lpcb_prev = NULL; 00110 struct tcp_pcb_listen *lpcb_any = NULL; 00111 #endif /* SO_REUSE */ 00112 u8_t hdrlen_bytes; 00113 err_t err; 00114 00115 LWIP_UNUSED_ARG(inp); 00116 00117 PERF_START; 00118 00119 TCP_STATS_INC(tcp.recv); 00120 MIB2_STATS_INC(mib2.tcpinsegs); 00121 00122 tcphdr = (struct tcp_hdr *)p->payload; 00123 00124 #if TCP_INPUT_DEBUG 00125 tcp_debug_print(tcphdr); 00126 #endif 00127 00128 /* Check that TCP header fits in payload */ 00129 if (p->len < TCP_HLEN) { 00130 /* drop short packets */ 00131 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet (%"U16_F" bytes) discarded\n", p->tot_len)); 00132 TCP_STATS_INC(tcp.lenerr); 00133 goto dropped; 00134 } 00135 00136 /* Don't even process incoming broadcasts/multicasts. */ 00137 if (ip_addr_isbroadcast(ip_current_dest_addr(), ip_current_netif()) || 00138 ip_addr_ismulticast(ip_current_dest_addr())) { 00139 TCP_STATS_INC(tcp.proterr); 00140 goto dropped; 00141 } 00142 00143 #if CHECKSUM_CHECK_TCP 00144 IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_TCP) { 00145 /* Verify TCP checksum. */ 00146 u16_t chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len, 00147 ip_current_src_addr(), ip_current_dest_addr()); 00148 if (chksum != 0) { 00149 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packet discarded due to failing checksum 0x%04"X16_F"\n", 00150 chksum)); 00151 tcp_debug_print(tcphdr); 00152 TCP_STATS_INC(tcp.chkerr); 00153 goto dropped; 00154 } 00155 } 00156 #endif /* CHECKSUM_CHECK_TCP */ 00157 00158 /* sanity-check header length */ 00159 hdrlen_bytes = TCPH_HDRLEN(tcphdr) * 4; 00160 if ((hdrlen_bytes < TCP_HLEN) || (hdrlen_bytes > p->tot_len)) { 00161 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: invalid header length (%"U16_F")\n", (u16_t)hdrlen_bytes)); 00162 TCP_STATS_INC(tcp.lenerr); 00163 goto dropped; 00164 } 00165 00166 /* Move the payload pointer in the pbuf so that it points to the 00167 TCP data instead of the TCP header. */ 00168 tcphdr_optlen = hdrlen_bytes - TCP_HLEN; 00169 tcphdr_opt2 = NULL; 00170 if (p->len >= hdrlen_bytes) { 00171 /* all options are in the first pbuf */ 00172 tcphdr_opt1len = tcphdr_optlen; 00173 pbuf_header(p, -(s16_t)hdrlen_bytes); /* cannot fail */ 00174 } else { 00175 u16_t opt2len; 00176 /* TCP header fits into first pbuf, options don't - data is in the next pbuf */ 00177 /* there must be a next pbuf, due to hdrlen_bytes sanity check above */ 00178 LWIP_ASSERT("p->next != NULL", p->next != NULL); 00179 00180 /* advance over the TCP header (cannot fail) */ 00181 pbuf_header(p, -TCP_HLEN); 00182 00183 /* determine how long the first and second parts of the options are */ 00184 tcphdr_opt1len = p->len; 00185 opt2len = tcphdr_optlen - tcphdr_opt1len; 00186 00187 /* options continue in the next pbuf: set p to zero length and hide the 00188 options in the next pbuf (adjusting p->tot_len) */ 00189 pbuf_header(p, -(s16_t)tcphdr_opt1len); 00190 00191 /* check that the options fit in the second pbuf */ 00192 if (opt2len > p->next->len) { 00193 /* drop short packets */ 00194 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: options overflow second pbuf (%"U16_F" bytes)\n", p->next->len)); 00195 TCP_STATS_INC(tcp.lenerr); 00196 goto dropped; 00197 } 00198 00199 /* remember the pointer to the second part of the options */ 00200 tcphdr_opt2 = (u8_t*)p->next->payload; 00201 00202 /* advance p->next to point after the options, and manually 00203 adjust p->tot_len to keep it consistent with the changed p->next */ 00204 pbuf_header(p->next, -(s16_t)opt2len); 00205 p->tot_len -= opt2len; 00206 00207 LWIP_ASSERT("p->len == 0", p->len == 0); 00208 LWIP_ASSERT("p->tot_len == p->next->tot_len", p->tot_len == p->next->tot_len); 00209 } 00210 00211 /* Convert fields in TCP header to host byte order. */ 00212 tcphdr->src = lwip_ntohs(tcphdr->src); 00213 tcphdr->dest = lwip_ntohs(tcphdr->dest); 00214 seqno = tcphdr->seqno = lwip_ntohl(tcphdr->seqno); 00215 ackno = tcphdr->ackno = lwip_ntohl(tcphdr->ackno); 00216 tcphdr->wnd = lwip_ntohs(tcphdr->wnd); 00217 00218 flags = TCPH_FLAGS(tcphdr); 00219 tcplen = p->tot_len + ((flags & (TCP_FIN | TCP_SYN)) ? 1 : 0); 00220 00221 /* Demultiplex an incoming segment. First, we check if it is destined 00222 for an active connection. */ 00223 prev = NULL; 00224 00225 for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { 00226 LWIP_ASSERT("tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED); 00227 LWIP_ASSERT("tcp_input: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT); 00228 LWIP_ASSERT("tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN); 00229 if (pcb->remote_port == tcphdr->src && 00230 pcb->local_port == tcphdr->dest && 00231 ip_addr_cmp(&pcb->remote_ip, ip_current_src_addr()) && 00232 ip_addr_cmp(&pcb->local_ip, ip_current_dest_addr())) { 00233 /* Move this PCB to the front of the list so that subsequent 00234 lookups will be faster (we exploit locality in TCP segment 00235 arrivals). */ 00236 LWIP_ASSERT("tcp_input: pcb->next != pcb (before cache)", pcb->next != pcb); 00237 if (prev != NULL) { 00238 prev->next = pcb->next; 00239 pcb->next = tcp_active_pcbs; 00240 tcp_active_pcbs = pcb; 00241 } else { 00242 TCP_STATS_INC(tcp.cachehit); 00243 } 00244 LWIP_ASSERT("tcp_input: pcb->next != pcb (after cache)", pcb->next != pcb); 00245 break; 00246 } 00247 prev = pcb; 00248 } 00249 00250 if (pcb == NULL) { 00251 /* If it did not go to an active connection, we check the connections 00252 in the TIME-WAIT state. */ 00253 for (pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { 00254 LWIP_ASSERT("tcp_input: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT); 00255 if (pcb->remote_port == tcphdr->src && 00256 pcb->local_port == tcphdr->dest && 00257 ip_addr_cmp(&pcb->remote_ip, ip_current_src_addr()) && 00258 ip_addr_cmp(&pcb->local_ip, ip_current_dest_addr())) { 00259 /* We don't really care enough to move this PCB to the front 00260 of the list since we are not very likely to receive that 00261 many segments for connections in TIME-WAIT. */ 00262 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for TIME_WAITing connection.\n")); 00263 tcp_timewait_input(pcb); 00264 pbuf_free(p); 00265 return; 00266 } 00267 } 00268 00269 /* Finally, if we still did not get a match, we check all PCBs that 00270 are LISTENing for incoming connections. */ 00271 prev = NULL; 00272 for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { 00273 if (lpcb->local_port == tcphdr->dest) { 00274 if (IP_IS_ANY_TYPE_VAL(lpcb->local_ip)) { 00275 /* found an ANY TYPE (IPv4/IPv6) match */ 00276 #if SO_REUSE 00277 lpcb_any = lpcb; 00278 lpcb_prev = prev; 00279 #else /* SO_REUSE */ 00280 break; 00281 #endif /* SO_REUSE */ 00282 } else if (IP_ADDR_PCB_VERSION_MATCH_EXACT(lpcb, ip_current_dest_addr())) { 00283 if (ip_addr_cmp(&lpcb->local_ip, ip_current_dest_addr())) { 00284 /* found an exact match */ 00285 break; 00286 } else if (ip_addr_isany(&lpcb->local_ip)) { 00287 /* found an ANY-match */ 00288 #if SO_REUSE 00289 lpcb_any = lpcb; 00290 lpcb_prev = prev; 00291 #else /* SO_REUSE */ 00292 break; 00293 #endif /* SO_REUSE */ 00294 } 00295 } 00296 } 00297 prev = (struct tcp_pcb *)lpcb; 00298 } 00299 #if SO_REUSE 00300 /* first try specific local IP */ 00301 if (lpcb == NULL) { 00302 /* only pass to ANY if no specific local IP has been found */ 00303 lpcb = lpcb_any; 00304 prev = lpcb_prev; 00305 } 00306 #endif /* SO_REUSE */ 00307 if (lpcb != NULL) { 00308 /* Move this PCB to the front of the list so that subsequent 00309 lookups will be faster (we exploit locality in TCP segment 00310 arrivals). */ 00311 if (prev != NULL) { 00312 ((struct tcp_pcb_listen *)prev)->next = lpcb->next; 00313 /* our successor is the remainder of the listening list */ 00314 lpcb->next = tcp_listen_pcbs.listen_pcbs; 00315 /* put this listening pcb at the head of the listening list */ 00316 tcp_listen_pcbs.listen_pcbs = lpcb; 00317 } else { 00318 TCP_STATS_INC(tcp.cachehit); 00319 } 00320 00321 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for LISTENing connection.\n")); 00322 tcp_listen_input(lpcb); 00323 pbuf_free(p); 00324 return; 00325 } 00326 } 00327 00328 #if TCP_INPUT_DEBUG 00329 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("+-+-+-+-+-+-+-+-+-+-+-+-+-+- tcp_input: flags ")); 00330 tcp_debug_print_flags(TCPH_FLAGS(tcphdr)); 00331 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n")); 00332 #endif /* TCP_INPUT_DEBUG */ 00333 00334 00335 if (pcb != NULL) { 00336 /* The incoming segment belongs to a connection. */ 00337 #if TCP_INPUT_DEBUG 00338 tcp_debug_print_state(pcb->state); 00339 #endif /* TCP_INPUT_DEBUG */ 00340 00341 /* Set up a tcp_seg structure. */ 00342 inseg.next = NULL; 00343 inseg.len = p->tot_len; 00344 inseg.p = p; 00345 inseg.tcphdr = tcphdr; 00346 00347 recv_data = NULL; 00348 recv_flags = 0; 00349 recv_acked = 0; 00350 00351 if (flags & TCP_PSH) { 00352 p->flags |= PBUF_FLAG_PUSH; 00353 } 00354 00355 /* If there is data which was previously "refused" by upper layer */ 00356 if (pcb->refused_data != NULL) { 00357 if ((tcp_process_refused_data(pcb) == ERR_ABRT) || 00358 ((pcb->refused_data != NULL) && (tcplen > 0))) { 00359 /* pcb has been aborted or refused data is still refused and the new 00360 segment contains data */ 00361 if (pcb->rcv_ann_wnd == 0) { 00362 /* this is a zero-window probe, we respond to it with current RCV.NXT 00363 and drop the data segment */ 00364 tcp_send_empty_ack(pcb); 00365 } 00366 TCP_STATS_INC(tcp.drop); 00367 MIB2_STATS_INC(mib2.tcpinerrs); 00368 goto aborted; 00369 } 00370 } 00371 tcp_input_pcb = pcb; 00372 err = tcp_process(pcb); 00373 /* A return value of ERR_ABRT means that tcp_abort() was called 00374 and that the pcb has been freed. If so, we don't do anything. */ 00375 if (err != ERR_ABRT) { 00376 if (recv_flags & TF_RESET) { 00377 /* TF_RESET means that the connection was reset by the other 00378 end. We then call the error callback to inform the 00379 application that the connection is dead before we 00380 deallocate the PCB. */ 00381 TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_RST); 00382 tcp_pcb_remove(&tcp_active_pcbs, pcb); 00383 memp_free(MEMP_TCP_PCB, pcb); 00384 } else { 00385 err = ERR_OK; 00386 /* If the application has registered a "sent" function to be 00387 called when new send buffer space is available, we call it 00388 now. */ 00389 if (recv_acked > 0) { 00390 u16_t acked16; 00391 #if LWIP_WND_SCALE 00392 /* recv_acked is u32_t but the sent callback only takes a u16_t, 00393 so we might have to call it multiple times. */ 00394 u32_t acked = recv_acked; 00395 while (acked > 0) { 00396 acked16 = (u16_t)LWIP_MIN(acked, 0xffffu); 00397 acked -= acked16; 00398 #else 00399 { 00400 acked16 = recv_acked; 00401 #endif 00402 TCP_EVENT_SENT(pcb, (u16_t)acked16, err); 00403 if (err == ERR_ABRT) { 00404 goto aborted; 00405 } 00406 } 00407 recv_acked = 0; 00408 } 00409 if (recv_flags & TF_CLOSED) { 00410 /* The connection has been closed and we will deallocate the 00411 PCB. */ 00412 if (!(pcb->flags & TF_RXCLOSED)) { 00413 /* Connection closed although the application has only shut down the 00414 tx side: call the PCB's err callback and indicate the closure to 00415 ensure the application doesn't continue using the PCB. */ 00416 TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_CLSD); 00417 } 00418 tcp_pcb_remove(&tcp_active_pcbs, pcb); 00419 memp_free(MEMP_TCP_PCB, pcb); 00420 goto aborted; 00421 } 00422 #if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE 00423 while (recv_data != NULL) { 00424 struct pbuf *rest = NULL; 00425 pbuf_split_64k(recv_data, &rest); 00426 #else /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ 00427 if (recv_data != NULL) { 00428 #endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ 00429 00430 LWIP_ASSERT("pcb->refused_data == NULL", pcb->refused_data == NULL); 00431 if (pcb->flags & TF_RXCLOSED) { 00432 /* received data although already closed -> abort (send RST) to 00433 notify the remote host that not all data has been processed */ 00434 pbuf_free(recv_data); 00435 #if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE 00436 if (rest != NULL) { 00437 pbuf_free(rest); 00438 } 00439 #endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ 00440 tcp_abort(pcb); 00441 goto aborted; 00442 } 00443 00444 /* Notify application that data has been received. */ 00445 TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err); 00446 if (err == ERR_ABRT) { 00447 #if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE 00448 if (rest != NULL) { 00449 pbuf_free(rest); 00450 } 00451 #endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ 00452 goto aborted; 00453 } 00454 00455 /* If the upper layer can't receive this data, store it */ 00456 if (err != ERR_OK) { 00457 #if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE 00458 if (rest != NULL) { 00459 pbuf_cat(recv_data, rest); 00460 } 00461 #endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ 00462 pcb->refused_data = recv_data; 00463 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: keep incoming packet, because pcb is \"full\"\n")); 00464 #if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE 00465 break; 00466 } else { 00467 /* Upper layer received the data, go on with the rest if > 64K */ 00468 recv_data = rest; 00469 #endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ 00470 } 00471 } 00472 00473 /* If a FIN segment was received, we call the callback 00474 function with a NULL buffer to indicate EOF. */ 00475 if (recv_flags & TF_GOT_FIN) { 00476 if (pcb->refused_data != NULL) { 00477 /* Delay this if we have refused data. */ 00478 pcb->refused_data->flags |= PBUF_FLAG_TCP_FIN; 00479 } else { 00480 /* correct rcv_wnd as the application won't call tcp_recved() 00481 for the FIN's seqno */ 00482 if (pcb->rcv_wnd != TCP_WND_MAX(pcb)) { 00483 pcb->rcv_wnd++; 00484 } 00485 TCP_EVENT_CLOSED(pcb, err); 00486 if (err == ERR_ABRT) { 00487 goto aborted; 00488 } 00489 } 00490 } 00491 00492 tcp_input_pcb = NULL; 00493 /* Try to send something out. */ 00494 tcp_output(pcb); 00495 #if TCP_INPUT_DEBUG 00496 #if TCP_DEBUG 00497 tcp_debug_print_state(pcb->state); 00498 #endif /* TCP_DEBUG */ 00499 #endif /* TCP_INPUT_DEBUG */ 00500 } 00501 } 00502 /* Jump target if pcb has been aborted in a callback (by calling tcp_abort()). 00503 Below this line, 'pcb' may not be dereferenced! */ 00504 aborted: 00505 tcp_input_pcb = NULL; 00506 recv_data = NULL; 00507 00508 /* give up our reference to inseg.p */ 00509 if (inseg.p != NULL) 00510 { 00511 pbuf_free(inseg.p); 00512 inseg.p = NULL; 00513 } 00514 } else { 00515 00516 /* If no matching PCB was found, send a TCP RST (reset) to the 00517 sender. */ 00518 LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_input: no PCB match found, resetting.\n")); 00519 if (!(TCPH_FLAGS(tcphdr) & TCP_RST)) { 00520 TCP_STATS_INC(tcp.proterr); 00521 TCP_STATS_INC(tcp.drop); 00522 tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), 00523 ip_current_src_addr(), tcphdr->dest, tcphdr->src); 00524 } 00525 pbuf_free(p); 00526 } 00527 00528 LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane()); 00529 PERF_STOP("tcp_input"); 00530 return; 00531 dropped: 00532 TCP_STATS_INC(tcp.drop); 00533 MIB2_STATS_INC(mib2.tcpinerrs); 00534 pbuf_free(p); 00535 } 00536 00537 /** 00538 * Called by tcp_input() when a segment arrives for a listening 00539 * connection (from tcp_input()). 00540 * 00541 * @param pcb the tcp_pcb_listen for which a segment arrived 00542 * 00543 * @note the segment which arrived is saved in global variables, therefore only the pcb 00544 * involved is passed as a parameter to this function 00545 */ 00546 static void 00547 tcp_listen_input(struct tcp_pcb_listen *pcb) 00548 { 00549 struct tcp_pcb *npcb; 00550 u32_t iss; 00551 err_t rc; 00552 00553 if (flags & TCP_RST) { 00554 /* An incoming RST should be ignored. Return. */ 00555 return; 00556 } 00557 00558 /* In the LISTEN state, we check for incoming SYN segments, 00559 creates a new PCB, and responds with a SYN|ACK. */ 00560 if (flags & TCP_ACK) { 00561 /* For incoming segments with the ACK flag set, respond with a 00562 RST. */ 00563 LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_listen_input: ACK in LISTEN, sending reset\n")); 00564 tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), 00565 ip_current_src_addr(), tcphdr->dest, tcphdr->src); 00566 } else if (flags & TCP_SYN) { 00567 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection request %"U16_F" -> %"U16_F".\n", tcphdr->src, tcphdr->dest)); 00568 #if TCP_LISTEN_BACKLOG 00569 if (pcb->accepts_pending >= pcb->backlog) { 00570 LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: listen backlog exceeded for port %"U16_F"\n", tcphdr->dest)); 00571 return; 00572 } 00573 #endif /* TCP_LISTEN_BACKLOG */ 00574 npcb = tcp_alloc(pcb->prio); 00575 /* If a new PCB could not be created (probably due to lack of memory), 00576 we don't do anything, but rely on the sender will retransmit the 00577 SYN at a time when we have more memory available. */ 00578 if (npcb == NULL) { 00579 err_t err; 00580 LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: could not allocate PCB\n")); 00581 TCP_STATS_INC(tcp.memerr); 00582 TCP_EVENT_ACCEPT(pcb, NULL, pcb->callback_arg, ERR_MEM, err); 00583 LWIP_UNUSED_ARG(err); /* err not useful here */ 00584 return; 00585 } 00586 #if TCP_LISTEN_BACKLOG 00587 pcb->accepts_pending++; 00588 npcb->flags |= TF_BACKLOGPEND; 00589 #endif /* TCP_LISTEN_BACKLOG */ 00590 /* Set up the new PCB. */ 00591 ip_addr_copy(npcb->local_ip, *ip_current_dest_addr()); 00592 ip_addr_copy(npcb->remote_ip, *ip_current_src_addr()); 00593 npcb->local_port = pcb->local_port; 00594 npcb->remote_port = tcphdr->src; 00595 npcb->state = SYN_RCVD; 00596 npcb->rcv_nxt = seqno + 1; 00597 npcb->rcv_ann_right_edge = npcb->rcv_nxt; 00598 iss = tcp_next_iss(npcb); 00599 npcb->snd_wl2 = iss; 00600 npcb->snd_nxt = iss; 00601 npcb->lastack = iss; 00602 npcb->snd_lbb = iss; 00603 npcb->snd_wl1 = seqno - 1;/* initialise to seqno-1 to force window update */ 00604 npcb->callback_arg = pcb->callback_arg; 00605 #if LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG 00606 npcb->listener = pcb; 00607 #endif /* LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG */ 00608 /* inherit socket options */ 00609 npcb->so_options = pcb->so_options & SOF_INHERITED; 00610 /* Register the new PCB so that we can begin receiving segments 00611 for it. */ 00612 TCP_REG_ACTIVE(npcb); 00613 00614 /* Parse any options in the SYN. */ 00615 tcp_parseopt(npcb); 00616 npcb->snd_wnd = tcphdr->wnd; 00617 npcb->snd_wnd_max = npcb->snd_wnd; 00618 npcb->ssthresh = LWIP_TCP_INITIAL_SSTHRESH(npcb); 00619 00620 #if TCP_CALCULATE_EFF_SEND_MSS 00621 npcb->mss = tcp_eff_send_mss(npcb->mss, &npcb->local_ip, &npcb->remote_ip); 00622 #endif /* TCP_CALCULATE_EFF_SEND_MSS */ 00623 00624 MIB2_STATS_INC(mib2.tcppassiveopens); 00625 00626 /* Send a SYN|ACK together with the MSS option. */ 00627 rc = tcp_enqueue_flags(npcb, TCP_SYN | TCP_ACK); 00628 if (rc != ERR_OK) { 00629 tcp_abandon(npcb, 0); 00630 return; 00631 } 00632 tcp_output(npcb); 00633 } 00634 return; 00635 } 00636 00637 /** 00638 * Called by tcp_input() when a segment arrives for a connection in 00639 * TIME_WAIT. 00640 * 00641 * @param pcb the tcp_pcb for which a segment arrived 00642 * 00643 * @note the segment which arrived is saved in global variables, therefore only the pcb 00644 * involved is passed as a parameter to this function 00645 */ 00646 static void 00647 tcp_timewait_input(struct tcp_pcb *pcb) 00648 { 00649 /* RFC 1337: in TIME_WAIT, ignore RST and ACK FINs + any 'acceptable' segments */ 00650 /* RFC 793 3.9 Event Processing - Segment Arrives: 00651 * - first check sequence number - we skip that one in TIME_WAIT (always 00652 * acceptable since we only send ACKs) 00653 * - second check the RST bit (... return) */ 00654 if (flags & TCP_RST) { 00655 return; 00656 } 00657 /* - fourth, check the SYN bit, */ 00658 if (flags & TCP_SYN) { 00659 /* If an incoming segment is not acceptable, an acknowledgment 00660 should be sent in reply */ 00661 if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd)) { 00662 /* If the SYN is in the window it is an error, send a reset */ 00663 tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), 00664 ip_current_src_addr(), tcphdr->dest, tcphdr->src); 00665 return; 00666 } 00667 } else if (flags & TCP_FIN) { 00668 /* - eighth, check the FIN bit: Remain in the TIME-WAIT state. 00669 Restart the 2 MSL time-wait timeout.*/ 00670 pcb->tmr = tcp_ticks; 00671 } 00672 00673 if ((tcplen > 0)) { 00674 /* Acknowledge data, FIN or out-of-window SYN */ 00675 pcb->flags |= TF_ACK_NOW; 00676 tcp_output(pcb); 00677 } 00678 return; 00679 } 00680 00681 /** 00682 * Implements the TCP state machine. Called by tcp_input. In some 00683 * states tcp_receive() is called to receive data. The tcp_seg 00684 * argument will be freed by the caller (tcp_input()) unless the 00685 * recv_data pointer in the pcb is set. 00686 * 00687 * @param pcb the tcp_pcb for which a segment arrived 00688 * 00689 * @note the segment which arrived is saved in global variables, therefore only the pcb 00690 * involved is passed as a parameter to this function 00691 */ 00692 static err_t 00693 tcp_process(struct tcp_pcb *pcb) 00694 { 00695 struct tcp_seg *rseg; 00696 u8_t acceptable = 0; 00697 err_t err; 00698 00699 err = ERR_OK; 00700 00701 /* Process incoming RST segments. */ 00702 if (flags & TCP_RST) { 00703 /* First, determine if the reset is acceptable. */ 00704 if (pcb->state == SYN_SENT) { 00705 /* "In the SYN-SENT state (a RST received in response to an initial SYN), 00706 the RST is acceptable if the ACK field acknowledges the SYN." */ 00707 if (ackno == pcb->snd_nxt) { 00708 acceptable = 1; 00709 } 00710 } else { 00711 /* "In all states except SYN-SENT, all reset (RST) segments are validated 00712 by checking their SEQ-fields." */ 00713 if (seqno == pcb->rcv_nxt) { 00714 acceptable = 1; 00715 } else if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, 00716 pcb->rcv_nxt + pcb->rcv_wnd)) { 00717 /* If the sequence number is inside the window, we only send an ACK 00718 and wait for a re-send with matching sequence number. 00719 This violates RFC 793, but is required to protection against 00720 CVE-2004-0230 (RST spoofing attack). */ 00721 tcp_ack_now(pcb); 00722 } 00723 } 00724 00725 if (acceptable) { 00726 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: Connection RESET\n")); 00727 LWIP_ASSERT("tcp_input: pcb->state != CLOSED", pcb->state != CLOSED); 00728 recv_flags |= TF_RESET; 00729 pcb->flags &= ~TF_ACK_DELAY; 00730 return ERR_RST; 00731 } else { 00732 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n", 00733 seqno, pcb->rcv_nxt)); 00734 LWIP_DEBUGF(TCP_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n", 00735 seqno, pcb->rcv_nxt)); 00736 return ERR_OK; 00737 } 00738 } 00739 00740 if ((flags & TCP_SYN) && (pcb->state != SYN_SENT && pcb->state != SYN_RCVD)) { 00741 /* Cope with new connection attempt after remote end crashed */ 00742 tcp_ack_now(pcb); 00743 return ERR_OK; 00744 } 00745 00746 if ((pcb->flags & TF_RXCLOSED) == 0) { 00747 /* Update the PCB (in)activity timer unless rx is closed (see tcp_shutdown) */ 00748 pcb->tmr = tcp_ticks; 00749 } 00750 pcb->keep_cnt_sent = 0; 00751 00752 tcp_parseopt(pcb); 00753 00754 /* Do different things depending on the TCP state. */ 00755 switch (pcb->state) { 00756 case SYN_SENT: 00757 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %"U32_F" pcb->snd_nxt %"U32_F" unacked %"U32_F"\n", ackno, 00758 pcb->snd_nxt, lwip_ntohl(pcb->unacked->tcphdr->seqno))); 00759 /* received SYN ACK with expected sequence number? */ 00760 if ((flags & TCP_ACK) && (flags & TCP_SYN) 00761 && (ackno == pcb->lastack + 1)) { 00762 pcb->rcv_nxt = seqno + 1; 00763 pcb->rcv_ann_right_edge = pcb->rcv_nxt; 00764 pcb->lastack = ackno; 00765 pcb->snd_wnd = tcphdr->wnd; 00766 pcb->snd_wnd_max = pcb->snd_wnd; 00767 pcb->snd_wl1 = seqno - 1; /* initialise to seqno - 1 to force window update */ 00768 pcb->state = ESTABLISHED; 00769 00770 #if TCP_CALCULATE_EFF_SEND_MSS 00771 pcb->mss = tcp_eff_send_mss(pcb->mss, &pcb->local_ip, &pcb->remote_ip); 00772 #endif /* TCP_CALCULATE_EFF_SEND_MSS */ 00773 00774 /* Set ssthresh again after changing 'mss' and 'snd_wnd' */ 00775 pcb->ssthresh = LWIP_TCP_INITIAL_SSTHRESH(pcb); 00776 00777 pcb->cwnd = LWIP_TCP_CALC_INITIAL_CWND(pcb->mss); 00778 LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_process (SENT): cwnd %"TCPWNDSIZE_F 00779 " ssthresh %"TCPWNDSIZE_F"\n", 00780 pcb->cwnd, pcb->ssthresh)); 00781 LWIP_ASSERT("pcb->snd_queuelen > 0", (pcb->snd_queuelen > 0)); 00782 --pcb->snd_queuelen; 00783 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_process: SYN-SENT --queuelen %"TCPWNDSIZE_F"\n", (tcpwnd_size_t)pcb->snd_queuelen)); 00784 rseg = pcb->unacked; 00785 if (rseg == NULL) { 00786 /* might happen if tcp_output fails in tcp_rexmit_rto() 00787 in which case the segment is on the unsent list */ 00788 rseg = pcb->unsent; 00789 LWIP_ASSERT("no segment to free", rseg != NULL); 00790 pcb->unsent = rseg->next; 00791 } else { 00792 pcb->unacked = rseg->next; 00793 } 00794 tcp_seg_free(rseg); 00795 00796 /* If there's nothing left to acknowledge, stop the retransmit 00797 timer, otherwise reset it to start again */ 00798 if (pcb->unacked == NULL) { 00799 pcb->rtime = -1; 00800 } else { 00801 pcb->rtime = 0; 00802 pcb->nrtx = 0; 00803 } 00804 00805 /* Call the user specified function to call when successfully 00806 * connected. */ 00807 TCP_EVENT_CONNECTED(pcb, ERR_OK, err); 00808 if (err == ERR_ABRT) { 00809 return ERR_ABRT; 00810 } 00811 tcp_ack_now(pcb); 00812 } 00813 /* received ACK? possibly a half-open connection */ 00814 else if (flags & TCP_ACK) { 00815 /* send a RST to bring the other side in a non-synchronized state. */ 00816 tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), 00817 ip_current_src_addr(), tcphdr->dest, tcphdr->src); 00818 /* Resend SYN immediately (don't wait for rto timeout) to establish 00819 connection faster */ 00820 pcb->rtime = 0; 00821 tcp_rexmit_rto(pcb); 00822 } 00823 break; 00824 case SYN_RCVD: 00825 if (flags & TCP_ACK) { 00826 /* expected ACK number? */ 00827 if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)) { 00828 pcb->state = ESTABLISHED; 00829 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection established %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); 00830 #if LWIP_CALLBACK_API 00831 LWIP_ASSERT("pcb->listener->accept != NULL", 00832 (pcb->listener == NULL) || (pcb->listener->accept != NULL)); 00833 if (pcb->listener == NULL) { 00834 /* listen pcb might be closed by now */ 00835 err = ERR_VAL; 00836 } else 00837 #endif 00838 { 00839 tcp_backlog_accepted(pcb); 00840 /* Call the accept function. */ 00841 TCP_EVENT_ACCEPT(pcb->listener, pcb, pcb->callback_arg, ERR_OK, err); 00842 } 00843 if (err != ERR_OK) { 00844 /* If the accept function returns with an error, we abort 00845 * the connection. */ 00846 /* Already aborted? */ 00847 if (err != ERR_ABRT) { 00848 tcp_abort(pcb); 00849 } 00850 return ERR_ABRT; 00851 } 00852 /* If there was any data contained within this ACK, 00853 * we'd better pass it on to the application as well. */ 00854 tcp_receive(pcb); 00855 00856 /* passive open: update initial ssthresh now that the correct window is 00857 known: if the remote side supports window scaling, the window sent 00858 with the initial SYN can be smaller than the one used later */ 00859 pcb->ssthresh = LWIP_TCP_INITIAL_SSTHRESH(pcb); 00860 00861 /* Prevent ACK for SYN to generate a sent event */ 00862 if (recv_acked != 0) { 00863 recv_acked--; 00864 } 00865 00866 pcb->cwnd = LWIP_TCP_CALC_INITIAL_CWND(pcb->mss); 00867 LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_process (SYN_RCVD): cwnd %"TCPWNDSIZE_F 00868 " ssthresh %"TCPWNDSIZE_F"\n", 00869 pcb->cwnd, pcb->ssthresh)); 00870 00871 if (recv_flags & TF_GOT_FIN) { 00872 tcp_ack_now(pcb); 00873 pcb->state = CLOSE_WAIT; 00874 } 00875 } else { 00876 /* incorrect ACK number, send RST */ 00877 tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), 00878 ip_current_src_addr(), tcphdr->dest, tcphdr->src); 00879 } 00880 } else if ((flags & TCP_SYN) && (seqno == pcb->rcv_nxt - 1)) { 00881 /* Looks like another copy of the SYN - retransmit our SYN-ACK */ 00882 tcp_rexmit(pcb); 00883 } 00884 break; 00885 case CLOSE_WAIT: 00886 /* FALLTHROUGH */ 00887 case ESTABLISHED: 00888 tcp_receive(pcb); 00889 if (recv_flags & TF_GOT_FIN) { /* passive close */ 00890 tcp_ack_now(pcb); 00891 pcb->state = CLOSE_WAIT; 00892 } 00893 break; 00894 case FIN_WAIT_1: 00895 tcp_receive(pcb); 00896 if (recv_flags & TF_GOT_FIN) { 00897 if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt) && 00898 pcb->unsent == NULL) { 00899 LWIP_DEBUGF(TCP_DEBUG, 00900 ("TCP connection closed: FIN_WAIT_1 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); 00901 tcp_ack_now(pcb); 00902 tcp_pcb_purge(pcb); 00903 TCP_RMV_ACTIVE(pcb); 00904 pcb->state = TIME_WAIT; 00905 TCP_REG(&tcp_tw_pcbs, pcb); 00906 } else { 00907 tcp_ack_now(pcb); 00908 pcb->state = CLOSING; 00909 } 00910 } else if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt) && 00911 pcb->unsent == NULL) { 00912 pcb->state = FIN_WAIT_2; 00913 } 00914 break; 00915 case FIN_WAIT_2: 00916 tcp_receive(pcb); 00917 if (recv_flags & TF_GOT_FIN) { 00918 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: FIN_WAIT_2 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); 00919 tcp_ack_now(pcb); 00920 tcp_pcb_purge(pcb); 00921 TCP_RMV_ACTIVE(pcb); 00922 pcb->state = TIME_WAIT; 00923 TCP_REG(&tcp_tw_pcbs, pcb); 00924 } 00925 break; 00926 case CLOSING: 00927 tcp_receive(pcb); 00928 if (flags & TCP_ACK && ackno == pcb->snd_nxt && pcb->unsent == NULL) { 00929 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: CLOSING %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); 00930 tcp_pcb_purge(pcb); 00931 TCP_RMV_ACTIVE(pcb); 00932 pcb->state = TIME_WAIT; 00933 TCP_REG(&tcp_tw_pcbs, pcb); 00934 } 00935 break; 00936 case LAST_ACK: 00937 tcp_receive(pcb); 00938 if (flags & TCP_ACK && ackno == pcb->snd_nxt && pcb->unsent == NULL) { 00939 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: LAST_ACK %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); 00940 /* bugfix #21699: don't set pcb->state to CLOSED here or we risk leaking segments */ 00941 recv_flags |= TF_CLOSED; 00942 } 00943 break; 00944 default: 00945 break; 00946 } 00947 return ERR_OK; 00948 } 00949 00950 #if TCP_QUEUE_OOSEQ 00951 /** 00952 * Insert segment into the list (segments covered with new one will be deleted) 00953 * 00954 * Called from tcp_receive() 00955 */ 00956 static void 00957 tcp_oos_insert_segment(struct tcp_seg *cseg, struct tcp_seg *next) 00958 { 00959 struct tcp_seg *old_seg; 00960 00961 if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) { 00962 /* received segment overlaps all following segments */ 00963 tcp_segs_free(next); 00964 next = NULL; 00965 } else { 00966 /* delete some following segments 00967 oos queue may have segments with FIN flag */ 00968 while (next && 00969 TCP_SEQ_GEQ((seqno + cseg->len), 00970 (next->tcphdr->seqno + next->len))) { 00971 /* cseg with FIN already processed */ 00972 if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) { 00973 TCPH_SET_FLAG(cseg->tcphdr, TCP_FIN); 00974 } 00975 old_seg = next; 00976 next = next->next; 00977 tcp_seg_free(old_seg); 00978 } 00979 if (next && 00980 TCP_SEQ_GT(seqno + cseg->len, next->tcphdr->seqno)) { 00981 /* We need to trim the incoming segment. */ 00982 cseg->len = (u16_t)(next->tcphdr->seqno - seqno); 00983 pbuf_realloc(cseg->p, cseg->len); 00984 } 00985 } 00986 cseg->next = next; 00987 } 00988 #endif /* TCP_QUEUE_OOSEQ */ 00989 00990 /** 00991 * Called by tcp_process. Checks if the given segment is an ACK for outstanding 00992 * data, and if so frees the memory of the buffered data. Next, it places the 00993 * segment on any of the receive queues (pcb->recved or pcb->ooseq). If the segment 00994 * is buffered, the pbuf is referenced by pbuf_ref so that it will not be freed until 00995 * it has been removed from the buffer. 00996 * 00997 * If the incoming segment constitutes an ACK for a segment that was used for RTT 00998 * estimation, the RTT is estimated here as well. 00999 * 01000 * Called from tcp_process(). 01001 */ 01002 static void 01003 tcp_receive(struct tcp_pcb *pcb) 01004 { 01005 struct tcp_seg *next; 01006 #if TCP_QUEUE_OOSEQ 01007 struct tcp_seg *prev, *cseg; 01008 #endif /* TCP_QUEUE_OOSEQ */ 01009 s32_t off; 01010 s16_t m; 01011 u32_t right_wnd_edge; 01012 u16_t new_tot_len; 01013 int found_dupack = 0; 01014 #if TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS 01015 u32_t ooseq_blen; 01016 u16_t ooseq_qlen; 01017 #endif /* TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS */ 01018 01019 LWIP_ASSERT("tcp_receive: wrong state", pcb->state >= ESTABLISHED); 01020 01021 if (flags & TCP_ACK) { 01022 right_wnd_edge = pcb->snd_wnd + pcb->snd_wl2; 01023 01024 /* Update window. */ 01025 if (TCP_SEQ_LT(pcb->snd_wl1, seqno) || 01026 (pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) || 01027 (pcb->snd_wl2 == ackno && (u32_t)SND_WND_SCALE(pcb, tcphdr->wnd) > pcb->snd_wnd)) { 01028 pcb->snd_wnd = SND_WND_SCALE(pcb, tcphdr->wnd); 01029 /* keep track of the biggest window announced by the remote host to calculate 01030 the maximum segment size */ 01031 if (pcb->snd_wnd_max < pcb->snd_wnd) { 01032 pcb->snd_wnd_max = pcb->snd_wnd; 01033 } 01034 pcb->snd_wl1 = seqno; 01035 pcb->snd_wl2 = ackno; 01036 if (pcb->snd_wnd == 0) { 01037 if (pcb->persist_backoff == 0) { 01038 /* start persist timer */ 01039 pcb->persist_cnt = 0; 01040 pcb->persist_backoff = 1; 01041 } 01042 } else if (pcb->persist_backoff > 0) { 01043 /* stop persist timer */ 01044 pcb->persist_backoff = 0; 01045 } 01046 LWIP_DEBUGF(TCP_WND_DEBUG, ("tcp_receive: window update %"TCPWNDSIZE_F"\n", pcb->snd_wnd)); 01047 #if TCP_WND_DEBUG 01048 } else { 01049 if (pcb->snd_wnd != (tcpwnd_size_t)SND_WND_SCALE(pcb, tcphdr->wnd)) { 01050 LWIP_DEBUGF(TCP_WND_DEBUG, 01051 ("tcp_receive: no window update lastack %"U32_F" ackno %" 01052 U32_F" wl1 %"U32_F" seqno %"U32_F" wl2 %"U32_F"\n", 01053 pcb->lastack, ackno, pcb->snd_wl1, seqno, pcb->snd_wl2)); 01054 } 01055 #endif /* TCP_WND_DEBUG */ 01056 } 01057 01058 /* (From Stevens TCP/IP Illustrated Vol II, p970.) Its only a 01059 * duplicate ack if: 01060 * 1) It doesn't ACK new data 01061 * 2) length of received packet is zero (i.e. no payload) 01062 * 3) the advertised window hasn't changed 01063 * 4) There is outstanding unacknowledged data (retransmission timer running) 01064 * 5) The ACK is == biggest ACK sequence number so far seen (snd_una) 01065 * 01066 * If it passes all five, should process as a dupack: 01067 * a) dupacks < 3: do nothing 01068 * b) dupacks == 3: fast retransmit 01069 * c) dupacks > 3: increase cwnd 01070 * 01071 * If it only passes 1-3, should reset dupack counter (and add to 01072 * stats, which we don't do in lwIP) 01073 * 01074 * If it only passes 1, should reset dupack counter 01075 * 01076 */ 01077 01078 /* Clause 1 */ 01079 if (TCP_SEQ_LEQ(ackno, pcb->lastack)) { 01080 /* Clause 2 */ 01081 if (tcplen == 0) { 01082 /* Clause 3 */ 01083 if (pcb->snd_wl2 + pcb->snd_wnd == right_wnd_edge) { 01084 /* Clause 4 */ 01085 if (pcb->rtime >= 0) { 01086 /* Clause 5 */ 01087 if (pcb->lastack == ackno) { 01088 found_dupack = 1; 01089 if ((u8_t)(pcb->dupacks + 1) > pcb->dupacks) { 01090 ++pcb->dupacks; 01091 } 01092 if (pcb->dupacks > 3) { 01093 /* Inflate the congestion window, but not if it means that 01094 the value overflows. */ 01095 if ((tcpwnd_size_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) { 01096 pcb->cwnd += pcb->mss; 01097 } 01098 } else if (pcb->dupacks == 3) { 01099 /* Do fast retransmit */ 01100 tcp_rexmit_fast(pcb); 01101 } 01102 } 01103 } 01104 } 01105 } 01106 /* If Clause (1) or more is true, but not a duplicate ack, reset 01107 * count of consecutive duplicate acks */ 01108 if (!found_dupack) { 01109 pcb->dupacks = 0; 01110 } 01111 } else if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)) { 01112 /* We come here when the ACK acknowledges new data. */ 01113 01114 /* Reset the "IN Fast Retransmit" flag, since we are no longer 01115 in fast retransmit. Also reset the congestion window to the 01116 slow start threshold. */ 01117 if (pcb->flags & TF_INFR) { 01118 pcb->flags &= ~TF_INFR; 01119 pcb->cwnd = pcb->ssthresh; 01120 } 01121 01122 /* Reset the number of retransmissions. */ 01123 pcb->nrtx = 0; 01124 01125 /* Reset the retransmission time-out. */ 01126 pcb->rto = (pcb->sa >> 3) + pcb->sv; 01127 01128 /* Reset the fast retransmit variables. */ 01129 pcb->dupacks = 0; 01130 pcb->lastack = ackno; 01131 01132 /* Update the congestion control variables (cwnd and 01133 ssthresh). */ 01134 if (pcb->state >= ESTABLISHED) { 01135 if (pcb->cwnd < pcb->ssthresh) { 01136 if ((tcpwnd_size_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) { 01137 pcb->cwnd += pcb->mss; 01138 } 01139 LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: slow start cwnd %"TCPWNDSIZE_F"\n", pcb->cwnd)); 01140 } else { 01141 tcpwnd_size_t new_cwnd = (pcb->cwnd + pcb->mss * pcb->mss / pcb->cwnd); 01142 if (new_cwnd > pcb->cwnd) { 01143 pcb->cwnd = new_cwnd; 01144 } 01145 LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: congestion avoidance cwnd %"TCPWNDSIZE_F"\n", pcb->cwnd)); 01146 } 01147 } 01148 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: ACK for %"U32_F", unacked->seqno %"U32_F":%"U32_F"\n", 01149 ackno, 01150 pcb->unacked != NULL? 01151 lwip_ntohl(pcb->unacked->tcphdr->seqno): 0, 01152 pcb->unacked != NULL? 01153 lwip_ntohl(pcb->unacked->tcphdr->seqno) + TCP_TCPLEN(pcb->unacked): 0)); 01154 01155 /* Remove segment from the unacknowledged list if the incoming 01156 ACK acknowledges them. */ 01157 while (pcb->unacked != NULL && 01158 TCP_SEQ_LEQ(lwip_ntohl(pcb->unacked->tcphdr->seqno) + 01159 TCP_TCPLEN(pcb->unacked), ackno)) { 01160 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unacked\n", 01161 lwip_ntohl(pcb->unacked->tcphdr->seqno), 01162 lwip_ntohl(pcb->unacked->tcphdr->seqno) + 01163 TCP_TCPLEN(pcb->unacked))); 01164 01165 next = pcb->unacked; 01166 pcb->unacked = pcb->unacked->next; 01167 01168 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"TCPWNDSIZE_F" ... ", (tcpwnd_size_t)pcb->snd_queuelen)); 01169 LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p))); 01170 01171 pcb->snd_queuelen -= pbuf_clen(next->p); 01172 recv_acked += next->len; 01173 tcp_seg_free(next); 01174 01175 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"TCPWNDSIZE_F" (after freeing unacked)\n", (tcpwnd_size_t)pcb->snd_queuelen)); 01176 if (pcb->snd_queuelen != 0) { 01177 LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL || 01178 pcb->unsent != NULL); 01179 } 01180 } 01181 01182 /* If there's nothing left to acknowledge, stop the retransmit 01183 timer, otherwise reset it to start again */ 01184 if (pcb->unacked == NULL) { 01185 pcb->rtime = -1; 01186 } else { 01187 pcb->rtime = 0; 01188 } 01189 01190 pcb->polltmr = 0; 01191 01192 #if LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS 01193 if (ip_current_is_v6()) { 01194 /* Inform neighbor reachability of forward progress. */ 01195 nd6_reachability_hint(ip6_current_src_addr()); 01196 } 01197 #endif /* LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS*/ 01198 } else { 01199 /* Out of sequence ACK, didn't really ack anything */ 01200 tcp_send_empty_ack(pcb); 01201 } 01202 01203 /* We go through the ->unsent list to see if any of the segments 01204 on the list are acknowledged by the ACK. This may seem 01205 strange since an "unsent" segment shouldn't be acked. The 01206 rationale is that lwIP puts all outstanding segments on the 01207 ->unsent list after a retransmission, so these segments may 01208 in fact have been sent once. */ 01209 while (pcb->unsent != NULL && 01210 TCP_SEQ_BETWEEN(ackno, lwip_ntohl(pcb->unsent->tcphdr->seqno) + 01211 TCP_TCPLEN(pcb->unsent), pcb->snd_nxt)) { 01212 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unsent\n", 01213 lwip_ntohl(pcb->unsent->tcphdr->seqno), lwip_ntohl(pcb->unsent->tcphdr->seqno) + 01214 TCP_TCPLEN(pcb->unsent))); 01215 01216 next = pcb->unsent; 01217 pcb->unsent = pcb->unsent->next; 01218 #if TCP_OVERSIZE 01219 if (pcb->unsent == NULL) { 01220 pcb->unsent_oversize = 0; 01221 } 01222 #endif /* TCP_OVERSIZE */ 01223 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"TCPWNDSIZE_F" ... ", (tcpwnd_size_t)pcb->snd_queuelen)); 01224 LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p))); 01225 /* Prevent ACK for FIN to generate a sent event */ 01226 pcb->snd_queuelen -= pbuf_clen(next->p); 01227 recv_acked += next->len; 01228 tcp_seg_free(next); 01229 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"TCPWNDSIZE_F" (after freeing unsent)\n", (tcpwnd_size_t)pcb->snd_queuelen)); 01230 if (pcb->snd_queuelen != 0) { 01231 LWIP_ASSERT("tcp_receive: valid queue length", 01232 pcb->unacked != NULL || pcb->unsent != NULL); 01233 } 01234 } 01235 pcb->snd_buf += recv_acked; 01236 /* End of ACK for new data processing. */ 01237 01238 LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: pcb->rttest %"U32_F" rtseq %"U32_F" ackno %"U32_F"\n", 01239 pcb->rttest, pcb->rtseq, ackno)); 01240 01241 /* RTT estimation calculations. This is done by checking if the 01242 incoming segment acknowledges the segment we use to take a 01243 round-trip time measurement. */ 01244 if (pcb->rttest && TCP_SEQ_LT(pcb->rtseq, ackno)) { 01245 /* diff between this shouldn't exceed 32K since this are tcp timer ticks 01246 and a round-trip shouldn't be that long... */ 01247 m = (s16_t)(tcp_ticks - pcb->rttest); 01248 01249 LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: experienced rtt %"U16_F" ticks (%"U16_F" msec).\n", 01250 m, (u16_t)(m * TCP_SLOW_INTERVAL))); 01251 01252 /* This is taken directly from VJs original code in his paper */ 01253 m = m - (pcb->sa >> 3); 01254 pcb->sa += m; 01255 if (m < 0) { 01256 m = -m; 01257 } 01258 m = m - (pcb->sv >> 2); 01259 pcb->sv += m; 01260 pcb->rto = (pcb->sa >> 3) + pcb->sv; 01261 01262 LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: RTO %"U16_F" (%"U16_F" milliseconds)\n", 01263 pcb->rto, (u16_t)(pcb->rto * TCP_SLOW_INTERVAL))); 01264 01265 pcb->rttest = 0; 01266 } 01267 } 01268 01269 /* If the incoming segment contains data, we must process it 01270 further unless the pcb already received a FIN. 01271 (RFC 793, chapter 3.9, "SEGMENT ARRIVES" in states CLOSE-WAIT, CLOSING, 01272 LAST-ACK and TIME-WAIT: "Ignore the segment text.") */ 01273 if ((tcplen > 0) && (pcb->state < CLOSE_WAIT)) { 01274 /* This code basically does three things: 01275 01276 +) If the incoming segment contains data that is the next 01277 in-sequence data, this data is passed to the application. This 01278 might involve trimming the first edge of the data. The rcv_nxt 01279 variable and the advertised window are adjusted. 01280 01281 +) If the incoming segment has data that is above the next 01282 sequence number expected (->rcv_nxt), the segment is placed on 01283 the ->ooseq queue. This is done by finding the appropriate 01284 place in the ->ooseq queue (which is ordered by sequence 01285 number) and trim the segment in both ends if needed. An 01286 immediate ACK is sent to indicate that we received an 01287 out-of-sequence segment. 01288 01289 +) Finally, we check if the first segment on the ->ooseq queue 01290 now is in sequence (i.e., if rcv_nxt >= ooseq->seqno). If 01291 rcv_nxt > ooseq->seqno, we must trim the first edge of the 01292 segment on ->ooseq before we adjust rcv_nxt. The data in the 01293 segments that are now on sequence are chained onto the 01294 incoming segment so that we only need to call the application 01295 once. 01296 */ 01297 01298 /* First, we check if we must trim the first edge. We have to do 01299 this if the sequence number of the incoming segment is less 01300 than rcv_nxt, and the sequence number plus the length of the 01301 segment is larger than rcv_nxt. */ 01302 /* if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)) { 01303 if (TCP_SEQ_LT(pcb->rcv_nxt, seqno + tcplen)) {*/ 01304 if (TCP_SEQ_BETWEEN(pcb->rcv_nxt, seqno + 1, seqno + tcplen - 1)) { 01305 /* Trimming the first edge is done by pushing the payload 01306 pointer in the pbuf downwards. This is somewhat tricky since 01307 we do not want to discard the full contents of the pbuf up to 01308 the new starting point of the data since we have to keep the 01309 TCP header which is present in the first pbuf in the chain. 01310 01311 What is done is really quite a nasty hack: the first pbuf in 01312 the pbuf chain is pointed to by inseg.p. Since we need to be 01313 able to deallocate the whole pbuf, we cannot change this 01314 inseg.p pointer to point to any of the later pbufs in the 01315 chain. Instead, we point the ->payload pointer in the first 01316 pbuf to data in one of the later pbufs. We also set the 01317 inseg.data pointer to point to the right place. This way, the 01318 ->p pointer will still point to the first pbuf, but the 01319 ->p->payload pointer will point to data in another pbuf. 01320 01321 After we are done with adjusting the pbuf pointers we must 01322 adjust the ->data pointer in the seg and the segment 01323 length.*/ 01324 01325 struct pbuf *p = inseg.p; 01326 off = pcb->rcv_nxt - seqno; 01327 LWIP_ASSERT("inseg.p != NULL", inseg.p); 01328 LWIP_ASSERT("insane offset!", (off < 0x7fff)); 01329 if (inseg.p->len < off) { 01330 LWIP_ASSERT("pbuf too short!", (((s32_t)inseg.p->tot_len) >= off)); 01331 new_tot_len = (u16_t)(inseg.p->tot_len - off); 01332 while (p->len < off) { 01333 off -= p->len; 01334 /* KJM following line changed (with addition of new_tot_len var) 01335 to fix bug #9076 01336 inseg.p->tot_len -= p->len; */ 01337 p->tot_len = new_tot_len; 01338 p->len = 0; 01339 p = p->next; 01340 } 01341 if (pbuf_header(p, (s16_t)-off)) { 01342 /* Do we need to cope with this failing? Assert for now */ 01343 LWIP_ASSERT("pbuf_header failed", 0); 01344 } 01345 } else { 01346 if (pbuf_header(inseg.p, (s16_t)-off)) { 01347 /* Do we need to cope with this failing? Assert for now */ 01348 LWIP_ASSERT("pbuf_header failed", 0); 01349 } 01350 } 01351 inseg.len -= (u16_t)(pcb->rcv_nxt - seqno); 01352 inseg.tcphdr->seqno = seqno = pcb->rcv_nxt; 01353 } 01354 else { 01355 if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)) { 01356 /* the whole segment is < rcv_nxt */ 01357 /* must be a duplicate of a packet that has already been correctly handled */ 01358 01359 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: duplicate seqno %"U32_F"\n", seqno)); 01360 tcp_ack_now(pcb); 01361 } 01362 } 01363 01364 /* The sequence number must be within the window (above rcv_nxt 01365 and below rcv_nxt + rcv_wnd) in order to be further 01366 processed. */ 01367 if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, 01368 pcb->rcv_nxt + pcb->rcv_wnd - 1)) { 01369 if (pcb->rcv_nxt == seqno) { 01370 /* The incoming segment is the next in sequence. We check if 01371 we have to trim the end of the segment and update rcv_nxt 01372 and pass the data to the application. */ 01373 tcplen = TCP_TCPLEN(&inseg); 01374 01375 if (tcplen > pcb->rcv_wnd) { 01376 LWIP_DEBUGF(TCP_INPUT_DEBUG, 01377 ("tcp_receive: other end overran receive window" 01378 "seqno %"U32_F" len %"U16_F" right edge %"U32_F"\n", 01379 seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd)); 01380 if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) { 01381 /* Must remove the FIN from the header as we're trimming 01382 * that byte of sequence-space from the packet */ 01383 TCPH_FLAGS_SET(inseg.tcphdr, TCPH_FLAGS(inseg.tcphdr) & ~(unsigned int)TCP_FIN); 01384 } 01385 /* Adjust length of segment to fit in the window. */ 01386 TCPWND_CHECK16(pcb->rcv_wnd); 01387 inseg.len = (u16_t)pcb->rcv_wnd; 01388 if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) { 01389 inseg.len -= 1; 01390 } 01391 pbuf_realloc(inseg.p, inseg.len); 01392 tcplen = TCP_TCPLEN(&inseg); 01393 LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n", 01394 (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd)); 01395 } 01396 #if TCP_QUEUE_OOSEQ 01397 /* Received in-sequence data, adjust ooseq data if: 01398 - FIN has been received or 01399 - inseq overlaps with ooseq */ 01400 if (pcb->ooseq != NULL) { 01401 if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) { 01402 LWIP_DEBUGF(TCP_INPUT_DEBUG, 01403 ("tcp_receive: received in-order FIN, binning ooseq queue\n")); 01404 /* Received in-order FIN means anything that was received 01405 * out of order must now have been received in-order, so 01406 * bin the ooseq queue */ 01407 while (pcb->ooseq != NULL) { 01408 struct tcp_seg *old_ooseq = pcb->ooseq; 01409 pcb->ooseq = pcb->ooseq->next; 01410 tcp_seg_free(old_ooseq); 01411 } 01412 } else { 01413 next = pcb->ooseq; 01414 /* Remove all segments on ooseq that are covered by inseg already. 01415 * FIN is copied from ooseq to inseg if present. */ 01416 while (next && 01417 TCP_SEQ_GEQ(seqno + tcplen, 01418 next->tcphdr->seqno + next->len)) { 01419 /* inseg cannot have FIN here (already processed above) */ 01420 if (TCPH_FLAGS(next->tcphdr) & TCP_FIN && 01421 (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) == 0) { 01422 TCPH_SET_FLAG(inseg.tcphdr, TCP_FIN); 01423 tcplen = TCP_TCPLEN(&inseg); 01424 } 01425 prev = next; 01426 next = next->next; 01427 tcp_seg_free(prev); 01428 } 01429 /* Now trim right side of inseg if it overlaps with the first 01430 * segment on ooseq */ 01431 if (next && 01432 TCP_SEQ_GT(seqno + tcplen, 01433 next->tcphdr->seqno)) { 01434 /* inseg cannot have FIN here (already processed above) */ 01435 inseg.len = (u16_t)(next->tcphdr->seqno - seqno); 01436 if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) { 01437 inseg.len -= 1; 01438 } 01439 pbuf_realloc(inseg.p, inseg.len); 01440 tcplen = TCP_TCPLEN(&inseg); 01441 LWIP_ASSERT("tcp_receive: segment not trimmed correctly to ooseq queue\n", 01442 (seqno + tcplen) == next->tcphdr->seqno); 01443 } 01444 pcb->ooseq = next; 01445 } 01446 } 01447 #endif /* TCP_QUEUE_OOSEQ */ 01448 01449 pcb->rcv_nxt = seqno + tcplen; 01450 01451 /* Update the receiver's (our) window. */ 01452 LWIP_ASSERT("tcp_receive: tcplen > rcv_wnd\n", pcb->rcv_wnd >= tcplen); 01453 pcb->rcv_wnd -= tcplen; 01454 01455 tcp_update_rcv_ann_wnd(pcb); 01456 01457 /* If there is data in the segment, we make preparations to 01458 pass this up to the application. The ->recv_data variable 01459 is used for holding the pbuf that goes to the 01460 application. The code for reassembling out-of-sequence data 01461 chains its data on this pbuf as well. 01462 01463 If the segment was a FIN, we set the TF_GOT_FIN flag that will 01464 be used to indicate to the application that the remote side has 01465 closed its end of the connection. */ 01466 if (inseg.p->tot_len > 0) { 01467 recv_data = inseg.p; 01468 /* Since this pbuf now is the responsibility of the 01469 application, we delete our reference to it so that we won't 01470 (mistakingly) deallocate it. */ 01471 inseg.p = NULL; 01472 } 01473 if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) { 01474 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN.\n")); 01475 recv_flags |= TF_GOT_FIN; 01476 } 01477 01478 #if TCP_QUEUE_OOSEQ 01479 /* We now check if we have segments on the ->ooseq queue that 01480 are now in sequence. */ 01481 while (pcb->ooseq != NULL && 01482 pcb->ooseq->tcphdr->seqno == pcb->rcv_nxt) { 01483 01484 cseg = pcb->ooseq; 01485 seqno = pcb->ooseq->tcphdr->seqno; 01486 01487 pcb->rcv_nxt += TCP_TCPLEN(cseg); 01488 LWIP_ASSERT("tcp_receive: ooseq tcplen > rcv_wnd\n", 01489 pcb->rcv_wnd >= TCP_TCPLEN(cseg)); 01490 pcb->rcv_wnd -= TCP_TCPLEN(cseg); 01491 01492 tcp_update_rcv_ann_wnd(pcb); 01493 01494 if (cseg->p->tot_len > 0) { 01495 /* Chain this pbuf onto the pbuf that we will pass to 01496 the application. */ 01497 /* With window scaling, this can overflow recv_data->tot_len, but 01498 that's not a problem since we explicitly fix that before passing 01499 recv_data to the application. */ 01500 if (recv_data) { 01501 pbuf_cat(recv_data, cseg->p); 01502 } else { 01503 recv_data = cseg->p; 01504 } 01505 cseg->p = NULL; 01506 } 01507 if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) { 01508 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN.\n")); 01509 recv_flags |= TF_GOT_FIN; 01510 if (pcb->state == ESTABLISHED) { /* force passive close or we can move to active close */ 01511 pcb->state = CLOSE_WAIT; 01512 } 01513 } 01514 01515 pcb->ooseq = cseg->next; 01516 tcp_seg_free(cseg); 01517 } 01518 #endif /* TCP_QUEUE_OOSEQ */ 01519 01520 01521 /* Acknowledge the segment(s). */ 01522 tcp_ack(pcb); 01523 01524 #if LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS 01525 if (ip_current_is_v6()) { 01526 /* Inform neighbor reachability of forward progress. */ 01527 nd6_reachability_hint(ip6_current_src_addr()); 01528 } 01529 #endif /* LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS*/ 01530 01531 } else { 01532 /* We get here if the incoming segment is out-of-sequence. */ 01533 tcp_send_empty_ack(pcb); 01534 #if TCP_QUEUE_OOSEQ 01535 /* We queue the segment on the ->ooseq queue. */ 01536 if (pcb->ooseq == NULL) { 01537 pcb->ooseq = tcp_seg_copy(&inseg); 01538 } else { 01539 /* If the queue is not empty, we walk through the queue and 01540 try to find a place where the sequence number of the 01541 incoming segment is between the sequence numbers of the 01542 previous and the next segment on the ->ooseq queue. That is 01543 the place where we put the incoming segment. If needed, we 01544 trim the second edges of the previous and the incoming 01545 segment so that it will fit into the sequence. 01546 01547 If the incoming segment has the same sequence number as a 01548 segment on the ->ooseq queue, we discard the segment that 01549 contains less data. */ 01550 01551 prev = NULL; 01552 for (next = pcb->ooseq; next != NULL; next = next->next) { 01553 if (seqno == next->tcphdr->seqno) { 01554 /* The sequence number of the incoming segment is the 01555 same as the sequence number of the segment on 01556 ->ooseq. We check the lengths to see which one to 01557 discard. */ 01558 if (inseg.len > next->len) { 01559 /* The incoming segment is larger than the old 01560 segment. We replace some segments with the new 01561 one. */ 01562 cseg = tcp_seg_copy(&inseg); 01563 if (cseg != NULL) { 01564 if (prev != NULL) { 01565 prev->next = cseg; 01566 } else { 01567 pcb->ooseq = cseg; 01568 } 01569 tcp_oos_insert_segment(cseg, next); 01570 } 01571 break; 01572 } else { 01573 /* Either the lengths are the same or the incoming 01574 segment was smaller than the old one; in either 01575 case, we ditch the incoming segment. */ 01576 break; 01577 } 01578 } else { 01579 if (prev == NULL) { 01580 if (TCP_SEQ_LT(seqno, next->tcphdr->seqno)) { 01581 /* The sequence number of the incoming segment is lower 01582 than the sequence number of the first segment on the 01583 queue. We put the incoming segment first on the 01584 queue. */ 01585 cseg = tcp_seg_copy(&inseg); 01586 if (cseg != NULL) { 01587 pcb->ooseq = cseg; 01588 tcp_oos_insert_segment(cseg, next); 01589 } 01590 break; 01591 } 01592 } else { 01593 /*if (TCP_SEQ_LT(prev->tcphdr->seqno, seqno) && 01594 TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {*/ 01595 if (TCP_SEQ_BETWEEN(seqno, prev->tcphdr->seqno+1, next->tcphdr->seqno-1)) { 01596 /* The sequence number of the incoming segment is in 01597 between the sequence numbers of the previous and 01598 the next segment on ->ooseq. We trim trim the previous 01599 segment, delete next segments that included in received segment 01600 and trim received, if needed. */ 01601 cseg = tcp_seg_copy(&inseg); 01602 if (cseg != NULL) { 01603 if (TCP_SEQ_GT(prev->tcphdr->seqno + prev->len, seqno)) { 01604 /* We need to trim the prev segment. */ 01605 prev->len = (u16_t)(seqno - prev->tcphdr->seqno); 01606 pbuf_realloc(prev->p, prev->len); 01607 } 01608 prev->next = cseg; 01609 tcp_oos_insert_segment(cseg, next); 01610 } 01611 break; 01612 } 01613 } 01614 /* If the "next" segment is the last segment on the 01615 ooseq queue, we add the incoming segment to the end 01616 of the list. */ 01617 if (next->next == NULL && 01618 TCP_SEQ_GT(seqno, next->tcphdr->seqno)) { 01619 if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) { 01620 /* segment "next" already contains all data */ 01621 break; 01622 } 01623 next->next = tcp_seg_copy(&inseg); 01624 if (next->next != NULL) { 01625 if (TCP_SEQ_GT(next->tcphdr->seqno + next->len, seqno)) { 01626 /* We need to trim the last segment. */ 01627 next->len = (u16_t)(seqno - next->tcphdr->seqno); 01628 pbuf_realloc(next->p, next->len); 01629 } 01630 /* check if the remote side overruns our receive window */ 01631 if (TCP_SEQ_GT((u32_t)tcplen + seqno, pcb->rcv_nxt + (u32_t)pcb->rcv_wnd)) { 01632 LWIP_DEBUGF(TCP_INPUT_DEBUG, 01633 ("tcp_receive: other end overran receive window" 01634 "seqno %"U32_F" len %"U16_F" right edge %"U32_F"\n", 01635 seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd)); 01636 if (TCPH_FLAGS(next->next->tcphdr) & TCP_FIN) { 01637 /* Must remove the FIN from the header as we're trimming 01638 * that byte of sequence-space from the packet */ 01639 TCPH_FLAGS_SET(next->next->tcphdr, TCPH_FLAGS(next->next->tcphdr) & ~TCP_FIN); 01640 } 01641 /* Adjust length of segment to fit in the window. */ 01642 next->next->len = (u16_t)(pcb->rcv_nxt + pcb->rcv_wnd - seqno); 01643 pbuf_realloc(next->next->p, next->next->len); 01644 tcplen = TCP_TCPLEN(next->next); 01645 LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n", 01646 (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd)); 01647 } 01648 } 01649 break; 01650 } 01651 } 01652 prev = next; 01653 } 01654 } 01655 #if TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS 01656 /* Check that the data on ooseq doesn't exceed one of the limits 01657 and throw away everything above that limit. */ 01658 ooseq_blen = 0; 01659 ooseq_qlen = 0; 01660 prev = NULL; 01661 for (next = pcb->ooseq; next != NULL; prev = next, next = next->next) { 01662 struct pbuf *p = next->p; 01663 ooseq_blen += p->tot_len; 01664 ooseq_qlen += pbuf_clen(p); 01665 if ((ooseq_blen > TCP_OOSEQ_MAX_BYTES) || 01666 (ooseq_qlen > TCP_OOSEQ_MAX_PBUFS)) { 01667 /* too much ooseq data, dump this and everything after it */ 01668 tcp_segs_free(next); 01669 if (prev == NULL) { 01670 /* first ooseq segment is too much, dump the whole queue */ 01671 pcb->ooseq = NULL; 01672 } else { 01673 /* just dump 'next' and everything after it */ 01674 prev->next = NULL; 01675 } 01676 break; 01677 } 01678 } 01679 #endif /* TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS */ 01680 #endif /* TCP_QUEUE_OOSEQ */ 01681 } 01682 } else { 01683 /* The incoming segment is not within the window. */ 01684 tcp_send_empty_ack(pcb); 01685 } 01686 } else { 01687 /* Segments with length 0 is taken care of here. Segments that 01688 fall out of the window are ACKed. */ 01689 if (!TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd - 1)) { 01690 tcp_ack_now(pcb); 01691 } 01692 } 01693 } 01694 01695 static u8_t 01696 tcp_getoptbyte(void) 01697 { 01698 if ((tcphdr_opt2 == NULL) || (tcp_optidx < tcphdr_opt1len)) { 01699 u8_t* opts = (u8_t *)tcphdr + TCP_HLEN; 01700 return opts[tcp_optidx++]; 01701 } else { 01702 u8_t idx = (u8_t)(tcp_optidx++ - tcphdr_opt1len); 01703 return tcphdr_opt2[idx]; 01704 } 01705 } 01706 01707 /** 01708 * Parses the options contained in the incoming segment. 01709 * 01710 * Called from tcp_listen_input() and tcp_process(). 01711 * Currently, only the MSS option is supported! 01712 * 01713 * @param pcb the tcp_pcb for which a segment arrived 01714 */ 01715 static void 01716 tcp_parseopt(struct tcp_pcb *pcb) 01717 { 01718 u8_t data; 01719 u16_t mss; 01720 #if LWIP_TCP_TIMESTAMPS 01721 u32_t tsval; 01722 #endif 01723 01724 /* Parse the TCP MSS option, if present. */ 01725 if (tcphdr_optlen != 0) { 01726 for (tcp_optidx = 0; tcp_optidx < tcphdr_optlen; ) { 01727 u8_t opt = tcp_getoptbyte(); 01728 switch (opt) { 01729 case LWIP_TCP_OPT_EOL: 01730 /* End of options. */ 01731 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: EOL\n")); 01732 return; 01733 case LWIP_TCP_OPT_NOP: 01734 /* NOP option. */ 01735 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: NOP\n")); 01736 break; 01737 case LWIP_TCP_OPT_MSS: 01738 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: MSS\n")); 01739 if (tcp_getoptbyte() != LWIP_TCP_OPT_LEN_MSS || (tcp_optidx - 2 + LWIP_TCP_OPT_LEN_MSS) > tcphdr_optlen) { 01740 /* Bad length */ 01741 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n")); 01742 return; 01743 } 01744 /* An MSS option with the right option length. */ 01745 mss = (tcp_getoptbyte() << 8); 01746 mss |= tcp_getoptbyte(); 01747 /* Limit the mss to the configured TCP_MSS and prevent division by zero */ 01748 pcb->mss = ((mss > TCP_MSS) || (mss == 0)) ? TCP_MSS : mss; 01749 break; 01750 #if LWIP_WND_SCALE 01751 case LWIP_TCP_OPT_WS: 01752 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: WND_SCALE\n")); 01753 if (tcp_getoptbyte() != LWIP_TCP_OPT_LEN_WS || (tcp_optidx - 2 + LWIP_TCP_OPT_LEN_WS) > tcphdr_optlen) { 01754 /* Bad length */ 01755 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n")); 01756 return; 01757 } 01758 /* If syn was received with wnd scale option, 01759 activate wnd scale opt, but only if this is not a retransmission */ 01760 if ((flags & TCP_SYN) && !(pcb->flags & TF_WND_SCALE)) { 01761 /* An WND_SCALE option with the right option length. */ 01762 data = tcp_getoptbyte(); 01763 pcb->snd_scale = data; 01764 if (pcb->snd_scale > 14U) { 01765 pcb->snd_scale = 14U; 01766 } 01767 pcb->rcv_scale = TCP_RCV_SCALE; 01768 pcb->flags |= TF_WND_SCALE; 01769 /* window scaling is enabled, we can use the full receive window */ 01770 LWIP_ASSERT("window not at default value", pcb->rcv_wnd == TCPWND_MIN16(TCP_WND)); 01771 LWIP_ASSERT("window not at default value", pcb->rcv_ann_wnd == TCPWND_MIN16(TCP_WND)); 01772 pcb->rcv_wnd = pcb->rcv_ann_wnd = TCP_WND; 01773 } 01774 break; 01775 #endif 01776 #if LWIP_TCP_TIMESTAMPS 01777 case LWIP_TCP_OPT_TS: 01778 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: TS\n")); 01779 if (tcp_getoptbyte() != LWIP_TCP_OPT_LEN_TS || (tcp_optidx - 2 + LWIP_TCP_OPT_LEN_TS) > tcphdr_optlen) { 01780 /* Bad length */ 01781 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n")); 01782 return; 01783 } 01784 /* TCP timestamp option with valid length */ 01785 tsval = tcp_getoptbyte(); 01786 tsval |= (tcp_getoptbyte() << 8); 01787 tsval |= (tcp_getoptbyte() << 16); 01788 tsval |= (tcp_getoptbyte() << 24); 01789 if (flags & TCP_SYN) { 01790 pcb->ts_recent = lwip_ntohl(tsval); 01791 /* Enable sending timestamps in every segment now that we know 01792 the remote host supports it. */ 01793 pcb->flags |= TF_TIMESTAMP; 01794 } else if (TCP_SEQ_BETWEEN(pcb->ts_lastacksent, seqno, seqno+tcplen)) { 01795 pcb->ts_recent = lwip_ntohl(tsval); 01796 } 01797 /* Advance to next option (6 bytes already read) */ 01798 tcp_optidx += LWIP_TCP_OPT_LEN_TS - 6; 01799 break; 01800 #endif 01801 default: 01802 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: other\n")); 01803 data = tcp_getoptbyte(); 01804 if (data < 2) { 01805 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n")); 01806 /* If the length field is zero, the options are malformed 01807 and we don't process them further. */ 01808 return; 01809 } 01810 /* All other options have a length field, so that we easily 01811 can skip past them. */ 01812 tcp_optidx += data - 2; 01813 } 01814 } 01815 } 01816 } 01817 01818 void 01819 tcp_trigger_input_pcb_close(void) 01820 { 01821 recv_flags |= TF_CLOSED; 01822 } 01823 01824 #endif /* LWIP_TCP */
Generated on Tue Jul 12 2022 11:02:28 by
1.7.2