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