1/** 2 * @file 3 * Transmission Control Protocol, incoming traffic 4 * 5 * The input processing functions of the TCP layer. 6 * 7 * These functions are generally called in the order (ip_input() ->) 8 * tcp_input() -> * tcp_process() -> tcp_receive() (-> application). 9 * 10 */ 11 12/* 13 * Copyright (c) 2001-2004 Swedish Institute of Computer Science. 14 * All rights reserved. 15 * 16 * Redistribution and use in source and binary forms, with or without modification, 17 * are permitted provided that the following conditions are met: 18 * 19 * 1. Redistributions of source code must retain the above copyright notice, 20 * this list of conditions and the following disclaimer. 21 * 2. Redistributions in binary form must reproduce the above copyright notice, 22 * this list of conditions and the following disclaimer in the documentation 23 * and/or other materials provided with the distribution. 24 * 3. The name of the author may not be used to endorse or promote products 25 * derived from this software without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 28 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 29 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 30 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 31 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 32 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 35 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 36 * OF SUCH DAMAGE. 37 * 38 * This file is part of the lwIP TCP/IP stack. 39 * 40 * Author: Adam Dunkels <adam@sics.se> 41 * 42 */ 43 44#include "lwip/opt.h" 45 46#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ 47 48#include "lwip/tcp_impl.h" 49#include "lwip/def.h" 50#include "lwip/ip_addr.h" 51#include "lwip/netif.h" 52#include "lwip/mem.h" 53#include "lwip/memp.h" 54#include "lwip/inet_chksum.h" 55#include "lwip/stats.h" 56#include "lwip/snmp.h" 57#include "arch/perf.h" 58 59/* These variables are global to all functions involved in the input 60 processing of TCP segments. They are set by the tcp_input() 61 function. */ 62static struct tcp_seg inseg; 63static struct tcp_hdr *tcphdr; 64static struct ip_hdr *iphdr; 65static u32_t seqno, ackno; 66static u8_t flags; 67static u16_t tcplen; 68 69static u8_t recv_flags; 70static struct pbuf *recv_data; 71 72struct tcp_pcb *tcp_input_pcb; 73 74/* Forward declarations. */ 75static err_t tcp_process(struct tcp_pcb *pcb); 76static void tcp_receive(struct tcp_pcb *pcb); 77static void tcp_parseopt(struct tcp_pcb *pcb); 78 79static err_t tcp_listen_input(struct tcp_pcb_listen *pcb); 80static err_t tcp_timewait_input(struct tcp_pcb *pcb); 81 82/** 83 * The initial input processing of TCP. It verifies the TCP header, demultiplexes 84 * the segment between the PCBs and passes it on to tcp_process(), which implements 85 * the TCP finite state machine. This function is called by the IP layer (in 86 * ip_input()). 87 * 88 * @param p received TCP segment to process (p->payload pointing to the IP header) 89 * @param inp network interface on which this segment was received 90 */ 91void 92tcp_input(struct pbuf *p, struct netif *inp) 93{ 94 struct tcp_pcb *pcb, *prev; 95 struct tcp_pcb_listen *lpcb; 96#if SO_REUSE 97 struct tcp_pcb *lpcb_prev = NULL; 98 struct tcp_pcb_listen *lpcb_any = NULL; 99#endif /* SO_REUSE */ 100 u8_t hdrlen; 101 err_t err; 102 103 PERF_START; 104 105 TCP_STATS_INC(tcp.recv); 106 snmp_inc_tcpinsegs(); 107 108 iphdr = (struct ip_hdr *)p->payload; 109 tcphdr = (struct tcp_hdr *)((u8_t *)p->payload + IPH_HL(iphdr) * 4); 110 111#if TCP_INPUT_DEBUG 112 tcp_debug_print(tcphdr); 113#endif 114 115 /* remove header from payload */ 116 if (pbuf_header(p, -((s16_t)(IPH_HL(iphdr) * 4))) || (p->tot_len < sizeof(struct tcp_hdr))) { 117 /* drop short packets */ 118 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet (%"U16_F" bytes) discarded\n", p->tot_len)); 119 TCP_STATS_INC(tcp.lenerr); 120 TCP_STATS_INC(tcp.drop); 121 snmp_inc_tcpinerrs(); 122 pbuf_free(p); 123 return; 124 } 125 126 /* Don't even process incoming broadcasts/multicasts. */ 127 if (ip_addr_isbroadcast(¤t_iphdr_dest, inp) || 128 ip_addr_ismulticast(¤t_iphdr_dest)) { 129 TCP_STATS_INC(tcp.proterr); 130 TCP_STATS_INC(tcp.drop); 131 snmp_inc_tcpinerrs(); 132 pbuf_free(p); 133 return; 134 } 135 136#if CHECKSUM_CHECK_TCP 137 /* Verify TCP checksum. */ 138 if (inet_chksum_pseudo(p, ip_current_src_addr(), ip_current_dest_addr(), 139 IP_PROTO_TCP, p->tot_len) != 0) { 140 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packet discarded due to failing checksum 0x%04"X16_F"\n", 141 inet_chksum_pseudo(p, ip_current_src_addr(), ip_current_dest_addr(), 142 IP_PROTO_TCP, p->tot_len))); 143#if TCP_DEBUG 144 tcp_debug_print(tcphdr); 145#endif /* TCP_DEBUG */ 146 TCP_STATS_INC(tcp.chkerr); 147 TCP_STATS_INC(tcp.drop); 148 snmp_inc_tcpinerrs(); 149 pbuf_free(p); 150 return; 151 } 152#endif 153 154 /* Move the payload pointer in the pbuf so that it points to the 155 TCP data instead of the TCP header. */ 156 hdrlen = TCPH_HDRLEN(tcphdr); 157 if(pbuf_header(p, -(hdrlen * 4))){ 158 /* drop short packets */ 159 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet\n")); 160 TCP_STATS_INC(tcp.lenerr); 161 TCP_STATS_INC(tcp.drop); 162 snmp_inc_tcpinerrs(); 163 pbuf_free(p); 164 return; 165 } 166 167 /* Convert fields in TCP header to host byte order. */ 168 tcphdr->src = ntohs(tcphdr->src); 169 tcphdr->dest = ntohs(tcphdr->dest); 170 seqno = tcphdr->seqno = ntohl(tcphdr->seqno); 171 ackno = tcphdr->ackno = ntohl(tcphdr->ackno); 172 tcphdr->wnd = ntohs(tcphdr->wnd); 173 174 flags = TCPH_FLAGS(tcphdr); 175 tcplen = p->tot_len + ((flags & (TCP_FIN | TCP_SYN)) ? 1 : 0); 176 177 /* Demultiplex an incoming segment. First, we check if it is destined 178 for an active connection. */ 179 prev = NULL; 180 181 182 for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { 183 LWIP_ASSERT("tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED); 184 LWIP_ASSERT("tcp_input: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT); 185 LWIP_ASSERT("tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN); 186 if (pcb->remote_port == tcphdr->src && 187 pcb->local_port == tcphdr->dest && 188 ip_addr_cmp(&(pcb->remote_ip), ¤t_iphdr_src) && 189 ip_addr_cmp(&(pcb->local_ip), ¤t_iphdr_dest)) { 190 191 /* Move this PCB to the front of the list so that subsequent 192 lookups will be faster (we exploit locality in TCP segment 193 arrivals). */ 194 LWIP_ASSERT("tcp_input: pcb->next != pcb (before cache)", pcb->next != pcb); 195 if (prev != NULL) { 196 prev->next = pcb->next; 197 pcb->next = tcp_active_pcbs; 198 tcp_active_pcbs = pcb; 199 } 200 LWIP_ASSERT("tcp_input: pcb->next != pcb (after cache)", pcb->next != pcb); 201 break; 202 } 203 prev = pcb; 204 } 205 206 if (pcb == NULL) { 207 /* If it did not go to an active connection, we check the connections 208 in the TIME-WAIT state. */ 209 for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { 210 LWIP_ASSERT("tcp_input: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT); 211 if (pcb->remote_port == tcphdr->src && 212 pcb->local_port == tcphdr->dest && 213 ip_addr_cmp(&(pcb->remote_ip), ¤t_iphdr_src) && 214 ip_addr_cmp(&(pcb->local_ip), ¤t_iphdr_dest)) { 215 /* We don't really care enough to move this PCB to the front 216 of the list since we are not very likely to receive that 217 many segments for connections in TIME-WAIT. */ 218 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for TIME_WAITing connection.\n")); 219 tcp_timewait_input(pcb); 220 pbuf_free(p); 221 return; 222 } 223 } 224 225 /* Finally, if we still did not get a match, we check all PCBs that 226 are LISTENing for incoming connections. */ 227 prev = NULL; 228 for(lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { 229 if (lpcb->local_port == tcphdr->dest) { 230#if SO_REUSE 231 if (ip_addr_cmp(&(lpcb->local_ip), ¤t_iphdr_dest)) { 232 /* found an exact match */ 233 break; 234 } else if(ip_addr_isany(&(lpcb->local_ip))) { 235 /* found an ANY-match */ 236 lpcb_any = lpcb; 237 lpcb_prev = prev; 238 } 239#else /* SO_REUSE */ 240 if (ip_addr_cmp(&(lpcb->local_ip), ¤t_iphdr_dest) || 241 ip_addr_isany(&(lpcb->local_ip))) { 242 /* found a match */ 243 break; 244 } 245#endif /* SO_REUSE */ 246 } 247 prev = (struct tcp_pcb *)lpcb; 248 } 249#if SO_REUSE 250 /* first try specific local IP */ 251 if (lpcb == NULL) { 252 /* only pass to ANY if no specific local IP has been found */ 253 lpcb = lpcb_any; 254 prev = lpcb_prev; 255 } 256#endif /* SO_REUSE */ 257 if (lpcb != NULL) { 258 /* Move this PCB to the front of the list so that subsequent 259 lookups will be faster (we exploit locality in TCP segment 260 arrivals). */ 261 if (prev != NULL) { 262 ((struct tcp_pcb_listen *)prev)->next = lpcb->next; 263 /* our successor is the remainder of the listening list */ 264 lpcb->next = tcp_listen_pcbs.listen_pcbs; 265 /* put this listening pcb at the head of the listening list */ 266 tcp_listen_pcbs.listen_pcbs = lpcb; 267 } 268 269 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for LISTENing connection.\n")); 270 tcp_listen_input(lpcb); 271 pbuf_free(p); 272 return; 273 } 274 } 275 276#if TCP_INPUT_DEBUG 277 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("+-+-+-+-+-+-+-+-+-+-+-+-+-+- tcp_input: flags ")); 278 tcp_debug_print_flags(TCPH_FLAGS(tcphdr)); 279 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n")); 280#endif /* TCP_INPUT_DEBUG */ 281 282 283 if (pcb != NULL) { 284 /* The incoming segment belongs to a connection. */ 285#if TCP_INPUT_DEBUG 286#if TCP_DEBUG 287 tcp_debug_print_state(pcb->state); 288#endif /* TCP_DEBUG */ 289#endif /* TCP_INPUT_DEBUG */ 290 291 /* Set up a tcp_seg structure. */ 292 inseg.next = NULL; 293 inseg.len = p->tot_len; 294 inseg.p = p; 295 inseg.tcphdr = tcphdr; 296 297 recv_data = NULL; 298 recv_flags = 0; 299 300 /* If there is data which was previously "refused" by upper layer */ 301 if (pcb->refused_data != NULL) { 302 /* Notify again application with data previously received. */ 303 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: notify kept packet\n")); 304 TCP_EVENT_RECV(pcb, pcb->refused_data, ERR_OK, err); 305 if (err == ERR_OK) { 306 pcb->refused_data = NULL; 307 } else if ((err == ERR_ABRT) || (tcplen > 0)) { 308 /* if err == ERR_ABRT, 'pcb' is already deallocated */ 309 /* Drop incoming packets because pcb is "full" (only if the incoming 310 segment contains data). */ 311 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: drop incoming packets, because pcb is \"full\"\n")); 312 TCP_STATS_INC(tcp.drop); 313 snmp_inc_tcpinerrs(); 314 pbuf_free(p); 315 return; 316 } 317 } 318 tcp_input_pcb = pcb; 319 err = tcp_process(pcb); 320 /* A return value of ERR_ABRT means that tcp_abort() was called 321 and that the pcb has been freed. If so, we don't do anything. */ 322 if (err != ERR_ABRT) { 323 if (recv_flags & TF_RESET) { 324 /* TF_RESET means that the connection was reset by the other 325 end. We then call the error callback to inform the 326 application that the connection is dead before we 327 deallocate the PCB. */ 328 TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_RST); 329 tcp_pcb_remove(&tcp_active_pcbs, pcb); 330 memp_free(MEMP_TCP_PCB, pcb); 331 } else if (recv_flags & TF_CLOSED) { 332 /* The connection has been closed and we will deallocate the 333 PCB. */ 334 tcp_pcb_remove(&tcp_active_pcbs, pcb); 335 memp_free(MEMP_TCP_PCB, pcb); 336 } else { 337 err = ERR_OK; 338 /* If the application has registered a "sent" function to be 339 called when new send buffer space is available, we call it 340 now. */ 341 if (pcb->acked > 0) { 342 TCP_EVENT_SENT(pcb, pcb->acked, err); 343 if (err == ERR_ABRT) { 344 goto aborted; 345 } 346 } 347 348 if (recv_data != NULL) { 349 LWIP_ASSERT("pcb->refused_data == NULL", pcb->refused_data == NULL); 350 if (pcb->flags & TF_RXCLOSED) { 351 /* received data although already closed -> abort (send RST) to 352 notify the remote host that not all data has been processed */ 353 pbuf_free(recv_data); 354 tcp_abort(pcb); 355 goto aborted; 356 } 357 if (flags & TCP_PSH) { 358 recv_data->flags |= PBUF_FLAG_PUSH; 359 } 360 361 /* Notify application that data has been received. */ 362 TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err); 363 if (err == ERR_ABRT) { 364 goto aborted; 365 } 366 367 /* If the upper layer can't receive this data, store it */ 368 if (err != ERR_OK) { 369 pcb->refused_data = recv_data; 370 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: keep incoming packet, because pcb is \"full\"\n")); 371 } 372 } 373 374 /* If a FIN segment was received, we call the callback 375 function with a NULL buffer to indicate EOF. */ 376 if (recv_flags & TF_GOT_FIN) { 377 /* correct rcv_wnd as the application won't call tcp_recved() 378 for the FIN's seqno */ 379 if (pcb->rcv_wnd != TCP_WND) { 380 pcb->rcv_wnd++; 381 } 382 TCP_EVENT_CLOSED(pcb, err); 383 if (err == ERR_ABRT) { 384 goto aborted; 385 } 386 } 387 388 tcp_input_pcb = NULL; 389 /* Try to send something out. */ 390 tcp_output(pcb); 391#if TCP_INPUT_DEBUG 392#if TCP_DEBUG 393 tcp_debug_print_state(pcb->state); 394#endif /* TCP_DEBUG */ 395#endif /* TCP_INPUT_DEBUG */ 396 } 397 } 398 /* Jump target if pcb has been aborted in a callback (by calling tcp_abort()). 399 Below this line, 'pcb' may not be dereferenced! */ 400aborted: 401 tcp_input_pcb = NULL; 402 recv_data = NULL; 403 404 /* give up our reference to inseg.p */ 405 if (inseg.p != NULL) 406 { 407 pbuf_free(inseg.p); 408 inseg.p = NULL; 409 } 410 } else { 411 412 /* If no matching PCB was found, send a TCP RST (reset) to the 413 sender. */ 414 LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_input: no PCB match found, resetting.\n")); 415 if (!(TCPH_FLAGS(tcphdr) & TCP_RST)) { 416 TCP_STATS_INC(tcp.proterr); 417 TCP_STATS_INC(tcp.drop); 418 tcp_rst(ackno, seqno + tcplen, 419 ip_current_dest_addr(), ip_current_src_addr(), 420 tcphdr->dest, tcphdr->src); 421 } 422 pbuf_free(p); 423 } 424 425 LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane()); 426 PERF_STOP("tcp_input"); 427} 428 429/** 430 * Called by tcp_input() when a segment arrives for a listening 431 * connection (from tcp_input()). 432 * 433 * @param pcb the tcp_pcb_listen for which a segment arrived 434 * @return ERR_OK if the segment was processed 435 * another err_t on error 436 * 437 * @note the return value is not (yet?) used in tcp_input() 438 * @note the segment which arrived is saved in global variables, therefore only the pcb 439 * involved is passed as a parameter to this function 440 */ 441static err_t 442tcp_listen_input(struct tcp_pcb_listen *pcb) 443{ 444 struct tcp_pcb *npcb; 445 err_t rc; 446 447 /* In the LISTEN state, we check for incoming SYN segments, 448 creates a new PCB, and responds with a SYN|ACK. */ 449 if (flags & TCP_ACK) { 450 /* For incoming segments with the ACK flag set, respond with a 451 RST. */ 452 LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_listen_input: ACK in LISTEN, sending reset\n")); 453 tcp_rst(ackno + 1, seqno + tcplen, 454 ip_current_dest_addr(), ip_current_src_addr(), 455 tcphdr->dest, tcphdr->src); 456 } else if (flags & TCP_SYN) { 457 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection request %"U16_F" -> %"U16_F".\n", tcphdr->src, tcphdr->dest)); 458#if TCP_LISTEN_BACKLOG 459 if (pcb->accepts_pending >= pcb->backlog) { 460 LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: listen backlog exceeded for port %"U16_F"\n", tcphdr->dest)); 461 return ERR_ABRT; 462 } 463#endif /* TCP_LISTEN_BACKLOG */ 464 npcb = tcp_alloc(pcb->prio); 465 /* If a new PCB could not be created (probably due to lack of memory), 466 we don't do anything, but rely on the sender will retransmit the 467 SYN at a time when we have more memory available. */ 468 if (npcb == NULL) { 469 LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: could not allocate PCB\n")); 470 TCP_STATS_INC(tcp.memerr); 471 return ERR_MEM; 472 } 473#if TCP_LISTEN_BACKLOG 474 pcb->accepts_pending++; 475#endif /* TCP_LISTEN_BACKLOG */ 476 /* Set up the new PCB. */ 477 ip_addr_copy(npcb->local_ip, current_iphdr_dest); 478 npcb->local_port = pcb->local_port; 479 ip_addr_copy(npcb->remote_ip, current_iphdr_src); 480 npcb->remote_port = tcphdr->src; 481 npcb->state = SYN_RCVD; 482 npcb->rcv_nxt = seqno + 1; 483 npcb->rcv_ann_right_edge = npcb->rcv_nxt; 484 npcb->snd_wnd = tcphdr->wnd; 485 npcb->ssthresh = npcb->snd_wnd; 486 npcb->snd_wl1 = seqno - 1;/* initialise to seqno-1 to force window update */ 487 npcb->callback_arg = pcb->callback_arg; 488#if LWIP_CALLBACK_API 489 npcb->accept = pcb->accept; 490#endif /* LWIP_CALLBACK_API */ 491 /* inherit socket options */ 492 npcb->so_options = pcb->so_options & SOF_INHERITED; 493 /* Register the new PCB so that we can begin receiving segments 494 for it. */ 495 TCP_REG(&tcp_active_pcbs, npcb); 496 497 /* Parse any options in the SYN. */ 498 tcp_parseopt(npcb); 499#if TCP_CALCULATE_EFF_SEND_MSS 500 npcb->mss = tcp_eff_send_mss(npcb->mss, &(npcb->remote_ip)); 501#endif /* TCP_CALCULATE_EFF_SEND_MSS */ 502 503 snmp_inc_tcppassiveopens(); 504 505 /* Send a SYN|ACK together with the MSS option. */ 506 rc = tcp_enqueue_flags(npcb, TCP_SYN | TCP_ACK); 507 if (rc != ERR_OK) { 508 tcp_abandon(npcb, 0); 509 return rc; 510 } 511 return tcp_output(npcb); 512 } 513 return ERR_OK; 514} 515 516/** 517 * Called by tcp_input() when a segment arrives for a connection in 518 * TIME_WAIT. 519 * 520 * @param pcb the tcp_pcb for which a segment arrived 521 * 522 * @note the segment which arrived is saved in global variables, therefore only the pcb 523 * involved is passed as a parameter to this function 524 */ 525static err_t 526tcp_timewait_input(struct tcp_pcb *pcb) 527{ 528 /* RFC 1337: in TIME_WAIT, ignore RST and ACK FINs + any 'acceptable' segments */ 529 /* RFC 793 3.9 Event Processing - Segment Arrives: 530 * - first check sequence number - we skip that one in TIME_WAIT (always 531 * acceptable since we only send ACKs) 532 * - second check the RST bit (... return) */ 533 if (flags & TCP_RST) { 534 return ERR_OK; 535 } 536 /* - fourth, check the SYN bit, */ 537 if (flags & TCP_SYN) { 538 /* If an incoming segment is not acceptable, an acknowledgment 539 should be sent in reply */ 540 if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt+pcb->rcv_wnd)) { 541 /* If the SYN is in the window it is an error, send a reset */ 542 tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(), 543 tcphdr->dest, tcphdr->src); 544 return ERR_OK; 545 } 546 } else if (flags & TCP_FIN) { 547 /* - eighth, check the FIN bit: Remain in the TIME-WAIT state. 548 Restart the 2 MSL time-wait timeout.*/ 549 pcb->tmr = tcp_ticks; 550 } 551 552 if ((tcplen > 0)) { 553 /* Acknowledge data, FIN or out-of-window SYN */ 554 pcb->flags |= TF_ACK_NOW; 555 return tcp_output(pcb); 556 } 557 return ERR_OK; 558} 559 560/** 561 * Implements the TCP state machine. Called by tcp_input. In some 562 * states tcp_receive() is called to receive data. The tcp_seg 563 * argument will be freed by the caller (tcp_input()) unless the 564 * recv_data pointer in the pcb is set. 565 * 566 * @param pcb the tcp_pcb for which a segment arrived 567 * 568 * @note the segment which arrived is saved in global variables, therefore only the pcb 569 * involved is passed as a parameter to this function 570 */ 571static err_t 572tcp_process(struct tcp_pcb *pcb) 573{ 574 struct tcp_seg *rseg; 575 u8_t acceptable = 0; 576 err_t err; 577 578 err = ERR_OK; 579 580 /* Process incoming RST segments. */ 581 if (flags & TCP_RST) { 582 /* First, determine if the reset is acceptable. */ 583 if (pcb->state == SYN_SENT) { 584 if (ackno == pcb->snd_nxt) { 585 acceptable = 1; 586 } 587 } else { 588 if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, 589 pcb->rcv_nxt+pcb->rcv_wnd)) { 590 acceptable = 1; 591 } 592 } 593 594 if (acceptable) { 595 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: Connection RESET\n")); 596 LWIP_ASSERT("tcp_input: pcb->state != CLOSED", pcb->state != CLOSED); 597 recv_flags |= TF_RESET; 598 pcb->flags &= ~TF_ACK_DELAY; 599 return ERR_RST; 600 } else { 601 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n", 602 seqno, pcb->rcv_nxt)); 603 LWIP_DEBUGF(TCP_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n", 604 seqno, pcb->rcv_nxt)); 605 return ERR_OK; 606 } 607 } 608 609 if ((flags & TCP_SYN) && (pcb->state != SYN_SENT && pcb->state != SYN_RCVD)) { 610 /* Cope with new connection attempt after remote end crashed */ 611 tcp_ack_now(pcb); 612 return ERR_OK; 613 } 614 615 if ((pcb->flags & TF_RXCLOSED) == 0) { 616 /* Update the PCB (in)activity timer unless rx is closed (see tcp_shutdown) */ 617 pcb->tmr = tcp_ticks; 618 } 619 pcb->keep_cnt_sent = 0; 620 621 tcp_parseopt(pcb); 622 623 /* Do different things depending on the TCP state. */ 624 switch (pcb->state) { 625 case SYN_SENT: 626 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %"U32_F" pcb->snd_nxt %"U32_F" unacked %"U32_F"\n", ackno, 627 pcb->snd_nxt, ntohl(pcb->unacked->tcphdr->seqno))); 628 /* received SYN ACK with expected sequence number? */ 629 if ((flags & TCP_ACK) && (flags & TCP_SYN) 630 && ackno == ntohl(pcb->unacked->tcphdr->seqno) + 1) { 631 pcb->snd_buf++; 632 pcb->rcv_nxt = seqno + 1; 633 pcb->rcv_ann_right_edge = pcb->rcv_nxt; 634 pcb->lastack = ackno; 635 pcb->snd_wnd = tcphdr->wnd; 636 pcb->snd_wl1 = seqno - 1; /* initialise to seqno - 1 to force window update */ 637 pcb->state = ESTABLISHED; 638 639#if TCP_CALCULATE_EFF_SEND_MSS 640 pcb->mss = tcp_eff_send_mss(pcb->mss, &(pcb->remote_ip)); 641#endif /* TCP_CALCULATE_EFF_SEND_MSS */ 642 643 /* Set ssthresh again after changing pcb->mss (already set in tcp_connect 644 * but for the default value of pcb->mss) */ 645 pcb->ssthresh = pcb->mss * 10; 646 647 pcb->cwnd = ((pcb->cwnd == 1) ? (pcb->mss * 2) : pcb->mss); 648 LWIP_ASSERT("pcb->snd_queuelen > 0", (pcb->snd_queuelen > 0)); 649 --pcb->snd_queuelen; 650 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_process: SYN-SENT --queuelen %"U16_F"\n", (u16_t)pcb->snd_queuelen)); 651 rseg = pcb->unacked; 652 pcb->unacked = rseg->next; 653 654 /* If there's nothing left to acknowledge, stop the retransmit 655 timer, otherwise reset it to start again */ 656 if(pcb->unacked == NULL) 657 pcb->rtime = -1; 658 else { 659 pcb->rtime = 0; 660 pcb->nrtx = 0; 661 } 662 663 tcp_seg_free(rseg); 664 665 /* Call the user specified function to call when sucessfully 666 * connected. */ 667 TCP_EVENT_CONNECTED(pcb, ERR_OK, err); 668 if (err == ERR_ABRT) { 669 return ERR_ABRT; 670 } 671 tcp_ack_now(pcb); 672 } 673 /* received ACK? possibly a half-open connection */ 674 else if (flags & TCP_ACK) { 675 /* send a RST to bring the other side in a non-synchronized state. */ 676 tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(), 677 tcphdr->dest, tcphdr->src); 678 } 679 break; 680 case SYN_RCVD: 681 if (flags & TCP_ACK) { 682 /* expected ACK number? */ 683 if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)) { 684 u16_t old_cwnd; 685 pcb->state = ESTABLISHED; 686 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection established %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); 687#if LWIP_CALLBACK_API 688 LWIP_ASSERT("pcb->accept != NULL", pcb->accept != NULL); 689#endif 690 /* Call the accept function. */ 691 TCP_EVENT_ACCEPT(pcb, ERR_OK, err); 692 if (err != ERR_OK) { 693 /* If the accept function returns with an error, we abort 694 * the connection. */ 695 /* Already aborted? */ 696 if (err != ERR_ABRT) { 697 tcp_abort(pcb); 698 } 699 return ERR_ABRT; 700 } 701 old_cwnd = pcb->cwnd; 702 /* If there was any data contained within this ACK, 703 * we'd better pass it on to the application as well. */ 704 tcp_receive(pcb); 705 706 /* Prevent ACK for SYN to generate a sent event */ 707 if (pcb->acked != 0) { 708 pcb->acked--; 709 } 710 711 pcb->cwnd = ((old_cwnd == 1) ? (pcb->mss * 2) : pcb->mss); 712 713 if (recv_flags & TF_GOT_FIN) { 714 tcp_ack_now(pcb); 715 pcb->state = CLOSE_WAIT; 716 } 717 } else { 718 /* incorrect ACK number, send RST */ 719 tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(), 720 tcphdr->dest, tcphdr->src); 721 } 722 } else if ((flags & TCP_SYN) && (seqno == pcb->rcv_nxt - 1)) { 723 /* Looks like another copy of the SYN - retransmit our SYN-ACK */ 724 tcp_rexmit(pcb); 725 } 726 break; 727 case CLOSE_WAIT: 728 /* FALLTHROUGH */ 729 case ESTABLISHED: 730 tcp_receive(pcb); 731 if (recv_flags & TF_GOT_FIN) { /* passive close */ 732 tcp_ack_now(pcb); 733 pcb->state = CLOSE_WAIT; 734 } 735 break; 736 case FIN_WAIT_1: 737 tcp_receive(pcb); 738 if (recv_flags & TF_GOT_FIN) { 739 if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) { 740 LWIP_DEBUGF(TCP_DEBUG, 741 ("TCP connection closed: FIN_WAIT_1 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); 742 tcp_ack_now(pcb); 743 tcp_pcb_purge(pcb); 744 TCP_RMV(&tcp_active_pcbs, pcb); 745 pcb->state = TIME_WAIT; 746 TCP_REG(&tcp_tw_pcbs, pcb); 747 } else { 748 tcp_ack_now(pcb); 749 pcb->state = CLOSING; 750 } 751 } else if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) { 752 pcb->state = FIN_WAIT_2; 753 } 754 break; 755 case FIN_WAIT_2: 756 tcp_receive(pcb); 757 if (recv_flags & TF_GOT_FIN) { 758 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: FIN_WAIT_2 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); 759 tcp_ack_now(pcb); 760 tcp_pcb_purge(pcb); 761 TCP_RMV(&tcp_active_pcbs, pcb); 762 pcb->state = TIME_WAIT; 763 TCP_REG(&tcp_tw_pcbs, pcb); 764 } 765 break; 766 case CLOSING: 767 tcp_receive(pcb); 768 if (flags & TCP_ACK && ackno == pcb->snd_nxt) { 769 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: CLOSING %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); 770 tcp_pcb_purge(pcb); 771 TCP_RMV(&tcp_active_pcbs, pcb); 772 pcb->state = TIME_WAIT; 773 TCP_REG(&tcp_tw_pcbs, pcb); 774 } 775 break; 776 case LAST_ACK: 777 tcp_receive(pcb); 778 if (flags & TCP_ACK && ackno == pcb->snd_nxt) { 779 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: LAST_ACK %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); 780 /* bugfix #21699: don't set pcb->state to CLOSED here or we risk leaking segments */ 781 recv_flags |= TF_CLOSED; 782 } 783 break; 784 default: 785 break; 786 } 787 return ERR_OK; 788} 789 790#if TCP_QUEUE_OOSEQ 791/** 792 * Insert segment into the list (segments covered with new one will be deleted) 793 * 794 * Called from tcp_receive() 795 */ 796static void 797tcp_oos_insert_segment(struct tcp_seg *cseg, struct tcp_seg *next) 798{ 799 struct tcp_seg *old_seg; 800 801 if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) { 802 /* received segment overlaps all following segments */ 803 tcp_segs_free(next); 804 next = NULL; 805 } 806 else { 807 /* delete some following segments 808 oos queue may have segments with FIN flag */ 809 while (next && 810 TCP_SEQ_GEQ((seqno + cseg->len), 811 (next->tcphdr->seqno + next->len))) { 812 /* cseg with FIN already processed */ 813 if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) { 814 TCPH_SET_FLAG(cseg->tcphdr, TCP_FIN); 815 } 816 old_seg = next; 817 next = next->next; 818 tcp_seg_free(old_seg); 819 } 820 if (next && 821 TCP_SEQ_GT(seqno + cseg->len, next->tcphdr->seqno)) { 822 /* We need to trim the incoming segment. */ 823 cseg->len = (u16_t)(next->tcphdr->seqno - seqno); 824 pbuf_realloc(cseg->p, cseg->len); 825 } 826 } 827 cseg->next = next; 828} 829#endif /* TCP_QUEUE_OOSEQ */ 830 831/** 832 * Called by tcp_process. Checks if the given segment is an ACK for outstanding 833 * data, and if so frees the memory of the buffered data. Next, is places the 834 * segment on any of the receive queues (pcb->recved or pcb->ooseq). If the segment 835 * is buffered, the pbuf is referenced by pbuf_ref so that it will not be freed until 836 * i it has been removed from the buffer. 837 * 838 * If the incoming segment constitutes an ACK for a segment that was used for RTT 839 * estimation, the RTT is estimated here as well. 840 * 841 * Called from tcp_process(). 842 */ 843static void 844tcp_receive(struct tcp_pcb *pcb) 845{ 846 struct tcp_seg *next; 847#if TCP_QUEUE_OOSEQ 848 struct tcp_seg *prev, *cseg; 849#endif /* TCP_QUEUE_OOSEQ */ 850 struct pbuf *p; 851 s32_t off; 852 s16_t m; 853 u32_t right_wnd_edge; 854 u16_t new_tot_len; 855 int found_dupack = 0; 856 857 if (flags & TCP_ACK) { 858 right_wnd_edge = pcb->snd_wnd + pcb->snd_wl2; 859 860 /* Update window. */ 861 if (TCP_SEQ_LT(pcb->snd_wl1, seqno) || 862 (pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) || 863 (pcb->snd_wl2 == ackno && tcphdr->wnd > pcb->snd_wnd)) { 864 pcb->snd_wnd = tcphdr->wnd; 865 pcb->snd_wl1 = seqno; 866 pcb->snd_wl2 = ackno; 867 if (pcb->snd_wnd > 0 && pcb->persist_backoff > 0) { 868 pcb->persist_backoff = 0; 869 } 870 LWIP_DEBUGF(TCP_WND_DEBUG, ("tcp_receive: window update %"U16_F"\n", pcb->snd_wnd)); 871#if TCP_WND_DEBUG 872 } else { 873 if (pcb->snd_wnd != tcphdr->wnd) { 874 LWIP_DEBUGF(TCP_WND_DEBUG, 875 ("tcp_receive: no window update lastack %"U32_F" ackno %" 876 U32_F" wl1 %"U32_F" seqno %"U32_F" wl2 %"U32_F"\n", 877 pcb->lastack, ackno, pcb->snd_wl1, seqno, pcb->snd_wl2)); 878 } 879#endif /* TCP_WND_DEBUG */ 880 } 881 882 /* (From Stevens TCP/IP Illustrated Vol II, p970.) Its only a 883 * duplicate ack if: 884 * 1) It doesn't ACK new data 885 * 2) length of received packet is zero (i.e. no payload) 886 * 3) the advertised window hasn't changed 887 * 4) There is outstanding unacknowledged data (retransmission timer running) 888 * 5) The ACK is == biggest ACK sequence number so far seen (snd_una) 889 * 890 * If it passes all five, should process as a dupack: 891 * a) dupacks < 3: do nothing 892 * b) dupacks == 3: fast retransmit 893 * c) dupacks > 3: increase cwnd 894 * 895 * If it only passes 1-3, should reset dupack counter (and add to 896 * stats, which we don't do in lwIP) 897 * 898 * If it only passes 1, should reset dupack counter 899 * 900 */ 901 902 /* Clause 1 */ 903 if (TCP_SEQ_LEQ(ackno, pcb->lastack)) { 904 pcb->acked = 0; 905 /* Clause 2 */ 906 if (tcplen == 0) { 907 /* Clause 3 */ 908 if (pcb->snd_wl2 + pcb->snd_wnd == right_wnd_edge){ 909 /* Clause 4 */ 910 if (pcb->rtime >= 0) { 911 /* Clause 5 */ 912 if (pcb->lastack == ackno) { 913 found_dupack = 1; 914 if (pcb->dupacks + 1 > pcb->dupacks) 915 ++pcb->dupacks; 916 if (pcb->dupacks > 3) { 917 /* Inflate the congestion window, but not if it means that 918 the value overflows. */ 919 if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) { 920 pcb->cwnd += pcb->mss; 921 } 922 } else if (pcb->dupacks == 3) { 923 /* Do fast retransmit */ 924 tcp_rexmit_fast(pcb); 925 } 926 } 927 } 928 } 929 } 930 /* If Clause (1) or more is true, but not a duplicate ack, reset 931 * count of consecutive duplicate acks */ 932 if (!found_dupack) { 933 pcb->dupacks = 0; 934 } 935 } else if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)){ 936 /* We come here when the ACK acknowledges new data. */ 937 938 /* Reset the "IN Fast Retransmit" flag, since we are no longer 939 in fast retransmit. Also reset the congestion window to the 940 slow start threshold. */ 941 if (pcb->flags & TF_INFR) { 942 pcb->flags &= ~TF_INFR; 943 pcb->cwnd = pcb->ssthresh; 944 } 945 946 /* Reset the number of retransmissions. */ 947 pcb->nrtx = 0; 948 949 /* Reset the retransmission time-out. */ 950 pcb->rto = (pcb->sa >> 3) + pcb->sv; 951 952 /* Update the send buffer space. Diff between the two can never exceed 64K? */ 953 pcb->acked = (u16_t)(ackno - pcb->lastack); 954 955 pcb->snd_buf += pcb->acked; 956 957 /* Reset the fast retransmit variables. */ 958 pcb->dupacks = 0; 959 pcb->lastack = ackno; 960 961 /* Update the congestion control variables (cwnd and 962 ssthresh). */ 963 if (pcb->state >= ESTABLISHED) { 964 if (pcb->cwnd < pcb->ssthresh) { 965 if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) { 966 pcb->cwnd += pcb->mss; 967 } 968 LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: slow start cwnd %"U16_F"\n", pcb->cwnd)); 969 } else { 970 u16_t new_cwnd = (pcb->cwnd + pcb->mss * pcb->mss / pcb->cwnd); 971 if (new_cwnd > pcb->cwnd) { 972 pcb->cwnd = new_cwnd; 973 } 974 LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: congestion avoidance cwnd %"U16_F"\n", pcb->cwnd)); 975 } 976 } 977 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: ACK for %"U32_F", unacked->seqno %"U32_F":%"U32_F"\n", 978 ackno, 979 pcb->unacked != NULL? 980 ntohl(pcb->unacked->tcphdr->seqno): 0, 981 pcb->unacked != NULL? 982 ntohl(pcb->unacked->tcphdr->seqno) + TCP_TCPLEN(pcb->unacked): 0)); 983 984 /* Remove segment from the unacknowledged list if the incoming 985 ACK acknowlegdes them. */ 986 while (pcb->unacked != NULL && 987 TCP_SEQ_LEQ(ntohl(pcb->unacked->tcphdr->seqno) + 988 TCP_TCPLEN(pcb->unacked), ackno)) { 989 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unacked\n", 990 ntohl(pcb->unacked->tcphdr->seqno), 991 ntohl(pcb->unacked->tcphdr->seqno) + 992 TCP_TCPLEN(pcb->unacked))); 993 994 next = pcb->unacked; 995 pcb->unacked = pcb->unacked->next; 996 997 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen)); 998 LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p))); 999 /* Prevent ACK for FIN to generate a sent event */ 1000 if ((pcb->acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) { 1001 pcb->acked--; 1002 } 1003 1004 pcb->snd_queuelen -= pbuf_clen(next->p); 1005 tcp_seg_free(next); 1006 1007 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U16_F" (after freeing unacked)\n", (u16_t)pcb->snd_queuelen)); 1008 if (pcb->snd_queuelen != 0) { 1009 LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL || 1010 pcb->unsent != NULL); 1011 } 1012 } 1013 1014 /* If there's nothing left to acknowledge, stop the retransmit 1015 timer, otherwise reset it to start again */ 1016 if(pcb->unacked == NULL) 1017 pcb->rtime = -1; 1018 else 1019 pcb->rtime = 0; 1020 1021 pcb->polltmr = 0; 1022 } else { 1023 /* Fix bug bug #21582: out of sequence ACK, didn't really ack anything */ 1024 pcb->acked = 0; 1025 } 1026 1027 /* We go through the ->unsent list to see if any of the segments 1028 on the list are acknowledged by the ACK. This may seem 1029 strange since an "unsent" segment shouldn't be acked. The 1030 rationale is that lwIP puts all outstanding segments on the 1031 ->unsent list after a retransmission, so these segments may 1032 in fact have been sent once. */ 1033 while (pcb->unsent != NULL && 1034 TCP_SEQ_BETWEEN(ackno, ntohl(pcb->unsent->tcphdr->seqno) + 1035 TCP_TCPLEN(pcb->unsent), pcb->snd_nxt)) { 1036 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unsent\n", 1037 ntohl(pcb->unsent->tcphdr->seqno), ntohl(pcb->unsent->tcphdr->seqno) + 1038 TCP_TCPLEN(pcb->unsent))); 1039 1040 next = pcb->unsent; 1041 pcb->unsent = pcb->unsent->next; 1042 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen)); 1043 LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p))); 1044 /* Prevent ACK for FIN to generate a sent event */ 1045 if ((pcb->acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) { 1046 pcb->acked--; 1047 } 1048 pcb->snd_queuelen -= pbuf_clen(next->p); 1049 tcp_seg_free(next); 1050 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U16_F" (after freeing unsent)\n", (u16_t)pcb->snd_queuelen)); 1051 if (pcb->snd_queuelen != 0) { 1052 LWIP_ASSERT("tcp_receive: valid queue length", 1053 pcb->unacked != NULL || pcb->unsent != NULL); 1054 } 1055 } 1056 /* End of ACK for new data processing. */ 1057 1058 LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: pcb->rttest %"U32_F" rtseq %"U32_F" ackno %"U32_F"\n", 1059 pcb->rttest, pcb->rtseq, ackno)); 1060 1061 /* RTT estimation calculations. This is done by checking if the 1062 incoming segment acknowledges the segment we use to take a 1063 round-trip time measurement. */ 1064 if (pcb->rttest && TCP_SEQ_LT(pcb->rtseq, ackno)) { 1065 /* diff between this shouldn't exceed 32K since this are tcp timer ticks 1066 and a round-trip shouldn't be that long... */ 1067 m = (s16_t)(tcp_ticks - pcb->rttest); 1068 1069 LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: experienced rtt %"U16_F" ticks (%"U16_F" msec).\n", 1070 m, m * TCP_SLOW_INTERVAL)); 1071 1072 /* This is taken directly from VJs original code in his paper */ 1073 m = m - (pcb->sa >> 3); 1074 pcb->sa += m; 1075 if (m < 0) { 1076 m = -m; 1077 } 1078 m = m - (pcb->sv >> 2); 1079 pcb->sv += m; 1080 pcb->rto = (pcb->sa >> 3) + pcb->sv; 1081 1082 LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: RTO %"U16_F" (%"U16_F" milliseconds)\n", 1083 pcb->rto, pcb->rto * TCP_SLOW_INTERVAL)); 1084 1085 pcb->rttest = 0; 1086 } 1087 } 1088 1089 /* If the incoming segment contains data, we must process it 1090 further. */ 1091 if (tcplen > 0) { 1092 /* This code basically does three things: 1093 1094 +) If the incoming segment contains data that is the next 1095 in-sequence data, this data is passed to the application. This 1096 might involve trimming the first edge of the data. The rcv_nxt 1097 variable and the advertised window are adjusted. 1098 1099 +) If the incoming segment has data that is above the next 1100 sequence number expected (->rcv_nxt), the segment is placed on 1101 the ->ooseq queue. This is done by finding the appropriate 1102 place in the ->ooseq queue (which is ordered by sequence 1103 number) and trim the segment in both ends if needed. An 1104 immediate ACK is sent to indicate that we received an 1105 out-of-sequence segment. 1106 1107 +) Finally, we check if the first segment on the ->ooseq queue 1108 now is in sequence (i.e., if rcv_nxt >= ooseq->seqno). If 1109 rcv_nxt > ooseq->seqno, we must trim the first edge of the 1110 segment on ->ooseq before we adjust rcv_nxt. The data in the 1111 segments that are now on sequence are chained onto the 1112 incoming segment so that we only need to call the application 1113 once. 1114 */ 1115 1116 /* First, we check if we must trim the first edge. We have to do 1117 this if the sequence number of the incoming segment is less 1118 than rcv_nxt, and the sequence number plus the length of the 1119 segment is larger than rcv_nxt. */ 1120 /* if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)){ 1121 if (TCP_SEQ_LT(pcb->rcv_nxt, seqno + tcplen)) {*/ 1122 if (TCP_SEQ_BETWEEN(pcb->rcv_nxt, seqno + 1, seqno + tcplen - 1)){ 1123 /* Trimming the first edge is done by pushing the payload 1124 pointer in the pbuf downwards. This is somewhat tricky since 1125 we do not want to discard the full contents of the pbuf up to 1126 the new starting point of the data since we have to keep the 1127 TCP header which is present in the first pbuf in the chain. 1128 1129 What is done is really quite a nasty hack: the first pbuf in 1130 the pbuf chain is pointed to by inseg.p. Since we need to be 1131 able to deallocate the whole pbuf, we cannot change this 1132 inseg.p pointer to point to any of the later pbufs in the 1133 chain. Instead, we point the ->payload pointer in the first 1134 pbuf to data in one of the later pbufs. We also set the 1135 inseg.data pointer to point to the right place. This way, the 1136 ->p pointer will still point to the first pbuf, but the 1137 ->p->payload pointer will point to data in another pbuf. 1138 1139 After we are done with adjusting the pbuf pointers we must 1140 adjust the ->data pointer in the seg and the segment 1141 length.*/ 1142 1143 off = pcb->rcv_nxt - seqno; 1144 p = inseg.p; 1145 LWIP_ASSERT("inseg.p != NULL", inseg.p); 1146 LWIP_ASSERT("insane offset!", (off < 0x7fff)); 1147 if (inseg.p->len < off) { 1148 LWIP_ASSERT("pbuf too short!", (((s32_t)inseg.p->tot_len) >= off)); 1149 new_tot_len = (u16_t)(inseg.p->tot_len - off); 1150 while (p->len < off) { 1151 off -= p->len; 1152 /* KJM following line changed (with addition of new_tot_len var) 1153 to fix bug #9076 1154 inseg.p->tot_len -= p->len; */ 1155 p->tot_len = new_tot_len; 1156 p->len = 0; 1157 p = p->next; 1158 } 1159 if(pbuf_header(p, (s16_t)-off)) { 1160 /* Do we need to cope with this failing? Assert for now */ 1161 LWIP_ASSERT("pbuf_header failed", 0); 1162 } 1163 } else { 1164 if(pbuf_header(inseg.p, (s16_t)-off)) { 1165 /* Do we need to cope with this failing? Assert for now */ 1166 LWIP_ASSERT("pbuf_header failed", 0); 1167 } 1168 } 1169 inseg.len -= (u16_t)(pcb->rcv_nxt - seqno); 1170 inseg.tcphdr->seqno = seqno = pcb->rcv_nxt; 1171 } 1172 else { 1173 if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)){ 1174 /* the whole segment is < rcv_nxt */ 1175 /* must be a duplicate of a packet that has already been correctly handled */ 1176 1177 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: duplicate seqno %"U32_F"\n", seqno)); 1178 tcp_ack_now(pcb); 1179 } 1180 } 1181 1182 /* The sequence number must be within the window (above rcv_nxt 1183 and below rcv_nxt + rcv_wnd) in order to be further 1184 processed. */ 1185 if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, 1186 pcb->rcv_nxt + pcb->rcv_wnd - 1)){ 1187 if (pcb->rcv_nxt == seqno) { 1188 /* The incoming segment is the next in sequence. We check if 1189 we have to trim the end of the segment and update rcv_nxt 1190 and pass the data to the application. */ 1191 tcplen = TCP_TCPLEN(&inseg); 1192 1193 if (tcplen > pcb->rcv_wnd) { 1194 LWIP_DEBUGF(TCP_INPUT_DEBUG, 1195 ("tcp_receive: other end overran receive window" 1196 "seqno %"U32_F" len %"U16_F" right edge %"U32_F"\n", 1197 seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd)); 1198 if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) { 1199 /* Must remove the FIN from the header as we're trimming 1200 * that byte of sequence-space from the packet */ 1201 TCPH_FLAGS_SET(inseg.tcphdr, TCPH_FLAGS(inseg.tcphdr) &~ TCP_FIN); 1202 } 1203 /* Adjust length of segment to fit in the window. */ 1204 inseg.len = pcb->rcv_wnd; 1205 if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) { 1206 inseg.len -= 1; 1207 } 1208 pbuf_realloc(inseg.p, inseg.len); 1209 tcplen = TCP_TCPLEN(&inseg); 1210 LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n", 1211 (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd)); 1212 } 1213#if TCP_QUEUE_OOSEQ 1214 /* Received in-sequence data, adjust ooseq data if: 1215 - FIN has been received or 1216 - inseq overlaps with ooseq */ 1217 if (pcb->ooseq != NULL) { 1218 if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) { 1219 LWIP_DEBUGF(TCP_INPUT_DEBUG, 1220 ("tcp_receive: received in-order FIN, binning ooseq queue\n")); 1221 /* Received in-order FIN means anything that was received 1222 * out of order must now have been received in-order, so 1223 * bin the ooseq queue */ 1224 while (pcb->ooseq != NULL) { 1225 struct tcp_seg *old_ooseq = pcb->ooseq; 1226 pcb->ooseq = pcb->ooseq->next; 1227 tcp_seg_free(old_ooseq); 1228 } 1229 } 1230 else { 1231 next = pcb->ooseq; 1232 /* Remove all segments on ooseq that are covered by inseg already. 1233 * FIN is copied from ooseq to inseg if present. */ 1234 while (next && 1235 TCP_SEQ_GEQ(seqno + tcplen, 1236 next->tcphdr->seqno + next->len)) { 1237 /* inseg cannot have FIN here (already processed above) */ 1238 if (TCPH_FLAGS(next->tcphdr) & TCP_FIN && 1239 (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) == 0) { 1240 TCPH_SET_FLAG(inseg.tcphdr, TCP_FIN); 1241 tcplen = TCP_TCPLEN(&inseg); 1242 } 1243 prev = next; 1244 next = next->next; 1245 tcp_seg_free(prev); 1246 } 1247 /* Now trim right side of inseg if it overlaps with the first 1248 * segment on ooseq */ 1249 if (next && 1250 TCP_SEQ_GT(seqno + tcplen, 1251 next->tcphdr->seqno)) { 1252 /* inseg cannot have FIN here (already processed above) */ 1253 inseg.len = (u16_t)(next->tcphdr->seqno - seqno); 1254 if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) { 1255 inseg.len -= 1; 1256 } 1257 pbuf_realloc(inseg.p, inseg.len); 1258 tcplen = TCP_TCPLEN(&inseg); 1259 LWIP_ASSERT("tcp_receive: segment not trimmed correctly to ooseq queue\n", 1260 (seqno + tcplen) == next->tcphdr->seqno); 1261 } 1262 pcb->ooseq = next; 1263 } 1264 } 1265#endif /* TCP_QUEUE_OOSEQ */ 1266 1267 pcb->rcv_nxt = seqno + tcplen; 1268 1269 /* Update the receiver's (our) window. */ 1270 LWIP_ASSERT("tcp_receive: tcplen > rcv_wnd\n", pcb->rcv_wnd >= tcplen); 1271 pcb->rcv_wnd -= tcplen; 1272 1273 tcp_update_rcv_ann_wnd(pcb); 1274 1275 /* If there is data in the segment, we make preparations to 1276 pass this up to the application. The ->recv_data variable 1277 is used for holding the pbuf that goes to the 1278 application. The code for reassembling out-of-sequence data 1279 chains its data on this pbuf as well. 1280 1281 If the segment was a FIN, we set the TF_GOT_FIN flag that will 1282 be used to indicate to the application that the remote side has 1283 closed its end of the connection. */ 1284 if (inseg.p->tot_len > 0) { 1285 recv_data = inseg.p; 1286 /* Since this pbuf now is the responsibility of the 1287 application, we delete our reference to it so that we won't 1288 (mistakingly) deallocate it. */ 1289 inseg.p = NULL; 1290 } 1291 if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) { 1292 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN.\n")); 1293 recv_flags |= TF_GOT_FIN; 1294 } 1295 1296#if TCP_QUEUE_OOSEQ 1297 /* We now check if we have segments on the ->ooseq queue that 1298 are now in sequence. */ 1299 while (pcb->ooseq != NULL && 1300 pcb->ooseq->tcphdr->seqno == pcb->rcv_nxt) { 1301 1302 cseg = pcb->ooseq; 1303 seqno = pcb->ooseq->tcphdr->seqno; 1304 1305 pcb->rcv_nxt += TCP_TCPLEN(cseg); 1306 LWIP_ASSERT("tcp_receive: ooseq tcplen > rcv_wnd\n", 1307 pcb->rcv_wnd >= TCP_TCPLEN(cseg)); 1308 pcb->rcv_wnd -= TCP_TCPLEN(cseg); 1309 1310 tcp_update_rcv_ann_wnd(pcb); 1311 1312 if (cseg->p->tot_len > 0) { 1313 /* Chain this pbuf onto the pbuf that we will pass to 1314 the application. */ 1315 if (recv_data) { 1316 pbuf_cat(recv_data, cseg->p); 1317 } else { 1318 recv_data = cseg->p; 1319 } 1320 cseg->p = NULL; 1321 } 1322 if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) { 1323 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN.\n")); 1324 recv_flags |= TF_GOT_FIN; 1325 if (pcb->state == ESTABLISHED) { /* force passive close or we can move to active close */ 1326 pcb->state = CLOSE_WAIT; 1327 } 1328 } 1329 1330 pcb->ooseq = cseg->next; 1331 tcp_seg_free(cseg); 1332 } 1333#endif /* TCP_QUEUE_OOSEQ */ 1334 1335 1336 /* Acknowledge the segment(s). */ 1337 tcp_ack(pcb); 1338 1339 } else { 1340 /* We get here if the incoming segment is out-of-sequence. */ 1341 tcp_send_empty_ack(pcb); 1342#if TCP_QUEUE_OOSEQ 1343 /* We queue the segment on the ->ooseq queue. */ 1344 if (pcb->ooseq == NULL) { 1345 pcb->ooseq = tcp_seg_copy(&inseg); 1346 } else { 1347 /* If the queue is not empty, we walk through the queue and 1348 try to find a place where the sequence number of the 1349 incoming segment is between the sequence numbers of the 1350 previous and the next segment on the ->ooseq queue. That is 1351 the place where we put the incoming segment. If needed, we 1352 trim the second edges of the previous and the incoming 1353 segment so that it will fit into the sequence. 1354 1355 If the incoming segment has the same sequence number as a 1356 segment on the ->ooseq queue, we discard the segment that 1357 contains less data. */ 1358 1359 prev = NULL; 1360 for(next = pcb->ooseq; next != NULL; next = next->next) { 1361 if (seqno == next->tcphdr->seqno) { 1362 /* The sequence number of the incoming segment is the 1363 same as the sequence number of the segment on 1364 ->ooseq. We check the lengths to see which one to 1365 discard. */ 1366 if (inseg.len > next->len) { 1367 /* The incoming segment is larger than the old 1368 segment. We replace some segments with the new 1369 one. */ 1370 cseg = tcp_seg_copy(&inseg); 1371 if (cseg != NULL) { 1372 if (prev != NULL) { 1373 prev->next = cseg; 1374 } else { 1375 pcb->ooseq = cseg; 1376 } 1377 tcp_oos_insert_segment(cseg, next); 1378 } 1379 break; 1380 } else { 1381 /* Either the lenghts are the same or the incoming 1382 segment was smaller than the old one; in either 1383 case, we ditch the incoming segment. */ 1384 break; 1385 } 1386 } else { 1387 if (prev == NULL) { 1388 if (TCP_SEQ_LT(seqno, next->tcphdr->seqno)) { 1389 /* The sequence number of the incoming segment is lower 1390 than the sequence number of the first segment on the 1391 queue. We put the incoming segment first on the 1392 queue. */ 1393 cseg = tcp_seg_copy(&inseg); 1394 if (cseg != NULL) { 1395 pcb->ooseq = cseg; 1396 tcp_oos_insert_segment(cseg, next); 1397 } 1398 break; 1399 } 1400 } else { 1401 /*if (TCP_SEQ_LT(prev->tcphdr->seqno, seqno) && 1402 TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {*/ 1403 if (TCP_SEQ_BETWEEN(seqno, prev->tcphdr->seqno+1, next->tcphdr->seqno-1)) { 1404 /* The sequence number of the incoming segment is in 1405 between the sequence numbers of the previous and 1406 the next segment on ->ooseq. We trim trim the previous 1407 segment, delete next segments that included in received segment 1408 and trim received, if needed. */ 1409 cseg = tcp_seg_copy(&inseg); 1410 if (cseg != NULL) { 1411 if (TCP_SEQ_GT(prev->tcphdr->seqno + prev->len, seqno)) { 1412 /* We need to trim the prev segment. */ 1413 prev->len = (u16_t)(seqno - prev->tcphdr->seqno); 1414 pbuf_realloc(prev->p, prev->len); 1415 } 1416 prev->next = cseg; 1417 tcp_oos_insert_segment(cseg, next); 1418 } 1419 break; 1420 } 1421 } 1422 /* If the "next" segment is the last segment on the 1423 ooseq queue, we add the incoming segment to the end 1424 of the list. */ 1425 if (next->next == NULL && 1426 TCP_SEQ_GT(seqno, next->tcphdr->seqno)) { 1427 if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) { 1428 /* segment "next" already contains all data */ 1429 break; 1430 } 1431 next->next = tcp_seg_copy(&inseg); 1432 if (next->next != NULL) { 1433 if (TCP_SEQ_GT(next->tcphdr->seqno + next->len, seqno)) { 1434 /* We need to trim the last segment. */ 1435 next->len = (u16_t)(seqno - next->tcphdr->seqno); 1436 pbuf_realloc(next->p, next->len); 1437 } 1438 /* check if the remote side overruns our receive window */ 1439 if ((u32_t)tcplen + seqno > pcb->rcv_nxt + (u32_t)pcb->rcv_wnd) { 1440 LWIP_DEBUGF(TCP_INPUT_DEBUG, 1441 ("tcp_receive: other end overran receive window" 1442 "seqno %"U32_F" len %"U16_F" right edge %"U32_F"\n", 1443 seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd)); 1444 if (TCPH_FLAGS(next->next->tcphdr) & TCP_FIN) { 1445 /* Must remove the FIN from the header as we're trimming 1446 * that byte of sequence-space from the packet */ 1447 TCPH_FLAGS_SET(next->next->tcphdr, TCPH_FLAGS(next->next->tcphdr) &~ TCP_FIN); 1448 } 1449 /* Adjust length of segment to fit in the window. */ 1450 next->next->len = pcb->rcv_nxt + pcb->rcv_wnd - seqno; 1451 pbuf_realloc(next->next->p, next->next->len); 1452 tcplen = TCP_TCPLEN(next->next); 1453 LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n", 1454 (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd)); 1455 } 1456 } 1457 break; 1458 } 1459 } 1460 prev = next; 1461 } 1462 } 1463#endif /* TCP_QUEUE_OOSEQ */ 1464 1465 } 1466 } else { 1467 /* The incoming segment is not withing the window. */ 1468 tcp_send_empty_ack(pcb); 1469 } 1470 } else { 1471 /* Segments with length 0 is taken care of here. Segments that 1472 fall out of the window are ACKed. */ 1473 /*if (TCP_SEQ_GT(pcb->rcv_nxt, seqno) || 1474 TCP_SEQ_GEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {*/ 1475 if(!TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd-1)){ 1476 tcp_ack_now(pcb); 1477 } 1478 } 1479} 1480 1481/** 1482 * Parses the options contained in the incoming segment. 1483 * 1484 * Called from tcp_listen_input() and tcp_process(). 1485 * Currently, only the MSS option is supported! 1486 * 1487 * @param pcb the tcp_pcb for which a segment arrived 1488 */ 1489static void 1490tcp_parseopt(struct tcp_pcb *pcb) 1491{ 1492 u16_t c, max_c; 1493 u16_t mss; 1494 u8_t *opts, opt; 1495#if LWIP_TCP_TIMESTAMPS 1496 u32_t tsval; 1497#endif 1498 1499 opts = (u8_t *)tcphdr + TCP_HLEN; 1500 1501 /* Parse the TCP MSS option, if present. */ 1502 if(TCPH_HDRLEN(tcphdr) > 0x5) { 1503 max_c = (TCPH_HDRLEN(tcphdr) - 5) << 2; 1504 for (c = 0; c < max_c; ) { 1505 opt = opts[c]; 1506 switch (opt) { 1507 case 0x00: 1508 /* End of options. */ 1509 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: EOL\n")); 1510 return; 1511 case 0x01: 1512 /* NOP option. */ 1513 ++c; 1514 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: NOP\n")); 1515 break; 1516 case 0x02: 1517 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: MSS\n")); 1518 if (opts[c + 1] != 0x04 || c + 0x04 > max_c) { 1519 /* Bad length */ 1520 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n")); 1521 return; 1522 } 1523 /* An MSS option with the right option length. */ 1524 mss = (opts[c + 2] << 8) | opts[c + 3]; 1525 /* Limit the mss to the configured TCP_MSS and prevent division by zero */ 1526 pcb->mss = ((mss > TCP_MSS) || (mss == 0)) ? TCP_MSS : mss; 1527 /* Advance to next option */ 1528 c += 0x04; 1529 break; 1530#if LWIP_TCP_TIMESTAMPS 1531 case 0x08: 1532 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: TS\n")); 1533 if (opts[c + 1] != 0x0A || c + 0x0A > max_c) { 1534 /* Bad length */ 1535 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n")); 1536 return; 1537 } 1538 /* TCP timestamp option with valid length */ 1539 tsval = (opts[c+2]) | (opts[c+3] << 8) | 1540 (opts[c+4] << 16) | (opts[c+5] << 24); 1541 if (flags & TCP_SYN) { 1542 pcb->ts_recent = ntohl(tsval); 1543 pcb->flags |= TF_TIMESTAMP; 1544 } else if (TCP_SEQ_BETWEEN(pcb->ts_lastacksent, seqno, seqno+tcplen)) { 1545 pcb->ts_recent = ntohl(tsval); 1546 } 1547 /* Advance to next option */ 1548 c += 0x0A; 1549 break; 1550#endif 1551 default: 1552 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: other\n")); 1553 if (opts[c + 1] == 0) { 1554 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n")); 1555 /* If the length field is zero, the options are malformed 1556 and we don't process them further. */ 1557 return; 1558 } 1559 /* All other options have a length field, so that we easily 1560 can skip past them. */ 1561 c += opts[c + 1]; 1562 } 1563 } 1564 } 1565} 1566 1567#endif /* LWIP_TCP */ 1568