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