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