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