Disabling auto-refresh of game list by default, as it is causing bugs sometimes
[open-ps2-loader.git] / modules / network / SMSTCPIP / tcp_in.c
blob48db952b5ed9a0a63f46f77d2e704867d871f402
1 /**
2 * @file
4 * Transmission Control Protocol, incoming traffic
5 */
7 /*
8 * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
9 * All rights reserved.
11 * Redistribution and use in source and binary forms, with or without modification,
12 * are permitted provided that the following conditions are met:
14 * 1. Redistributions of source code must retain the above copyright notice,
15 * this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright notice,
17 * this list of conditions and the following disclaimer in the documentation
18 * and/or other materials provided with the distribution.
19 * 3. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
23 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
25 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
27 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
30 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
31 * OF SUCH DAMAGE.
33 * This file is part of the lwIP TCP/IP stack.
35 * Author: Adam Dunkels <adam@sics.se>
40 /* tcp_input.c
42 * The input processing functions of TCP.
44 * These functions are generally called in the order (ip_input() ->) tcp_input() ->
45 * tcp_process() -> tcp_receive() (-> application).
51 #include "lwip/def.h"
52 #include "lwip/opt.h"
54 #include "lwip/netif.h"
55 #include "lwip/mem.h"
56 #include "lwip/memp.h"
58 #include "lwip/inet.h"
59 #include "lwip/tcp.h"
61 #include "lwip/stats.h"
63 #if LWIP_TCP
64 /* These variables are global to all functions involved in the input
65 processing of TCP segments. They are set by the tcp_input()
66 function. */
67 static struct tcp_seg inseg;
68 static struct tcp_hdr *tcphdr;
69 static struct ip_hdr *iphdr;
70 static u32_t seqno, ackno;
71 static u8_t flags;
72 static u16_t tcplen;
74 static u8_t recv_flags;
75 static struct pbuf *recv_data;
77 struct tcp_pcb *tcp_input_pcb;
79 /* Forward declarations. */
80 static err_t tcp_process(struct tcp_pcb *pcb);
81 static void tcp_receive(struct tcp_pcb *pcb);
82 static void tcp_parseopt(struct tcp_pcb *pcb);
84 static err_t tcp_listen_input(struct tcp_pcb_listen *pcb);
85 static err_t tcp_timewait_input(struct tcp_pcb *pcb);
88 /* tcp_input:
90 * The initial input processing of TCP. It verifies the TCP header, demultiplexes
91 * the segment between the PCBs and passes it on to tcp_process(), which implements
92 * the TCP finite state machine. This function is called by the IP layer (in
93 * ip_input()).
97 void
98 tcp_input(struct pbuf *p, struct netif *inp)
100 struct tcp_pcb *pcb, *prev;
101 struct tcp_pcb_listen *lpcb;
102 u8_t hdrlen;
103 err_t err;
105 #ifdef SO_REUSE
106 struct tcp_pcb *pcb_temp;
107 int reuse = 0;
108 int reuse_port = 0;
109 #endif /* SO_REUSE */
111 TCP_STATS_INC(tcp.recv);
113 iphdr = p->payload;
114 tcphdr = (struct tcp_hdr *)((u8_t *)p->payload + IPH_HL(iphdr) * 4);
116 #if TCP_INPUT_DEBUG
117 tcp_debug_print(tcphdr);
118 #endif
120 /* remove header from payload */
121 if (pbuf_header(p, -((s16_t)(IPH_HL(iphdr) * 4))) || (p->tot_len < sizeof(struct tcp_hdr))) {
122 /* drop short packets */
123 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet (%u bytes) discarded\n", p->tot_len));
124 TCP_STATS_INC(tcp.lenerr);
125 TCP_STATS_INC(tcp.drop);
126 pbuf_free(p);
127 return;
130 /* Don't even process incoming broadcasts/multicasts. */
131 if (ip_addr_isbroadcast(&(iphdr->dest), &(inp->netmask)) ||
132 ip_addr_ismulticast(&(iphdr->dest))) {
133 pbuf_free(p);
134 return;
137 /* Verify TCP checksum. */
138 if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),
139 (struct ip_addr *)&(iphdr->dest),
140 IP_PROTO_TCP, p->tot_len) != 0) {
141 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packet discarded due to failing checksum 0x%04x\n",
142 inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src), (struct ip_addr *)&(iphdr->dest),
143 IP_PROTO_TCP, p->tot_len)));
144 #if TCP_DEBUG
145 tcp_debug_print(tcphdr);
146 #endif /* TCP_DEBUG */
147 TCP_STATS_INC(tcp.chkerr);
148 TCP_STATS_INC(tcp.drop);
150 pbuf_free(p);
151 return;
155 /* Move the payload pointer in the pbuf so that it points to the
156 TCP data instead of the TCP header. */
157 hdrlen = TCPH_HDRLEN(tcphdr);
158 pbuf_header(p, -(hdrlen * 4));
160 /* Convert fields in TCP header to host byte order. */
161 tcphdr->src = ntohs(tcphdr->src);
162 tcphdr->dest = ntohs(tcphdr->dest);
163 seqno = tcphdr->seqno = ntohl(tcphdr->seqno);
164 ackno = tcphdr->ackno = ntohl(tcphdr->ackno);
165 tcphdr->wnd = ntohs(tcphdr->wnd);
167 flags = TCPH_FLAGS(tcphdr) & TCP_FLAGS;
168 tcplen = p->tot_len + ((flags & TCP_FIN || flags & TCP_SYN)? 1: 0);
170 /* Demultiplex an incoming segment. First, we check if it is destined
171 for an active connection. */
172 prev = NULL;
174 #ifdef SO_REUSE
175 pcb_temp = tcp_active_pcbs;
177 again_1:
179 /* Iterate through the TCP pcb list for a fully matching pcb */
180 for(pcb = pcb_temp; pcb != NULL; pcb = pcb->next) {
181 #else /* SO_REUSE */
182 for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
183 #endif /* SO_REUSE */
184 LWIP_ASSERT("tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED);
185 LWIP_ASSERT("tcp_input: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);
186 LWIP_ASSERT("tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN);
187 if (pcb->remote_port == tcphdr->src &&
188 pcb->local_port == tcphdr->dest &&
189 ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src)) &&
190 ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest))) {
192 #ifdef SO_REUSE
193 if(pcb->so_options & SOF_REUSEPORT) {
194 if(reuse) {
195 /* We processed one PCB already */
196 LWIP_DEBUGF(TCP_INPUT_DEBUG,("tcp_input: second or later PCB and SOF_REUSEPORT set.\n"));
197 } else {
198 /* First PCB with this address */
199 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: first PCB and SOF_REUSEPORT set.\n"));
200 reuse = 1;
203 reuse_port = 1;
204 p->ref++;
206 /* We want to search on next socket after receiving */
207 pcb_temp = pcb->next;
209 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: reference counter on PBUF set to %i\n", p->ref));
210 } else {
211 if(reuse) {
212 /* We processed one PCB already */
213 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: second or later PCB but SOF_REUSEPORT not set !\n"));
216 #endif /* SO_REUSE */
218 /* Move this PCB to the front of the list so that subsequent
219 lookups will be faster (we exploit locality in TCP segment
220 arrivals). */
221 LWIP_ASSERT("tcp_input: pcb->next != pcb (before cache)", pcb->next != pcb);
222 if (prev != NULL) {
223 prev->next = pcb->next;
224 pcb->next = tcp_active_pcbs;
225 tcp_active_pcbs = pcb;
227 LWIP_ASSERT("tcp_input: pcb->next != pcb (after cache)", pcb->next != pcb);
228 break;
230 prev = pcb;
233 if (pcb == NULL) {
234 /* If it did not go to an active connection, we check the connections
235 in the TIME-WAIT state. */
237 for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
238 LWIP_ASSERT("tcp_input: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
239 if (pcb->remote_port == tcphdr->src &&
240 pcb->local_port == tcphdr->dest &&
241 ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src)) &&
242 ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest))) {
243 /* We don't really care enough to move this PCB to the front
244 of the list since we are not very likely to receive that
245 many segments for connections in TIME-WAIT. */
246 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for TIME_WAITing connection.\n"));
247 tcp_timewait_input(pcb);
248 pbuf_free(p);
249 return;
253 /* Finally, if we still did not get a match, we check all PCBs that
254 are LISTENing for incoming connections. */
255 prev = NULL;
256 for(lpcb = tcp_listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
257 if ((ip_addr_isany(&(lpcb->local_ip)) ||
258 ip_addr_cmp(&(lpcb->local_ip), &(iphdr->dest))) &&
259 lpcb->local_port == tcphdr->dest) {
260 /* Move this PCB to the front of the list so that subsequent
261 lookups will be faster (we exploit locality in TCP segment
262 arrivals). */
263 if (prev != NULL) {
264 ((struct tcp_pcb_listen *)prev)->next = lpcb->next;
265 /* our successor is the remainder of the listening list */
266 lpcb->next = tcp_listen_pcbs;
267 /* put this listening pcb at the head of the listening list */
268 tcp_listen_pcbs = lpcb;
271 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for LISTENing connection.\n"));
272 tcp_listen_input(lpcb);
273 pbuf_free(p);
274 return;
276 prev = (struct tcp_pcb *)lpcb;
280 if (pcb != NULL) {
281 /* The incoming segment belongs to a connection. */
282 /* Set up a tcp_seg structure. */
283 inseg.next = NULL;
284 inseg.len = p->tot_len;
285 inseg.dataptr = p->payload;
286 inseg.p = p;
287 inseg.tcphdr = tcphdr;
289 recv_data = NULL;
290 recv_flags = 0;
292 tcp_input_pcb = pcb;
293 err = tcp_process(pcb);
294 tcp_input_pcb = NULL;
295 /* A return value of ERR_ABRT means that tcp_abort() was called
296 and that the pcb has been freed. If so, we don't do anything. */
297 if (err != ERR_ABRT) {
298 if (recv_flags & TF_RESET) {
299 /* TF_RESET means that the connection was reset by the other
300 end. We then call the error callback to inform the
301 application that the connection is dead before we
302 deallocate the PCB. */
303 TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_RST);
304 tcp_pcb_remove(&tcp_active_pcbs, pcb);
305 memp_free(MEMP_TCP_PCB, pcb);
306 } else if (recv_flags & TF_CLOSED) {
307 /* The connection has been closed and we will deallocate the
308 PCB. */
309 tcp_pcb_remove(&tcp_active_pcbs, pcb);
310 memp_free(MEMP_TCP_PCB, pcb);
311 } else {
312 err = ERR_OK;
313 /* If the application has registered a "sent" function to be
314 called when new send buffer space is available, we call it
315 now. */
316 if (pcb->acked > 0) {
317 TCP_EVENT_SENT(pcb, pcb->acked, err);
320 if (recv_data != NULL) {
321 /* Notify application that data has been received. */
322 TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err);
325 /* If a FIN segment was received, we call the callback
326 function with a NULL buffer to indicate EOF. */
327 if (recv_flags & TF_GOT_FIN) {
328 TCP_EVENT_RECV(pcb, NULL, ERR_OK, err);
330 /* If there were no errors, we try to send something out. */
331 if (err == ERR_OK) {
332 tcp_output(pcb);
338 /* We deallocate the incoming pbuf. If it was buffered by the
339 application, the application should have called pbuf_ref() to
340 increase the reference counter in the pbuf. If so, the buffer
341 isn't actually deallocated by the call to pbuf_free(), only the
342 reference count is decreased. */
343 pbuf_free(inseg.p);
344 #if TCP_INPUT_DEBUG
345 #if TCP_DEBUG
346 tcp_debug_print_state(pcb->state);
347 #endif /* TCP_DEBUG */
348 #endif /* TCP_INPUT_DEBUG */
349 #ifdef SO_REUSE
350 /* First socket should receive now */
351 if(reuse_port) {
352 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: searching next PCB.\n"));
353 reuse_port = 0;
355 /* We are searching connected sockets */
356 goto again_1;
358 #endif /* SO_REUSE */
360 } else {
361 #ifdef SO_REUSE
362 if(reuse) {
363 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: freeing PBUF with reference counter set to %i\n", p->ref));
364 pbuf_free(p);
365 goto end;
367 #endif /* SO_REUSE */
368 /* If no matching PCB was found, send a TCP RST (reset) to the
369 sender. */
370 LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_input: no PCB match found, resetting.\n"));
371 if (!(TCPH_FLAGS(tcphdr) & TCP_RST)) {
372 TCP_STATS_INC(tcp.proterr);
373 TCP_STATS_INC(tcp.drop);
374 tcp_rst(ackno, seqno + tcplen,
375 &(iphdr->dest), &(iphdr->src),
376 tcphdr->dest, tcphdr->src);
378 pbuf_free(p);
380 #ifdef SO_REUSE
381 end:
382 #endif /* SO_REUSE */
383 LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane());
386 /* tcp_listen_input():
388 * Called by tcp_input() when a segment arrives for a listening
389 * connection.
392 static err_t
393 tcp_listen_input(struct tcp_pcb_listen *pcb)
395 struct tcp_pcb *npcb;
396 u32_t optdata;
398 /* In the LISTEN state, we check for incoming SYN segments,
399 creates a new PCB, and responds with a SYN|ACK. */
400 if (flags & TCP_ACK) {
401 /* For incoming segments with the ACK flag set, respond with a
402 RST. */
403 LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_listen_input: ACK in LISTEN, sending reset\n"));
404 tcp_rst(ackno + 1, seqno + tcplen,
405 &(iphdr->dest), &(iphdr->src),
406 tcphdr->dest, tcphdr->src);
407 } else if (flags & TCP_SYN) {
408 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection request %u -> %u.\n", tcphdr->src, tcphdr->dest));
409 npcb = tcp_alloc(pcb->prio);
410 /* If a new PCB could not be created (probably due to lack of memory),
411 we don't do anything, but rely on the sender will retransmit the
412 SYN at a time when we have more memory available. */
413 if (npcb == NULL) {
414 LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: could not allocate PCB\n"));
415 TCP_STATS_INC(tcp.memerr);
416 return ERR_MEM;
418 /* Set up the new PCB. */
419 ip_addr_set(&(npcb->local_ip), &(iphdr->dest));
420 npcb->local_port = pcb->local_port;
421 ip_addr_set(&(npcb->remote_ip), &(iphdr->src));
422 npcb->remote_port = tcphdr->src;
423 npcb->state = SYN_RCVD;
424 npcb->rcv_nxt = seqno + 1;
425 npcb->snd_wnd = tcphdr->wnd;
426 npcb->ssthresh = npcb->snd_wnd;
427 npcb->snd_wl1 = seqno - 1;/* initialise to seqno-1 to force window update */
428 npcb->callback_arg = pcb->callback_arg;
429 #if LWIP_CALLBACK_API
430 npcb->accept = pcb->accept;
431 #endif /* LWIP_CALLBACK_API */
432 /* inherit socket options */
433 npcb->so_options = pcb->so_options & (SOF_DEBUG|SOF_DONTROUTE|SOF_KEEPALIVE|SOF_OOBINLINE|SOF_LINGER);
434 /* Register the new PCB so that we can begin receiving segments
435 for it. */
436 TCP_REG(&tcp_active_pcbs, npcb);
438 /* Parse any options in the SYN. */
439 tcp_parseopt(npcb);
441 /* Build an MSS option. */
442 optdata = htonl(((u32_t)2 << 24) |
443 ((u32_t)4 << 16) |
444 (((u32_t)npcb->mss / 256) << 8) |
445 (npcb->mss & 255));
446 /* Send a SYN|ACK together with the MSS option. */
447 tcp_enqueue(npcb, NULL, 0, TCP_SYN | TCP_ACK, 0, (u8_t *)&optdata, 4);
448 return tcp_output(npcb);
450 return ERR_OK;
453 /* tcp_timewait_input():
455 * Called by tcp_input() when a segment arrives for a connection in
456 * TIME_WAIT.
459 static err_t
460 tcp_timewait_input(struct tcp_pcb *pcb)
462 if (TCP_SEQ_GT(seqno + tcplen, pcb->rcv_nxt)) {
463 pcb->rcv_nxt = seqno + tcplen;
465 if (tcplen > 0) {
466 tcp_ack_now(pcb);
468 return tcp_output(pcb);
471 /* tcp_process
473 * Implements the TCP state machine. Called by tcp_input. In some
474 * states tcp_receive() is called to receive data. The tcp_seg
475 * argument will be freed by the caller (tcp_input()) unless the
476 * recv_data pointer in the pcb is set.
479 static err_t
480 tcp_process(struct tcp_pcb *pcb)
482 struct tcp_seg *rseg;
483 u8_t acceptable = 0;
484 err_t err;
486 err = ERR_OK;
488 /* Process incoming RST segments. */
489 if (flags & TCP_RST) {
490 /* First, determine if the reset is acceptable. */
491 if (pcb->state == SYN_SENT) {
492 if (ackno == pcb->snd_nxt) {
493 acceptable = 1;
495 } else {
496 if (TCP_SEQ_GEQ(seqno, pcb->rcv_nxt) &&
497 TCP_SEQ_LEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {
498 acceptable = 1;
502 if (acceptable) {
503 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: Connection RESET\n"));
504 LWIP_ASSERT("tcp_input: pcb->state != CLOSED", pcb->state != CLOSED);
505 recv_flags = TF_RESET;
506 pcb->flags &= ~TF_ACK_DELAY;
507 return ERR_RST;
508 } else {
509 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: unacceptable reset seqno %lu rcv_nxt %lu\n",
510 seqno, pcb->rcv_nxt));
511 LWIP_DEBUGF(TCP_DEBUG, ("tcp_process: unacceptable reset seqno %lu rcv_nxt %lu\n",
512 seqno, pcb->rcv_nxt));
513 return ERR_OK;
517 /* Update the PCB (in)activity timer. */
518 pcb->tmr = tcp_ticks;
519 pcb->keep_cnt = 0;
521 /* Do different things depending on the TCP state. */
522 switch (pcb->state) {
523 case SYN_SENT:
524 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %lu pcb->snd_nxt %lu unacked %lu\n", ackno,
525 pcb->snd_nxt, ntohl(pcb->unacked->tcphdr->seqno)));
526 if ((flags & TCP_ACK) && (flags & TCP_SYN)
527 && ackno == ntohl(pcb->unacked->tcphdr->seqno) + 1) {
528 pcb->rcv_nxt = seqno + 1;
529 pcb->lastack = ackno;
530 pcb->snd_wnd = tcphdr->wnd;
531 pcb->snd_wl1 = seqno - 1; /* initialise to seqno - 1 to force window update */
532 pcb->state = ESTABLISHED;
533 pcb->cwnd = pcb->mss;
534 --pcb->snd_queuelen;
535 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_process: SYN-SENT --queuelen %u\n", (unsigned int)pcb->snd_queuelen));
536 rseg = pcb->unacked;
537 pcb->unacked = rseg->next;
538 tcp_seg_free(rseg);
540 /* Parse any options in the SYNACK. */
541 tcp_parseopt(pcb);
543 /* Call the user specified function to call when sucessfully
544 * connected. */
545 TCP_EVENT_CONNECTED(pcb, ERR_OK, err);
546 tcp_ack(pcb);
548 break;
549 case SYN_RCVD:
550 if (flags & TCP_ACK &&
551 !(flags & TCP_RST)) {
552 if (TCP_SEQ_LT(pcb->lastack, ackno) &&
553 TCP_SEQ_LEQ(ackno, pcb->snd_nxt)) {
554 pcb->state = ESTABLISHED;
555 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection established %u -> %u.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
556 #if LWIP_CALLBACK_API
557 LWIP_ASSERT("pcb->accept != NULL", pcb->accept != NULL);
558 #endif
559 /* Call the accept function. */
560 TCP_EVENT_ACCEPT(pcb, ERR_OK, err);
561 if (err != ERR_OK) {
562 /* If the accept function returns with an error, we abort
563 * the connection. */
564 tcp_abort(pcb);
565 return ERR_ABRT;
567 /* If there was any data contained within this ACK,
568 * we'd better pass it on to the application as well. */
569 tcp_receive(pcb);
570 pcb->cwnd = pcb->mss;
573 break;
574 case CLOSE_WAIT:
575 /* FALLTHROUGH */
576 case ESTABLISHED:
577 tcp_receive(pcb);
578 if (flags & TCP_FIN) {
579 tcp_ack_now(pcb);
580 pcb->state = CLOSE_WAIT;
582 break;
583 case FIN_WAIT_1:
584 tcp_receive(pcb);
585 if (flags & TCP_FIN) {
586 if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
587 LWIP_DEBUGF(TCP_DEBUG,
588 ("TCP connection closed %d -> %d.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
589 tcp_ack_now(pcb);
590 tcp_pcb_purge(pcb);
591 TCP_RMV(&tcp_active_pcbs, pcb);
592 pcb->state = TIME_WAIT;
593 TCP_REG(&tcp_tw_pcbs, pcb);
594 } else {
595 tcp_ack_now(pcb);
596 pcb->state = CLOSING;
598 } else if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
599 pcb->state = FIN_WAIT_2;
601 break;
602 case FIN_WAIT_2:
603 tcp_receive(pcb);
604 if (flags & TCP_FIN) {
605 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed %u -> %u.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
606 tcp_ack_now(pcb);
607 tcp_pcb_purge(pcb);
608 TCP_RMV(&tcp_active_pcbs, pcb);
609 pcb->state = TIME_WAIT;
610 TCP_REG(&tcp_tw_pcbs, pcb);
612 break;
613 case CLOSING:
614 tcp_receive(pcb);
615 if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
616 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed %u -> %u.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
617 tcp_ack_now(pcb);
618 tcp_pcb_purge(pcb);
619 TCP_RMV(&tcp_active_pcbs, pcb);
620 pcb->state = TIME_WAIT;
621 TCP_REG(&tcp_tw_pcbs, pcb);
623 break;
624 case LAST_ACK:
625 tcp_receive(pcb);
626 if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
627 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed %u -> %u.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
628 pcb->state = CLOSED;
629 recv_flags = TF_CLOSED;
631 break;
632 default:
633 break;
636 return ERR_OK;
639 /* tcp_receive:
641 * Called by tcp_process. Checks if the given segment is an ACK for outstanding
642 * data, and if so frees the memory of the buffered data. Next, is places the
643 * segment on any of the receive queues (pcb->recved or pcb->ooseq). If the segment
644 * is buffered, the pbuf is referenced by pbuf_ref so that it will not be freed until
645 * i it has been removed from the buffer.
647 * If the incoming segment constitutes an ACK for a segment that was used for RTT
648 * estimation, the RTT is estimated here as well.
651 #undef TCP_TCPLEN
653 static int inline TCP_TCPLEN ( struct tcp_seg* apSeg ){
654 int lFlags = TCPH_FLAGS( apSeg -> tcphdr );
655 return apSeg -> len + ( ( lFlags & TCP_FIN || lFlags & TCP_SYN ) ? 1 : 0 );
656 } /* end TCP_TCPLEN */
658 static void
659 tcp_receive(struct tcp_pcb *pcb)
661 struct tcp_seg* next;
662 #if TCP_QUEUE_OOSEQ
663 struct tcp_seg* prev;
664 struct tcp_seg* cseg;
665 #endif
666 struct pbuf* p;
667 s32_t off;
668 int m;
669 u32_t right_wnd_edge;
670 int lLen;
672 if (flags & TCP_ACK)
674 right_wnd_edge = pcb->snd_wnd + pcb->snd_wl1;
676 /* Update window. */
677 if (TCP_SEQ_LT(pcb->snd_wl1, seqno) || (pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) ||
678 (pcb->snd_wl2 == ackno && tcphdr->wnd > pcb->snd_wnd))
680 pcb->snd_wnd = tcphdr->wnd;
681 pcb->snd_wl1 = seqno;
682 pcb->snd_wl2 = ackno;
685 if (pcb->lastack == ackno)
687 pcb->acked = 0;
689 if (pcb->snd_wl1 + pcb->snd_wnd == right_wnd_edge)
691 ++pcb->dupacks;
692 if (pcb->dupacks >= 3 && pcb->unacked != NULL)
694 if (!(pcb->flags & TF_INFR))
696 /* This is fast retransmit. Retransmit the first unacked segment. */
697 tcp_rexmit(pcb);
698 /* Set ssthresh to max (FlightSize / 2, 2*SMSS) */
699 pcb->ssthresh = LWIP_MAX((pcb->snd_max - pcb->lastack) / 2, 2 * pcb->mss);
701 pcb->cwnd = pcb->ssthresh + 3 * pcb->mss;
702 pcb->flags |= TF_INFR;
704 else
706 /* Inflate the congestion window, but not if it means that the value overflows. */
707 if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd)
709 pcb->cwnd += pcb->mss;
715 else if (TCP_SEQ_LT(pcb->lastack, ackno) && TCP_SEQ_LEQ(ackno, pcb->snd_max))
717 /* We come here when the ACK acknowledges new data. */
719 /* Reset the "IN Fast Retransmit" flag, since we are no longer
720 in fast retransmit. Also reset the congestion window to the
721 slow start threshold. */
722 if (pcb->flags & TF_INFR)
724 pcb->flags &= ~TF_INFR;
725 pcb->cwnd = pcb->ssthresh;
728 /* Reset the number of retransmissions. */
729 pcb->nrtx = 0;
731 /* Reset the retransmission time-out. */
732 pcb->rto = (pcb->sa >> 3) + pcb->sv;
734 /* Update the send buffer space. */
735 pcb->acked = ackno - pcb->lastack;
736 pcb->snd_buf += pcb->acked;
738 /* Reset the fast retransmit variables. */
739 pcb->dupacks = 0;
740 pcb->lastack = ackno;
742 /* Update the congestion control variables (cwnd and ssthresh). */
743 if (pcb->state >= ESTABLISHED)
745 if (pcb->cwnd < pcb->ssthresh)
747 if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd)
749 pcb->cwnd += pcb->mss;
752 else
754 u16_t new_cwnd = (pcb->cwnd + pcb->mss * pcb->mss / pcb->cwnd);
755 if (new_cwnd > pcb->cwnd)
757 pcb->cwnd = new_cwnd;
761 /* Remove segment from the unacknowledged list if the incoming ACK acknowlegdes them. */
762 while (pcb->unacked != NULL && TCP_SEQ_LEQ(ntohl(pcb->unacked->tcphdr->seqno) + TCP_TCPLEN(pcb->unacked), ackno))
764 next = pcb->unacked;
765 pcb->unacked = pcb->unacked->next;
766 pcb->snd_queuelen -= pbuf_clen(next->p);
768 tcp_seg_free(next);
771 pcb->polltmr = 0;
774 /* We go through the ->unsent list to see if any of the segments
775 on the list are acknowledged by the ACK. This may seem
776 strange since an "unsent" segment shouldn't be acked. The
777 rationale is that lwIP puts all outstanding segments on the
778 ->unsent list after a retransmission, so these segments may
779 in fact have been sent once. */
780 while (pcb->unsent != NULL && TCP_SEQ_LEQ((lLen=ntohl(pcb->unsent->tcphdr->seqno)) + TCP_TCPLEN(pcb->unsent),ackno) &&
781 TCP_SEQ_LEQ(ackno, pcb->snd_max))
783 next = pcb->unsent;
784 pcb->unsent = pcb->unsent->next;
786 pcb->snd_queuelen -= pbuf_clen(next->p);
787 tcp_seg_free(next);
789 if (pcb->unsent != NULL) pcb->snd_nxt = lLen;
793 /* End of ACK for new data processing. */
795 /* RTT estimation calculations. This is done by checking if the incoming segment acknowledges the segment we use to take a
796 round-trip time measurement. */
797 if (pcb->rttest && TCP_SEQ_LT(pcb->rtseq, ackno))
799 m = tcp_ticks - pcb->rttest;
801 /* This is taken directly from VJs original code in his paper */
802 m = m - (pcb->sa >> 3);
803 pcb->sa += m;
804 if (m < 0)
806 m = -m;
808 m = m - (pcb->sv >> 2);
809 pcb->sv += m;
810 pcb->rto = (pcb->sa >> 3) + pcb->sv;
812 pcb->rttest = 0;
816 /* If the incoming segment contains data, we must process it further. */
817 if (tcplen > 0)
819 /* This code basically does three things:
821 +) If the incoming segment contains data that is the next
822 in-sequence data, this data is passed to the application. This
823 might involve trimming the first edge of the data. The rcv_nxt
824 variable and the advertised window are adjusted.
826 +) If the incoming segment has data that is above the next
827 sequence number expected (->rcv_nxt), the segment is placed on
828 the ->ooseq queue. This is done by finding the appropriate
829 place in the ->ooseq queue (which is ordered by sequence
830 number) and trim the segment in both ends if needed. An
831 immediate ACK is sent to indicate that we received an
832 out-of-sequence segment.
834 +) Finally, we check if the first segment on the ->ooseq queue
835 now is in sequence (i.e., if rcv_nxt >= ooseq->seqno). If
836 rcv_nxt > ooseq->seqno, we must trim the first edge of the
837 segment on ->ooseq before we adjust rcv_nxt. The data in the
838 segments that are now on sequence are chained onto the
839 incoming segment so that we only need to call the application
840 once.
843 /* First, we check if we must trim the first edge. We have to do
844 this if the sequence number of the incoming segment is less
845 than rcv_nxt, and the sequence number plus the length of the
846 segment is larger than rcv_nxt. */
847 if (TCP_SEQ_LT(seqno, pcb->rcv_nxt))
849 if (TCP_SEQ_LT(pcb->rcv_nxt, seqno + tcplen))
851 /* Trimming the first edge is done by pushing the payload
852 pointer in the pbuf downwards. This is somewhat tricky since
853 we do not want to discard the full contents of the pbuf up to
854 the new starting point of the data since we have to keep the
855 TCP header which is present in the first pbuf in the chain.
857 What is done is really quite a nasty hack: the first pbuf in
858 the pbuf chain is pointed to by inseg.p. Since we need to be
859 able to deallocate the whole pbuf, we cannot change this
860 inseg.p pointer to point to any of the later pbufs in the
861 chain. Instead, we point the ->payload pointer in the first
862 pbuf to data in one of the later pbufs. We also set the
863 inseg.data pointer to point to the right place. This way, the
864 ->p pointer will still point to the first pbuf, but the
865 ->p->payload pointer will point to data in another pbuf.
867 After we are done with adjusting the pbuf pointers we must
868 adjust the ->data pointer in the seg and the segment
869 length.*/
870 off = pcb->rcv_nxt - seqno;
871 if (inseg.p->len < off)
873 p = inseg.p;
874 while (p->len < off)
876 off -= p->len;
877 inseg.p->tot_len -= p->len;
878 p->len = 0;
879 p = p->next;
881 pbuf_header(p, -off);
883 else
885 pbuf_header(inseg.p, -off);
887 inseg.dataptr = inseg.p->payload;
888 inseg.len -= pcb->rcv_nxt - seqno;
889 inseg.tcphdr->seqno = seqno = pcb->rcv_nxt;
891 else
893 /* the whole segment is < rcv_nxt */
894 /* must be a duplicate of a packet that has already been correctly handled */
896 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: duplicate seqno %lu\n", seqno));
897 tcp_ack_now(pcb);
901 /* The sequence number must be within the window (above rcv_nxt
902 and below rcv_nxt + rcv_wnd) in order to be further
903 processed. */
904 if (TCP_SEQ_GEQ(seqno, pcb->rcv_nxt) && TCP_SEQ_LT(seqno, pcb->rcv_nxt + pcb->rcv_wnd))
906 if (pcb->rcv_nxt == seqno)
908 int tcpflags;
909 /* The incoming segment is the next in sequence. We check if
910 we have to trim the end of the segment and update rcv_nxt
911 and pass the data to the application. */
912 #if TCP_QUEUE_OOSEQ
913 if (pcb->ooseq != NULL && TCP_SEQ_LEQ(pcb->ooseq->tcphdr->seqno, seqno + inseg.len))
915 /* We have to trim the second edge of the incoming segment. */
916 inseg.len = pcb->ooseq->tcphdr->seqno - seqno;
917 pbuf_realloc(inseg.p, inseg.len);
919 #endif /* TCP_QUEUE_OOSEQ */
921 tcpflags = TCPH_FLAGS( inseg.tcphdr );
922 tcplen = inseg.len + ((tcpflags & TCP_FIN || tcpflags & TCP_SYN)? 1: 0);
923 pcb->rcv_nxt += tcplen;
925 /* Update the receiver's (our) window. */
926 if (pcb->rcv_wnd < tcplen)
928 pcb->rcv_wnd = 0;
930 else
932 pcb->rcv_wnd -= tcplen;
935 /* If there is data in the segment, we make preparations to
936 pass this up to the application. The ->recv_data variable
937 is used for holding the pbuf that goes to the
938 application. The code for reassembling out-of-sequence data
939 chains its data on this pbuf as well.
941 If the segment was a FIN, we set the TF_GOT_FIN flag that will
942 be used to indicate to the application that the remote side has
943 closed its end of the connection. */
944 if (inseg.p->tot_len > 0)
946 recv_data = inseg.p;
947 /* Since this pbuf now is the responsibility of the
948 application, we delete our reference to it so that we won't
949 (mistakingly) deallocate it. */
950 inseg.p = NULL;
952 if (tcpflags & TCP_FIN)
954 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN.\n"));
955 recv_flags = TF_GOT_FIN;
958 #if TCP_QUEUE_OOSEQ
959 /* We now check if we have segments on the ->ooseq queue that is now in sequence. */
960 while (pcb->ooseq != NULL && pcb->ooseq->tcphdr->seqno == pcb->rcv_nxt)
962 int lLen;
963 int lFlags;
965 cseg = pcb->ooseq;
966 seqno = pcb->ooseq->tcphdr->seqno;
967 lFlags = TCPH_FLAGS( cseg -> tcphdr );
968 lLen = cseg->len + ((lFlags & TCP_FIN || lFlags & TCP_SYN)? 1: 0);
969 pcb->rcv_nxt += lLen;
970 if (pcb->rcv_wnd < lLen)
972 pcb->rcv_wnd = 0;
974 else
976 pcb->rcv_wnd -= lLen;
978 if (cseg->p->tot_len > 0)
980 /* Chain this pbuf onto the pbuf that we will pass to the application. */
981 if (recv_data)
983 pbuf_cat(recv_data, cseg->p);
985 else
987 recv_data = cseg->p;
989 cseg->p = NULL;
991 if (lFlags & TCP_FIN) recv_flags = TF_GOT_FIN;
993 pcb->ooseq = cseg->next;
994 tcp_seg_free(cseg);
996 #endif /* TCP_QUEUE_OOSEQ */
998 /* Acknowledge the segment(s). */
999 tcp_ack(pcb);
1002 else
1004 /* We get here if the incoming segment is out-of-sequence. */
1005 tcp_ack_now(pcb);
1006 #if TCP_QUEUE_OOSEQ
1007 /* We queue the segment on the ->ooseq queue. */
1008 if (pcb->ooseq == NULL)
1010 pcb->ooseq = tcp_seg_copy(&inseg);
1012 else
1014 /* If the queue is not empty, we walk through the queue and
1015 try to find a place where the sequence number of the
1016 incoming segment is between the sequence numbers of the
1017 previous and the next segment on the ->ooseq queue. That is
1018 the place where we put the incoming segment. If needed, we
1019 trim the second edges of the previous and the incoming
1020 segment so that it will fit into the sequence.
1022 If the incoming segment has the same sequence number as a
1023 segment on the ->ooseq queue, we discard the segment that
1024 contains less data. */
1026 prev = NULL;
1027 for (next = pcb->ooseq; next != NULL; next = next->next)
1029 if (seqno == next->tcphdr->seqno)
1031 /* The sequence number of the incoming segment is the
1032 same as the sequence number of the segment on
1033 ->ooseq. We check the lengths to see which one to
1034 discard. */
1035 if (inseg.len > next->len)
1037 /* The incoming segment is larger than the old
1038 segment. We replace the old segment with the new
1039 one. */
1040 cseg = tcp_seg_copy(&inseg);
1041 if (cseg != NULL)
1043 cseg->next = next->next;
1044 if (prev != NULL)
1046 prev->next = cseg;
1048 else
1050 pcb->ooseq = cseg;
1053 break;
1055 else
1057 /* Either the lenghts are the same or the incoming
1058 segment was smaller than the old one; in either
1059 case, we ditch the incoming segment. */
1060 break;
1063 else
1065 if (prev == NULL)
1067 if (TCP_SEQ_LT(seqno, next->tcphdr->seqno))
1069 /* The sequence number of the incoming segment is lower
1070 than the sequence number of the first segment on the
1071 queue. We put the incoming segment first on the
1072 queue. */
1074 if (TCP_SEQ_GT(seqno + inseg.len, next->tcphdr->seqno))
1076 /* We need to trim the incoming segment. */
1077 inseg.len = next->tcphdr->seqno - seqno;
1078 pbuf_realloc(inseg.p, inseg.len);
1080 cseg = tcp_seg_copy(&inseg);
1081 if (cseg != NULL)
1083 cseg->next = next;
1084 pcb->ooseq = cseg;
1086 break;
1089 else if (TCP_SEQ_LT(prev->tcphdr->seqno, seqno) && TCP_SEQ_LT(seqno, next->tcphdr->seqno))
1091 /* The sequence number of the incoming segment is in
1092 between the sequence numbers of the previous and
1093 the next segment on ->ooseq. We trim and insert the
1094 incoming segment and trim the previous segment, if
1095 needed. */
1096 if (TCP_SEQ_GT(seqno + inseg.len, next->tcphdr->seqno))
1098 /* We need to trim the incoming segment. */
1099 inseg.len = next->tcphdr->seqno - seqno;
1100 pbuf_realloc(inseg.p, inseg.len);
1103 cseg = tcp_seg_copy(&inseg);
1104 if (cseg != NULL)
1106 cseg->next = next;
1107 prev->next = cseg;
1108 if (TCP_SEQ_GT(prev->tcphdr->seqno + prev->len, seqno))
1110 /* We need to trim the prev segment. */
1111 prev->len = seqno - prev->tcphdr->seqno;
1112 pbuf_realloc(prev->p, prev->len);
1115 break;
1117 /* If the "next" segment is the last segment on the
1118 ooseq queue, we add the incoming segment to the end
1119 of the list. */
1120 if (next->next == NULL && TCP_SEQ_GT(seqno, next->tcphdr->seqno))
1122 next->next = tcp_seg_copy(&inseg);
1123 if (next->next != NULL)
1125 if (TCP_SEQ_GT(next->tcphdr->seqno + next->len, seqno))
1127 /* We need to trim the last segment. */
1128 next->len = seqno - next->tcphdr->seqno;
1129 pbuf_realloc(next->p, next->len);
1132 break;
1135 prev = next;
1138 #endif /* TCP_QUEUE_OOSEQ */
1143 else
1145 /* Segments with length 0 is taken care of here. Segments that fall out of the window are ACKed. */
1146 if (TCP_SEQ_GT(pcb->rcv_nxt, seqno) || TCP_SEQ_GEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd))
1148 tcp_ack_now(pcb);
1154 * tcp_parseopt:
1156 * Parses the options contained in the incoming segment. (Code taken
1157 * from uIP with only small changes.)
1161 static void
1162 tcp_parseopt(struct tcp_pcb *pcb)
1164 u8_t c;
1165 u8_t *opts, opt;
1166 u16_t mss;
1167 int lLen = TCPH_HDRLEN(tcphdr);
1169 opts = (u8_t *)tcphdr + TCP_HLEN;
1171 /* Parse the TCP MSS option, if present. */
1172 if(lLen > 0x5) {
1173 for(c = 0; c < (lLen - 5) << 2 ;) {
1174 opt = opts[c];
1175 if (opt == 0x00) {
1176 /* End of options. */
1177 break;
1178 } else if (opt == 0x01) {
1179 ++c;
1180 /* NOP option. */
1181 } else if (opt == 0x02 &&
1182 opts[c + 1] == 0x04) {
1183 /* An MSS option with the right option length. */
1184 mss = (opts[c + 2] << 8) | opts[c + 3];
1185 pcb->mss = mss > TCP_MSS? TCP_MSS: mss;
1187 /* And we are done processing options. */
1188 break;
1189 } else {
1190 if (opts[c + 1] == 0) {
1191 /* If the length field is zero, the options are malformed
1192 and we don't process them further. */
1193 break;
1195 /* All other options have a length field, so that we easily
1196 can skip past them. */
1197 c += opts[c + 1];
1202 #endif /* LWIP_TCP */