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