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