MeterLogger
tcp_in.c
Go to the documentation of this file.
1 /**
2  * @file
3  * Transmission Control Protocol, incoming traffic
4  *
5  * The input processing functions of the TCP layer.
6  *
7  * These functions are generally called in the order (ip_input() ->)
8  * tcp_input() -> * tcp_process() -> tcp_receive() (-> application).
9  *
10  */
11 
12 /*
13  * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
14  * All rights reserved.
15  *
16  * Redistribution and use in source and binary forms, with or without modification,
17  * are permitted provided that the following conditions are met:
18  *
19  * 1. Redistributions of source code must retain the above copyright notice,
20  * this list of conditions and the following disclaimer.
21  * 2. Redistributions in binary form must reproduce the above copyright notice,
22  * this list of conditions and the following disclaimer in the documentation
23  * and/or other materials provided with the distribution.
24  * 3. The name of the author may not be used to endorse or promote products
25  * derived from this software without specific prior written permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
28  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
29  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
30  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
32  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
35  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
36  * OF SUCH DAMAGE.
37  *
38  * This file is part of the lwIP TCP/IP stack.
39  *
40  * Author: Adam Dunkels <adam@sics.se>
41  *
42  */
43 
44 #include "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 #ifdef MEMLEAK_DEBUG
60 static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__;
61 #endif
62 
63 /* These variables are global to all functions involved in the input
64  processing of TCP segments. They are set by the tcp_input()
65  function. */
66 static struct tcp_seg inseg; //tcp_seg�ṹ����������ı��Ķ�
67 static struct tcp_hdr *tcphdr; //���Ķ���TCP�ײ�
68 static struct ip_hdr *iphdr; //IP��ݰ��ײ�
69 static u32_t seqno, ackno; //TCP�ײ�������ֶ���ȷ�Ϻ��ֶ�
70 static u8_t flags; //�ײ���־�ֶ�
71 static u16_t tcplen; //TCP���ij���
72 
73 static u8_t recv_flags; //��ǰ���Ĵ�����
74 static struct pbuf *recv_data; //���Ķ����pbuf
75 
76 struct tcp_pcb *tcp_input_pcb; //��ǰ���Ŀ��ƿ�
77 
78 /* Forward declarations. */
79 static err_t tcp_process(struct tcp_pcb *pcb)ICACHE_FLASH_ATTR;
80 static void tcp_receive(struct tcp_pcb *pcb)ICACHE_FLASH_ATTR;
81 static void tcp_parseopt(struct tcp_pcb *pcb)ICACHE_FLASH_ATTR;
82 
83 static err_t tcp_listen_input(struct tcp_pcb_listen *pcb)ICACHE_FLASH_ATTR;
84 static err_t tcp_timewait_input(struct tcp_pcb *pcb)ICACHE_FLASH_ATTR;
85 
86 /**
87  * The initial input processing of TCP. It verifies the TCP header, demultiplexes
88  * the segment between the PCBs and passes it on to tcp_process(), which implements
89  * the TCP finite state machine. This function is called by the IP layer (in
90  * ip_input()).
91  *
92  * @param p received TCP segment to process (p->payload pointing to the IP header)
93  * @param inp network interface on which this segment was received
94  */
95  /**
96  * TCP��ʼ�����봦�?��֤��TCPͷ���������IP�����
97 
98  * @����p:������յ�TCP��(ָ��IPͷ�ĸ���)
99  * @����inp:���նε�����ӿ�
100  */
101 void
102 tcp_input(struct pbuf *p, struct netif *inp)
103 {
104  struct tcp_pcb *pcb, *prev;
105  struct tcp_pcb_listen *lpcb;
106 #if SO_REUSE
107  struct tcp_pcb *lpcb_prev = NULL;
108  struct tcp_pcb_listen *lpcb_any = NULL;
109 #endif /* SO_REUSE */
110  u8_t hdrlen;
111  err_t err;
112 
113  PERF_START;
114 
115  TCP_STATS_INC(tcp.recv); //״̬��1
116  snmp_inc_tcpinsegs(); //tcp����μ�1
117 
118  iphdr = (struct ip_hdr *)p->payload;// pointer to the actual data in the buffer
119  /*
120  *��ͷ����(IHL)��4λ��IPЭ���ͷ�ij��ȣ�ָ��IPv4Э���ͷ���ȵ��ֽ������ٸ�32λ��
121  *����IPv4�İ�ͷ���ܰ�ɱ������Ŀ�ѡ ���������ֶο�������ȷ��IPv4��ݱ�����ݲ��ֵ�ƫ������
122  *IPv4��ͷ����С������20���ֽڣ����IHL����ֶε���Сֵ��ʮ���Ʊ�ʾ����5 (5x4 = 20�ֽ�)��
123  *����˵�����ʾ�İ�ͷ�����ֽ�����4�ֽڵı���
124  */
125  tcphdr = (struct tcp_hdr *)((u8_t *)p->payload + IPH_HL(iphdr) * 4);
126 
127 #if TCP_INPUT_DEBUG
128  tcp_debug_print(tcphdr);
129 #endif
130 
131  /* remove header from payload */
132  if (pbuf_header(p, -((s16_t)(IPH_HL(iphdr) * 4))) || (p->tot_len < sizeof(struct tcp_hdr))) {
133  /* drop short packets */
134  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet (%"U16_F" bytes) discarded\n", p->tot_len));
135  TCP_STATS_INC(tcp.lenerr);//���󳤶ȼ���
136  TCP_STATS_INC(tcp.drop);//��ֹ����
138  pbuf_free(p);//�ͷ�buffer
139  return;
140  }
141 
142  /* Don't even process incoming broadcasts/multicasts. */
145  TCP_STATS_INC(tcp.proterr);//Э��������
146  TCP_STATS_INC(tcp.drop);
148  pbuf_free(p);
149  return;
150  }
151 
152 #if CHECKSUM_CHECK_TCP
153  /* Verify TCP checksum. */
155  IP_PROTO_TCP, p->tot_len) != 0) {
156  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packet discarded due to failing checksum 0x%04"X16_F"\n",
158  IP_PROTO_TCP, p->tot_len)));
159 #if TCP_DEBUG
160  tcp_debug_print(tcphdr);
161 #endif /* TCP_DEBUG */
162  TCP_STATS_INC(tcp.chkerr);//У��������
163  TCP_STATS_INC(tcp.drop);
165  pbuf_free(p);
166  return;
167  }
168 #endif
169 
170  /* Move the payload pointer in the pbuf so that it points to the
171  TCP data instead of the TCP header. */
172  hdrlen = TCPH_HDRLEN(tcphdr);//����ͷ�ij���
173  if(pbuf_header(p, -(hdrlen * 4))){//���TCPͷ������0Ϊ�ɹ�������
174  /* drop short packets */
175  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet\n"));
176  TCP_STATS_INC(tcp.lenerr);//tcp���ȴ������
177  TCP_STATS_INC(tcp.drop);
179  pbuf_free(p);
180  return;
181  }
182 
183  /* Convert fields in TCP header to host byte order. */
184  tcphdr->src = ntohs(tcphdr->src); //ת��Դ��ַ
185  tcphdr->dest = ntohs(tcphdr->dest); //ת��Ŀ�ĵ�ַ
186  seqno = tcphdr->seqno = ntohl(tcphdr->seqno); //ת�����к�
187  ackno = tcphdr->ackno = ntohl(tcphdr->ackno); //ת��Ӧ���
188  tcphdr->wnd = ntohs(tcphdr->wnd); //ת��tcp����
189 
190  flags = TCPH_FLAGS(tcphdr);//�õ�tcp header�ı�־
191  /*
192  *��־��3λ�����ֶΣ���
193  * ����λ��1λ
194  * ���ֶ�λ��1λ��ȡֵ��0��������ݱ��ֶΣ���1����ݱ����ֶܷΣ�
195  * ����λ��1λ��ȡֵ��0����ݰ����û�а�1����ݰ�����и��İ�
196  */
197  tcplen = p->tot_len + ((flags & (TCP_FIN | TCP_SYN)) ? 1 : 0);//TCP_FIN �� TCP_SYN ��λ��1�������0
198 
199  /* Demultiplex an incoming segment. First, we check if it is destined
200  for an active connection. ���ȣ�����Ƿ�һ��Ҫ����һ������*/
201  ////////////////////////////////////////////////////////////////////////////////////////
202  prev = NULL;
203  for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {//������б�
204  LWIP_ASSERT("tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED);
205  LWIP_ASSERT("tcp_input: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);
206  LWIP_ASSERT("tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN);
207  if (pcb->remote_port == tcphdr->src &&
208  pcb->local_port == tcphdr->dest &&
209  ip_addr_cmp(&(pcb->remote_ip), &current_iphdr_src) &&
210  ip_addr_cmp(&(pcb->local_ip), &current_iphdr_dest)) {//�����صĵ�ַ
211 
212  /* Move this PCB to the front of the list so that subsequent
213  lookups will be faster (we exploit locality in TCP segment
214  arrivals). */
215  LWIP_ASSERT("tcp_input: pcb->next != pcb (before cache)", pcb->next != pcb);
216  if (prev != NULL) {//���ǰһ���ڵ㲻Ϊ��
217  prev->next = pcb->next;
218  pcb->next = tcp_active_pcbs;
219  tcp_active_pcbs = pcb;//pcb������ǰ��
220  }
221  LWIP_ASSERT("tcp_input: pcb->next != pcb (after cache)", pcb->next != pcb);
222  break;
223  }
224  prev = pcb;//prevָ��pcb
225  }
226 
227  if (pcb == NULL) {
228  /* If it did not go to an active connection, we check the connections
229  in the TIME-WAIT state. */
230  for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {//����ȴ�״̬�µ�pcb
231  LWIP_ASSERT("tcp_input: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
232  if (pcb->remote_port == tcphdr->src &&
233  pcb->local_port == tcphdr->dest &&
234  ip_addr_cmp(&(pcb->remote_ip), &current_iphdr_src) &&
235  ip_addr_cmp(&(pcb->local_ip), &current_iphdr_dest)) {
236  /* We don't really care enough to move this PCB to the front
237  of the list since we are not very likely to receive that
238  many segments for connections in TIME-WAIT. */
239  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for TIME_WAITing connection.\n"));
240  tcp_timewait_input(pcb);//����tcp timewait �İ�
241  pbuf_free(p);
242  return;
243  }
244  }
245 
246  /* Finally, if we still did not get a match, we check all PCBs that
247  are LISTENing for incoming connections. */
248  prev = NULL;
249  for(lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {//�������״̬�����е�pcb
250  if (lpcb->local_port == tcphdr->dest) {
251 #if SO_REUSE
252  if (ip_addr_cmp(&(lpcb->local_ip), &current_iphdr_dest)) {
253  /* found an exact match */
254  break;
255  } else if(ip_addr_isany(&(lpcb->local_ip))) {
256  /* found an ANY-match */
257  lpcb_any = lpcb;
258  lpcb_prev = prev;
259  }
260 #else /* SO_REUSE */
261  if (ip_addr_cmp(&(lpcb->local_ip), &current_iphdr_dest) ||
262  ip_addr_isany(&(lpcb->local_ip))) {
263  /* found a match */
264  break;
265  }
266 #endif /* SO_REUSE */
267  }
268  prev = (struct tcp_pcb *)lpcb;
269  }
270 #if SO_REUSE
271  /* first try specific local IP */
272  if (lpcb == NULL) {
273  /* only pass to ANY if no specific local IP has been found */
274  lpcb = lpcb_any;
275  prev = lpcb_prev;
276  }
277 #endif /* SO_REUSE */
278  if (lpcb != NULL) {
279  /* Move this PCB to the front of the list so that subsequent
280  lookups will be faster (we exploit locality in TCP segment
281  arrivals). */
282  if (prev != NULL) {
283  ((struct tcp_pcb_listen *)prev)->next = lpcb->next;
284  /* our successor is the remainder of the listening list */
285  lpcb->next = tcp_listen_pcbs.listen_pcbs;
286  /* put this listening pcb at the head of the listening list */
287  tcp_listen_pcbs.listen_pcbs = lpcb;
288  }
289 
290  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for LISTENing connection.\n"));
291  tcp_listen_input(lpcb);//����tcp������ݰ�
292  pbuf_free(p);
293  return;
294  }
295  }
296 
297 #if TCP_INPUT_DEBUG
298  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("+-+-+-+-+-+-+-+-+-+-+-+-+-+- tcp_input: flags "));
299  tcp_debug_print_flags(TCPH_FLAGS(tcphdr));
300  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n"));
301 #endif /* TCP_INPUT_DEBUG */
302 
303 
304  if (pcb != NULL) {
305  /* The incoming segment belongs to a connection. */
306 #if TCP_INPUT_DEBUG
307 #if TCP_DEBUG
308  tcp_debug_print_state(pcb->state);
309 #endif /* TCP_DEBUG */
310 #endif /* TCP_INPUT_DEBUG */
311 
312  /* Set up a tcp_seg structure. */
313  inseg.next = NULL;
314  inseg.len = p->tot_len;
315  inseg.p = p;
316  inseg.tcphdr = tcphdr;
317 
318  recv_data = NULL;
319  recv_flags = 0;
320 
321  /* If there is data which was previously "refused" by upper layer */
322  if (pcb->refused_data != NULL) {
323  /* Notify again application with data previously received. */
324  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: notify kept packet\n"));
325  TCP_EVENT_RECV(pcb, pcb->refused_data, ERR_OK, err);//pcb�������
326  if (err == ERR_OK) {
327  pcb->refused_data = NULL;
328  } else if ((err == ERR_ABRT) || (tcplen > 0)) {
329  /* if err == ERR_ABRT, 'pcb' is already deallocated */
330  /* Drop incoming packets because pcb is "full" (only if the incoming
331  segment contains data). */
332  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: drop incoming packets, because pcb is \"full\"\n"));
333  TCP_STATS_INC(tcp.drop);//tcp�������
335  pbuf_free(p);
336  return;
337  }
338  }
339  tcp_input_pcb = pcb;//��¼��ǰ���Ĵ���Ŀ��ƿ�
340  err = tcp_process(pcb);//���?��
341  /* A return value of ERR_ABRT means that tcp_abort() was called
342  and that the pcb has been freed. If so, we don't do anything. */
343  if (err != ERR_ABRT) {
344  if (recv_flags & TF_RESET) {
345  /* TF_RESET means that the connection was reset by the other
346  end. We then call the error callback to inform the
347  application that the connection is dead before we
348  deallocate the PCB. */
349  TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_RST);
350  tcp_pcb_remove(&tcp_active_pcbs, pcb);//ɾ���pcb�б��е�pcb
351  memp_free(MEMP_TCP_PCB, pcb);
352  } else if (recv_flags & TF_CLOSED) {
353  /* The connection has been closed and we will deallocate the
354  PCB. */
355  if (!(pcb->flags & TF_RXCLOSED)) {
356  /* Connection closed although the application has only shut down the
357  tx side: call the PCB's err callback and indicate the closure to
358  ensure the application doesn't continue using the PCB. */
359  TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_CLSD);
360  }
361  tcp_pcb_remove(&tcp_active_pcbs, pcb);
362  memp_free(MEMP_TCP_PCB, pcb);
363  } else {
364  err = ERR_OK;
365  /* If the application has registered a "sent" function to be
366  called when new send buffer space is available, we call it
367  now. */
368  if (pcb->acked > 0) {
369  TCP_EVENT_SENT(pcb, pcb->acked, err);//����ݱ�ȷ�ϣ��ص��û���send����
370  if (err == ERR_ABRT) {
371  goto aborted;
372  }
373  }
374 
375  if (recv_data != NULL) {//����ݽ��յ�
376  LWIP_ASSERT("pcb->refused_data == NULL", pcb->refused_data == NULL);
377  if (pcb->flags & TF_RXCLOSED) {
378  /* received data although already closed -> abort (send RST) to
379  notify the remote host that not all data has been processed */
380  pbuf_free(recv_data);
381  tcp_abort(pcb);
382  goto aborted;
383  }
384 
385  //PSH��־ PSH ����λ��
386  //��PSH=1ʱ��Ҫ���ͷ����Ϸ��͸÷ֶΣ�
387  //����շ�����Ľ����Ľ���Ӧ�ò㣬�������д��?
388 
389  if (flags & TCP_PSH) {
390  recv_data->flags |= PBUF_FLAG_PUSH;//���bufferӦ������������
391  }
392 
393  /* Notify application that data has been received. */
394  TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err);
395  if (err == ERR_ABRT) {
396  goto aborted;
397  }
398 
399  /* If the upper layer can't receive this data, store it */
400  if (err != ERR_OK) {
401  pcb->refused_data = recv_data;
402  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: keep incoming packet, because pcb is \"full\"\n"));
403  }
404  }
405 
406  /* If a FIN segment was received, we call the callback
407  function with a NULL buffer to indicate EOF. */
408  if (recv_flags & TF_GOT_FIN) {
409  /* correct rcv_wnd as the application won't call tcp_recved()
410  for the FIN's seqno */
411  if (pcb->rcv_wnd != TCP_WND) {
412  pcb->rcv_wnd++;
413  }
414 
415  TCP_EVENT_CLOSED(pcb, err);
416  if (err == ERR_ABRT) {
417  goto aborted;
418  }
419  }
420 
421  tcp_input_pcb = NULL;//���ȫ�ֱ���
422  /* Try to send something out. */
423  tcp_output(pcb);//�����������
424 #if TCP_INPUT_DEBUG
425 #if TCP_DEBUG
426  tcp_debug_print_state(pcb->state);
427 #endif /* TCP_DEBUG */
428 #endif /* TCP_INPUT_DEBUG */
429  }
430  }
431  /* Jump target if pcb has been aborted in a callback (by calling tcp_abort()).
432  Below this line, 'pcb' may not be dereferenced! */
433 aborted:
434  tcp_input_pcb = NULL;
435  recv_data = NULL;
436 
437  /* give up our reference to inseg.p */
438  if (inseg.p != NULL)
439  {
440  pbuf_free(inseg.p);//�ͷ�buffer
441  inseg.p = NULL;
442  }
443 
444  /*add processing queue segments that arrive out of order by LiuHan*/
445 #if TCP_QUEUE_OOSEQ
446  extern char RxNodeNum(void);
447  if (RxNodeNum() < 2){
448  extern void pbuf_free_ooseq_new(void* arg);
449 // os_printf("reclaim some memory from queued\n");
450  pbuf_free_ooseq_new(NULL);
451  }
452 #endif
453  } else {
454 
455  /* If no matching PCB was found, send a TCP RST (reset) to the
456  sender. */
457  LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_input: no PCB match found, resetting.\n"));
458  if (!(TCPH_FLAGS(tcphdr) & TCP_RST)) {
459  TCP_STATS_INC(tcp.proterr);//Э��������
460  TCP_STATS_INC(tcp.drop);//tcp�������
461  tcp_rst(ackno, seqno + tcplen,
463  tcphdr->dest, tcphdr->src);//����TCP��λ
464  }
465  pbuf_free(p);
466  }
467 
468  LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane());
469  PERF_STOP("tcp_input");
470 }
471 
472 /**
473  * Called by tcp_input() when a segment arrives for a listening
474  * connection (from tcp_input()).
475  *
476  * @param pcb the tcp_pcb_listen for which a segment arrived
477  * @return ERR_OK if the segment was processed
478  * another err_t on error
479  *
480  * @note the return value is not (yet?) used in tcp_input()
481  * @note the segment which arrived is saved in global variables, therefore only the pcb
482  * involved is passed as a parameter to this function
483  */
484  /*
485 *����LISTEN״̬�Ŀ��ƿ���øú���
486 *ͨ���Ƿ�������������һ���˿ڲ�����ͻ���SYN��������
487 *
488 */
489 static err_t
490 tcp_listen_input(struct tcp_pcb_listen *pcb)
491 {
492  struct tcp_pcb *npcb;
493  struct tcp_pcb *pactive_pcb;
494  u8_t active_pcb_num = 0;
495  err_t rc;
496 
497  /* In the LISTEN state, we check for incoming SYN segments,
498  creates a new PCB, and responds with a SYN|ACK. */
499  if (flags & TCP_ACK) {
500  /* For incoming segments with the ACK flag set, respond with a
501  RST. */
502  LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_listen_input: ACK in LISTEN, sending reset\n"));
503  tcp_rst(ackno + 1, seqno + tcplen,
505  tcphdr->dest, tcphdr->src);
506  } else if (flags & TCP_SYN) {//�յ�SYN����
507  LWIP_DEBUGF(TCP_DEBUG, ("TCP connection request %"U16_F" -> %"U16_F".\n", tcphdr->src, tcphdr->dest));
508 #if TCP_LISTEN_BACKLOG
509  if (pcb->accepts_pending >= pcb->backlog) {
510  LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: listen backlog exceeded for port %"U16_F"\n", tcphdr->dest));
511  return ERR_ABRT;
512  }
513 #endif /* TCP_LISTEN_BACKLOG */
514  for(pactive_pcb = tcp_active_pcbs; pactive_pcb != NULL; pactive_pcb = pactive_pcb->next)
515  active_pcb_num ++;
516  if (active_pcb_num == MEMP_NUM_TCP_PCB){
517  LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: exceed the number of active TCP connections\n"));
518  TCP_STATS_INC(tcp.memerr);
519  return ERR_MEM;
520  }
521  npcb = tcp_alloc(pcb->prio);//�������ƿ�
522  /* If a new PCB could not be created (probably due to lack of memory),
523  we don't do anything, but rely on the sender will retransmit the
524  SYN at a time when we have more memory available. */
525  if (npcb == NULL) {
526  LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: could not allocate PCB\n"));
527  TCP_STATS_INC(tcp.memerr);//TCP�ڴ�������
528  return ERR_MEM;
529  }
530 
531 #if TCP_LISTEN_BACKLOG
532  pcb->accepts_pending++;
533 #endif /* TCP_LISTEN_BACKLOG */
534  /* Set up the new PCB. */
535  //���ƿ���������ص�4���ֶ�
536  ip_addr_copy(npcb->local_ip, current_iphdr_dest);
537  npcb->local_port = pcb->local_port;
538  ip_addr_copy(npcb->remote_ip, current_iphdr_src);
539  npcb->remote_port = tcphdr->src;
540 
541  //���ƿ��������ֶ�
542  npcb->state = SYN_RCVD;//��������״̬
543  npcb->rcv_nxt = seqno + 1;//������һ������������
544  npcb->rcv_ann_right_edge = npcb->rcv_nxt;
545  npcb->snd_wnd = tcphdr->wnd;//���÷��ʹ���
546  npcb->ssthresh = npcb->snd_wnd;
547  npcb->snd_wl1 = seqno - 1;/* initialise to seqno-1 to force window update */
548  npcb->callback_arg = pcb->callback_arg;
549 #if LWIP_CALLBACK_API
550  npcb->accept = pcb->accept;
551 #endif /* LWIP_CALLBACK_API */
552  /* inherit socket options */
553  npcb->so_options = pcb->so_options & SOF_INHERITED;
554  /* Register the new PCB so that we can begin receiving segments
555  for it. */
556  TCP_REG(&tcp_active_pcbs, npcb);
557 
558  /* Parse any options in the SYN. */
559  tcp_parseopt(npcb);
560 #if TCP_CALCULATE_EFF_SEND_MSS
561  npcb->mss = tcp_eff_send_mss(npcb->mss, &(npcb->remote_ip));
562 #endif /* TCP_CALCULATE_EFF_SEND_MSS */
563 
565 
566  /* Send a SYN|ACK together with the MSS option. */
567  rc = tcp_enqueue_flags(npcb, TCP_SYN | TCP_ACK);
568  if (rc != ERR_OK) {//��������ͷ��¿��ƿ�
569  tcp_abandon(npcb, 0);
570  return rc;
571  }
572  return tcp_output(npcb);//���ͱ���
573  }
574  return ERR_OK;
575 }
576 
577 /**
578  * Called by tcp_input() when a segment arrives for a connection in
579  * TIME_WAIT.
580  *
581  * @param pcb the tcp_pcb for which a segment arrived
582  *
583  * @note the segment which arrived is saved in global variables, therefore only the pcb
584  * involved is passed as a parameter to this function
585  */
586  /*
587 *����TIME_WAIT״̬�Ŀ��ƿ���øú������յ��ı��ĶΣ�
588 *��״̬�£��ر����ӵ����ֹ���Ѿ��������ڵȴ�2MSL��ʱ��
589 *��״̬�µı��Ķ����������еľ���ݣ�ֱ��ɾ��ɡ�
590 *����Ҫ���ͷ�����ACK����
591 */
592 static err_t
593 tcp_timewait_input(struct tcp_pcb *pcb)
594 {
595 
596  if (flags & TCP_RST) { //RST��λ��ֱ�ӷ���
597  return ERR_OK;
598  }
599 
600  if (flags & TCP_SYN) { //��SYN������Ϣ����������ݱ���ڽ��մ����ڣ����ͷ�����RST����
601 
602  if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt+pcb->rcv_wnd)) {
603 
604  tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(),
605  tcphdr->dest, tcphdr->src);
606  return ERR_OK;
607  }
608  } else if (flags & TCP_FIN) { //���İ�FIN������Ϣ
609 
610  pcb->tmr = tcp_ticks; //��λ�ȴ�2MSLʱ�䣬���ƿ����µȴ�2MSL
611  }
612 
613  if ((tcplen > 0)) { //��������ݵı��Ļ����ڽ��մ������SYN����
614  pcb->flags |= TF_ACK_NOW;//����һ��ACK����
615  return tcp_output(pcb);
616  }
617  return ERR_OK;
618 }
619 
620 /**
621  * Implements the TCP state machine. Called by tcp_input. In some
622  * states tcp_receive() is called to receive data. The tcp_seg
623  * argument will be freed by the caller (tcp_input()) unless the
624  * recv_data pointer in the pcb is set.
625  *
626  * @param pcb the tcp_pcb for which a segment arrived
627  *
628  * @note the segment which arrived is saved in global variables, therefore only the pcb
629  * involved is passed as a parameter to this function
630  */
631 static err_t
632 tcp_process(struct tcp_pcb *pcb)
633 {
634  struct tcp_seg *rseg;
635  u8_t acceptable = 0;
636  err_t err;
637 
638  err = ERR_OK;
639 
640  /* Process incoming RST segments. */
641  if (flags & TCP_RST) {
642  /* First, determine if the reset is acceptable. */
643  if (pcb->state == SYN_SENT) {
644  if (ackno == pcb->snd_nxt) {
645  acceptable = 1;
646  }
647  } else {
648  if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt,
649  pcb->rcv_nxt+pcb->rcv_wnd)) {
650  acceptable = 1;
651  }
652  }
653 
654  if (acceptable) {
655  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: Connection RESET\n"));
656  LWIP_ASSERT("tcp_input: pcb->state != CLOSED", pcb->state != CLOSED);
657  recv_flags |= TF_RESET;
658  pcb->flags &= ~TF_ACK_DELAY;
659  return ERR_RST;
660  } else {
661  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n",
662  seqno, pcb->rcv_nxt));
663  LWIP_DEBUGF(TCP_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n",
664  seqno, pcb->rcv_nxt));
665  return ERR_OK;
666  }
667  }
668 
669  if ((flags & TCP_SYN) && (pcb->state != SYN_SENT && pcb->state != SYN_RCVD)) {
670  /* Cope with new connection attempt after remote end crashed */
671  tcp_ack_now(pcb);
672  return ERR_OK;
673  }
674 
675  if ((pcb->flags & TF_RXCLOSED) == 0) {
676  /* Update the PCB (in)activity timer unless rx is closed (see tcp_shutdown) */
677  pcb->tmr = tcp_ticks;
678  }
679  pcb->keep_cnt_sent = 0;
680 
681  tcp_parseopt(pcb);
682 
683  /* Do different things depending on the TCP state. */
684  switch (pcb->state) {
685  case SYN_SENT:
686  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %"U32_F" pcb->snd_nxt %"U32_F" unacked %"U32_F"\n", ackno,
687  pcb->snd_nxt, ntohl(pcb->unacked->tcphdr->seqno)));
688  /* received SYN ACK with expected sequence number? */
689  if ((flags & TCP_ACK) && (flags & TCP_SYN)
690  && ackno == ntohl(pcb->unacked->tcphdr->seqno) + 1) {
691  pcb->snd_buf++;
692  pcb->rcv_nxt = seqno + 1;
693  pcb->rcv_ann_right_edge = pcb->rcv_nxt;
694  pcb->lastack = ackno;
695  pcb->snd_wnd = tcphdr->wnd;
696  pcb->snd_wl1 = seqno - 1; /* initialise to seqno - 1 to force window update */
697  pcb->state = ESTABLISHED;
698 
699 #if TCP_CALCULATE_EFF_SEND_MSS
700  pcb->mss = tcp_eff_send_mss(pcb->mss, &(pcb->remote_ip));
701 #endif /* TCP_CALCULATE_EFF_SEND_MSS */
702 
703  /* Set ssthresh again after changing pcb->mss (already set in tcp_connect
704  * but for the default value of pcb->mss) */
705  pcb->ssthresh = pcb->mss * 10;
706 
707  pcb->cwnd = ((pcb->cwnd == 1) ? (pcb->mss * 2) : pcb->mss);
708  LWIP_ASSERT("pcb->snd_queuelen > 0", (pcb->snd_queuelen > 0));
709  --pcb->snd_queuelen;
710  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_process: SYN-SENT --queuelen %"U16_F"\n", (u16_t)pcb->snd_queuelen));
711  rseg = pcb->unacked;
712  pcb->unacked = rseg->next;
713 
714  /* If there's nothing left to acknowledge, stop the retransmit
715  timer, otherwise reset it to start again */
716  if(pcb->unacked == NULL)
717  pcb->rtime = -1;
718  else {
719  pcb->rtime = 0;
720  pcb->nrtx = 0;
721  }
722 
723  tcp_seg_free(rseg);
724 
725  /* Call the user specified function to call when sucessfully
726  * connected. */
727  TCP_EVENT_CONNECTED(pcb, ERR_OK, err);
728  if (err == ERR_ABRT) {
729  return ERR_ABRT;
730  }
731  tcp_ack_now(pcb);
732  }
733  /* received ACK? possibly a half-open connection */
734  else if (flags & TCP_ACK) {
735  /* send a RST to bring the other side in a non-synchronized state. */
736  tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(),
737  tcphdr->dest, tcphdr->src);
738  }
739  break;
740  case SYN_RCVD:
741  if (flags & TCP_ACK) {
742  /* expected ACK number? */
743  if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)) {
744  u16_t old_cwnd;
745  pcb->state = ESTABLISHED;
746  LWIP_DEBUGF(TCP_DEBUG, ("TCP connection established %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
747 #if LWIP_CALLBACK_API
748  LWIP_ASSERT("pcb->accept != NULL", pcb->accept != NULL);
749 #endif
750  /* Call the accept function. */
751  TCP_EVENT_ACCEPT(pcb, ERR_OK, err);
752  if (err != ERR_OK) {
753  /* If the accept function returns with an error, we abort
754  * the connection. */
755  /* Already aborted? */
756  if (err != ERR_ABRT) {
757  tcp_abort(pcb);
758  }
759  return ERR_ABRT;
760  }
761  old_cwnd = pcb->cwnd;
762  /* If there was any data contained within this ACK,
763  * we'd better pass it on to the application as well. */
764  tcp_receive(pcb);
765 
766  /* Prevent ACK for SYN to generate a sent event */
767  if (pcb->acked != 0) {
768  pcb->acked--;
769  }
770 
771  pcb->cwnd = ((old_cwnd == 1) ? (pcb->mss * 2) : pcb->mss);
772 
773  if (recv_flags & TF_GOT_FIN) {
774  tcp_ack_now(pcb);
775  pcb->state = CLOSE_WAIT;
776  }
777  } else {
778  /* incorrect ACK number, send RST */
779  tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(),
780  tcphdr->dest, tcphdr->src);
781  }
782  } else if ((flags & TCP_SYN) && (seqno == pcb->rcv_nxt - 1)) {
783  /* Looks like another copy of the SYN - retransmit our SYN-ACK */
784  tcp_rexmit(pcb);
785  }
786  break;
787  case CLOSE_WAIT:
788  /* FALLTHROUGH */
789  case ESTABLISHED:
790  tcp_receive(pcb);
791  if (recv_flags & TF_GOT_FIN) { /* passive close */
792  tcp_ack_now(pcb);
793  pcb->state = CLOSE_WAIT;
794  }
795  break;
796  case FIN_WAIT_1:
797  tcp_receive(pcb);
798  if (recv_flags & TF_GOT_FIN) {
799  if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) {
801  ("TCP connection closed: FIN_WAIT_1 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
802  tcp_ack_now(pcb);
803  tcp_pcb_purge(pcb);
804  TCP_RMV(&tcp_active_pcbs, pcb);
805  pcb->state = TIME_WAIT;
806  TCP_REG(&tcp_tw_pcbs, pcb);
807  } else {
808  tcp_ack_now(pcb);
809  pcb->state = CLOSING;
810  }
811  } else if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) {
812  pcb->state = FIN_WAIT_2;
813  }
814  break;
815  case FIN_WAIT_2:
816  tcp_receive(pcb);
817  if (recv_flags & TF_GOT_FIN) {
818  LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: FIN_WAIT_2 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
819  tcp_ack_now(pcb);
820  tcp_pcb_purge(pcb);
821  TCP_RMV(&tcp_active_pcbs, pcb);
822  pcb->state = TIME_WAIT;
823  TCP_REG(&tcp_tw_pcbs, pcb);
824  }
825  break;
826  case CLOSING:
827  tcp_receive(pcb);
828  if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
829  LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: CLOSING %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
830  tcp_pcb_purge(pcb);
831  TCP_RMV(&tcp_active_pcbs, pcb);
832  pcb->state = TIME_WAIT;
833  TCP_REG(&tcp_tw_pcbs, pcb);
834  }
835  break;
836  case LAST_ACK:
837  tcp_receive(pcb);
838  if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
839  LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: LAST_ACK %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
840  /* bugfix #21699: don't set pcb->state to CLOSED here or we risk leaking segments */
841  recv_flags |= TF_CLOSED;
842  }
843  break;
844  default:
845  break;
846  }
847  return ERR_OK;
848 }
849 
850 #if TCP_QUEUE_OOSEQ
851 /**
852  * Insert segment into the list (segments covered with new one will be deleted)
853  *
854  * Called from tcp_receive()
855  */
856 static void ICACHE_FLASH_ATTR
857 tcp_oos_insert_segment(struct tcp_seg *cseg, struct tcp_seg *next)
858 {
859  struct tcp_seg *old_seg;
860 
861  if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) {
862  /* received segment overlaps all following segments */
863  tcp_segs_free(next);
864  next = NULL;
865  }
866  else {
867  /* delete some following segments
868  oos queue may have segments with FIN flag */
869  while (next &&
870  TCP_SEQ_GEQ((seqno + cseg->len),
871  (next->tcphdr->seqno + next->len))) {
872  /* cseg with FIN already processed */
873  if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) {
874  TCPH_SET_FLAG(cseg->tcphdr, TCP_FIN);
875  }
876  old_seg = next;
877  next = next->next;
878  tcp_seg_free(old_seg);
879  }
880  if (next &&
881  TCP_SEQ_GT(seqno + cseg->len, next->tcphdr->seqno)) {
882  /* We need to trim the incoming segment. */
883  cseg->len = (u16_t)(next->tcphdr->seqno - seqno);
884  pbuf_realloc(cseg->p, cseg->len);
885  }
886  }
887  cseg->next = next;
888 }
889 #endif /* TCP_QUEUE_OOSEQ */
890 
891 /**
892  * Called by tcp_process. Checks if the given segment is an ACK for outstanding
893  * data, and if so frees the memory of the buffered data. Next, is places the
894  * segment on any of the receive queues (pcb->recved or pcb->ooseq). If the segment
895  * is buffered, the pbuf is referenced by pbuf_ref so that it will not be freed until
896  * i it has been removed from the buffer.
897  *
898  * If the incoming segment constitutes an ACK for a segment that was used for RTT
899  * estimation, the RTT is estimated here as well.
900  *
901  * Called from tcp_process().
902  */
903 static void
904 tcp_receive(struct tcp_pcb *pcb)
905 {
906  struct tcp_seg *next;
907 #if TCP_QUEUE_OOSEQ
908  struct tcp_seg *prev, *cseg;
909 #endif /* TCP_QUEUE_OOSEQ */
910  struct pbuf *p;
911  s32_t off;
912  s16_t m;
913  u32_t right_wnd_edge;
914  u16_t new_tot_len;
915  int found_dupack = 0;
916 
917  if (flags & TCP_ACK) {//���İ�ACK
918  right_wnd_edge = pcb->snd_wnd + pcb->snd_wl2;//���ʹ��� + ����Ӧ����󴰿ڸ���
919 
920  // first /* Update window. */
921  /*seqno > snd_wl1���������ֹ�̲��ô��ָ���;
922  *seqno = snd_wl1����ackno > snd_wl2;��ʱ���Է�û�з�����ݣ�ֻ���յ���ݵ�ȷ��;
923  *ackno = snd_wl2�ұ����ײ��б�snd_wnd���Ĵ���.����������Ӧֵ
924  */
925  if (TCP_SEQ_LT(pcb->snd_wl1, seqno) ||
926  (pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) ||
927  (pcb->snd_wl2 == ackno && tcphdr->wnd > pcb->snd_wnd)) {
928  pcb->snd_wnd = tcphdr->wnd;
929  pcb->snd_wl1 = seqno;
930  pcb->snd_wl2 = ackno;
931  if (pcb->snd_wnd > 0 && pcb->persist_backoff > 0) {
932  pcb->persist_backoff = 0;//�����ʱ���˳�
933  }
934  LWIP_DEBUGF(TCP_WND_DEBUG, ("tcp_receive: window update %"U16_F"\n", pcb->snd_wnd));
935 #if TCP_WND_DEBUG
936  } else {
937  if (pcb->snd_wnd != tcphdr->wnd) {
939  ("tcp_receive: no window update lastack %"U32_F" ackno %"
940  U32_F" wl1 %"U32_F" seqno %"U32_F" wl2 %"U32_F"\n",
941  pcb->lastack, ackno, pcb->snd_wl1, seqno, pcb->snd_wl2));
942  }
943 #endif /* TCP_WND_DEBUG */
944  }
945 
946  /* (From Stevens TCP/IP Illustrated Vol II, p970.) Its only a
947  * duplicate ack if:
948  * 1) It doesn't ACK new data û��ȷ�������
949  * 2) length of received packet is zero (i.e. no payload) ���Ķ����κ����
950  * 3) the advertised window hasn't changed ���ش���û�и���
951  * 4) There is outstanding unacknowledged data (retransmission timer running)������ݵȴ�ȷ��
952  * 5) The ACK is == biggest ACK sequence number so far seen (snd_una) ackno = lastack
953  *
954  * If it passes all five, should process as a dupack:
955  * a) dupacks < 3: do nothing
956  * b) dupacks == 3: fast retransmit
957  * c) dupacks > 3: increase cwnd
958  *
959  * If it only passes 1-3, should reset dupack counter (and add to
960  * stats, which we don't do in lwIP)
961  *
962  * If it only passes 1, should reset dupack counter
963  *
964  */
965 
966  /* Clause 1 */
967  if (TCP_SEQ_LEQ(ackno, pcb->lastack)) {//���ظ�ACK?
968  pcb->acked = 0;
969  /* Clause 2 */
970  if (tcplen == 0) {
971  /* Clause 3 */
972  if (pcb->snd_wl2 + pcb->snd_wnd == right_wnd_edge){
973  /* Clause 4 */
974  if (pcb->rtime >= 0) {
975  /* Clause 5 */
976  if (pcb->lastack == ackno) {
977  found_dupack = 1;
978  if (pcb->dupacks + 1 > pcb->dupacks)
979  ++pcb->dupacks;
980  if (pcb->dupacks > 3) {
981  /* Inflate the congestion window, but not if it means that
982  the value overflows. */
983  if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {
984  pcb->cwnd += pcb->mss;
985  }
986  } else if (pcb->dupacks == 3) {//���ظ�ACK
987  /* Do fast retransmit */
988  tcp_rexmit_fast(pcb);
989  }
990  }
991  }
992  }
993  }
994  /* If Clause (1) or more is true, but not a duplicate ack, reset
995  * count of consecutive duplicate acks */
996  if (!found_dupack) {
997  pcb->dupacks = 0;
998  }
999  } else if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)){//ackno��lastack+1��snd_nxt֮�䣬�жϷ��ʹ��������
1000  /* We come here when the ACK acknowledges new data. */
1001 
1002  if (pcb->flags & TF_INFR) {
1003  pcb->flags &= ~TF_INFR;// Reset the "IN Fast Retransmit" flag,since we are no longer in fast retransmit
1004  pcb->cwnd = pcb->ssthresh;//Reset the congestion window to the "slow start threshold".
1005  }
1006 
1007  /* Reset the number of retransmissions. */
1008  pcb->nrtx = 0;
1009 
1010  /* Reset the retransmission time-out. */
1011  pcb->rto = (pcb->sa >> 3) + pcb->sv;
1012 
1013  /* Update the send buffer space. Diff between the two can never exceed 64K? */
1014  pcb->acked = (u16_t)(ackno - pcb->lastack);
1015 
1016  pcb->snd_buf += pcb->acked;
1017 
1018  /* Reset the fast retransmit variables. */
1019  pcb->dupacks = 0;
1020  pcb->lastack = ackno;
1021 
1022  /* Update the congestion control variables (cwnd and
1023  ssthresh). */
1024  if (pcb->state >= ESTABLISHED) {//״̬Ϊ�������ӱ�־
1025  if (pcb->cwnd < pcb->ssthresh) {
1026  if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {
1027  pcb->cwnd += pcb->mss;
1028  }
1029  LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: slow start cwnd %"U16_F"\n", pcb->cwnd));
1030  } else {
1031  u16_t new_cwnd = (pcb->cwnd + pcb->mss * pcb->mss / pcb->cwnd);
1032  if (new_cwnd > pcb->cwnd) {
1033  pcb->cwnd = new_cwnd;
1034  }
1035  LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: congestion avoidance cwnd %"U16_F"\n", pcb->cwnd));
1036  }
1037  }
1038  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: ACK for %"U32_F", unacked->seqno %"U32_F":%"U32_F"\n",
1039  ackno,
1040  pcb->unacked != NULL?
1041  ntohl(pcb->unacked->tcphdr->seqno): 0,
1042  pcb->unacked != NULL?
1043  ntohl(pcb->unacked->tcphdr->seqno) + TCP_TCPLEN(pcb->unacked): 0));
1044 
1045  /* Remove segment from the unacknowledged list if the incoming
1046  ACK acknowlegdes them.
1047  *�ͷ�unacked�����ϱ�ȷ�ϵı��ĶΣ�
1048  *ֱ��unacked����Ϊ��ֹͣ*/
1049  while (pcb->unacked != NULL &&
1050  TCP_SEQ_LEQ(ntohl(pcb->unacked->tcphdr->seqno) +
1051  TCP_TCPLEN(pcb->unacked), ackno)) {
1052  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unacked\n",
1053  ntohl(pcb->unacked->tcphdr->seqno),
1054  ntohl(pcb->unacked->tcphdr->seqno) +
1055  TCP_TCPLEN(pcb->unacked)));
1056 
1057  next = pcb->unacked;//pcb unacked��־
1058  pcb->unacked = pcb->unacked->next;//pcb unacked ��һ����־
1059 
1060  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen));
1061  LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p)));
1062  /* Prevent ACK for FIN to generate a sent event */
1063  if ((pcb->acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) {
1064  pcb->acked--;
1065  }
1066 
1067  pcb->snd_queuelen -= pbuf_clen(next->p);//�������������pbufs����
1068  tcp_seg_free(next);//�ͷ�tcp��
1069 
1070  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U16_F" (after freeing unacked)\n", (u16_t)pcb->snd_queuelen));
1071  if (pcb->snd_queuelen != 0) {
1072  LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL ||
1073  pcb->unsent != NULL);
1074  }
1075  }
1076 
1077  /* If there's nothing left to acknowledge, stop the retransmit
1078  timer, otherwise reset it to start again */
1079  if(pcb->unacked == NULL) //����ݵȴ�ȷ��
1080  pcb->rtime = -1; //ֹͣ�ش���ʱ��
1081  else
1082  pcb->rtime = 0; //��λ�ش���ʱ��
1083 
1084  pcb->polltmr = 0;
1085  } else {
1086  /* Fix bug bug #21582: out of sequence ACK, didn't really ack anything */
1087  pcb->acked = 0;
1088  }
1089 
1090  /* We go through the ->unsent list to see if any of the segments
1091  on the list are acknowledged by the ACK. This may seem
1092  strange since an "unsent" segment shouldn't be acked. The
1093  rationale is that lwIP puts all outstanding segments on the
1094  ->unsent list after a retransmission, so these segments may
1095  in fact have been sent once. */
1096  /** unsent�������Ƿ��ܱ�acknoȷ�ϵı��ĶΣ������ͷ�**/
1097  while (pcb->unsent != NULL &&
1098  TCP_SEQ_BETWEEN(ackno, ntohl(pcb->unsent->tcphdr->seqno) +
1099  TCP_TCPLEN(pcb->unsent), pcb->snd_nxt)) {
1100  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unsent\n",
1101  ntohl(pcb->unsent->tcphdr->seqno), ntohl(pcb->unsent->tcphdr->seqno) +
1102  TCP_TCPLEN(pcb->unsent)));
1103 
1104  next = pcb->unsent;//pcbδ���ͱ�־
1105  pcb->unsent = pcb->unsent->next;//δ���͵���һ��
1106  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen));
1107  LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p)));
1108  /* Prevent ACK for FIN to generate a sent event */
1109  if ((pcb->acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) {
1110  pcb->acked--;
1111  }
1112  pcb->snd_queuelen -= pbuf_clen(next->p);//������pbuf�ĸ���
1113  tcp_seg_free(next);//�ͷŶ�
1114  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U16_F" (after freeing unsent)\n", (u16_t)pcb->snd_queuelen));
1115  if (pcb->snd_queuelen != 0) {//�������г���
1116  LWIP_ASSERT("tcp_receive: valid queue length",
1117  pcb->unacked != NULL || pcb->unsent != NULL);
1118  }
1119  }
1120  /* End of ACK for new data processing. */
1121 
1122  LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: pcb->rttest %"U32_F" rtseq %"U32_F" ackno %"U32_F"\n",
1123  pcb->rttest, pcb->rtseq, ackno));
1124 
1125  /* RTT estimation calculations. This is done by checking if the
1126  incoming segment acknowledges the segment we use to take a
1127  round-trip time measurement. */
1128  if (pcb->rttest && TCP_SEQ_LT(pcb->rtseq, ackno)) {//RTT���ڽ����Ҹñ��Ķα�ȷ��
1129  /* diff between this shouldn't exceed 32K since this are tcp timer ticks
1130  and a round-trip shouldn't be that long... */
1131  m = (s16_t)(tcp_ticks - pcb->rttest);//����Mֵ
1132 
1133  LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: experienced rtt %"U16_F" ticks (%"U16_F" msec).\n",
1134  m, m * TCP_SLOW_INTERVAL));
1135 
1136  /* This is taken directly from VJs original code in his paper �����RTT���㹫ʽ*/
1137  m = m - (pcb->sa >> 3);
1138  pcb->sa += m;
1139  if (m < 0) {
1140  m = -m;
1141  }
1142  m = m - (pcb->sv >> 2);
1143  pcb->sv += m;
1144  pcb->rto = (pcb->sa >> 3) + pcb->sv;
1145 
1146  LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: RTO %"U16_F" (%"U16_F" milliseconds)\n",
1147  pcb->rto, pcb->rto * TCP_SLOW_INTERVAL));
1148 
1149  pcb->rttest = 0;
1150  }
1151  }
1152 
1153  /* If the incoming segment contains data, we must process it
1154  further. */
1155  if (tcplen > 0) {
1156  /* This code basically does three things:
1157 
1158  +) If the incoming segment contains data that is the next
1159  in-sequence data, this data is passed to the application. This
1160  might involve trimming the first edge of the data. The rcv_nxt
1161  variable and the advertised window are adjusted.
1162 
1163  +) If the incoming segment has data that is above the next
1164  sequence number expected (->rcv_nxt), the segment is placed on
1165  the ->ooseq queue. This is done by finding the appropriate
1166  place in the ->ooseq queue (which is ordered by sequence
1167  number) and trim the segment in both ends if needed. An
1168  immediate ACK is sent to indicate that we received an
1169  out-of-sequence segment.
1170 
1171  +) Finally, we check if the first segment on the ->ooseq queue
1172  now is in sequence (i.e., if rcv_nxt >= ooseq->seqno). If
1173  rcv_nxt > ooseq->seqno, we must trim the first edge of the
1174  segment on ->ooseq before we adjust rcv_nxt. The data in the
1175  segments that are now on sequence are chained onto the
1176  incoming segment so that we only need to call the application
1177  once.
1178  */
1179 
1180  /* First, we check if we must trim the first edge. We have to do
1181  this if the sequence number of the incoming segment is less
1182  than rcv_nxt, and the sequence number plus the length of the
1183  segment is larger than rcv_nxt. */
1184  /* if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)){
1185  if (TCP_SEQ_LT(pcb->rcv_nxt, seqno + tcplen)) {*/
1186  if (TCP_SEQ_BETWEEN(pcb->rcv_nxt, seqno + 1, seqno + tcplen - 1)){// seqno < rcv_nxt < seqno + tcplen
1187  /* Trimming the first edge is done by pushing the payload
1188  pointer in the pbuf downwards. This is somewhat tricky since
1189  we do not want to discard the full contents of the pbuf up to
1190  the new starting point of the data since we have to keep the
1191  TCP header which is present in the first pbuf in the chain.
1192 
1193  What is done is really quite a nasty hack: the first pbuf in
1194  the pbuf chain is pointed to by inseg.p. Since we need to be
1195  able to deallocate the whole pbuf, we cannot change this
1196  inseg.p pointer to point to any of the later pbufs in the
1197  chain. Instead, we point the ->payload pointer in the first
1198  pbuf to data in one of the later pbufs. We also set the
1199  inseg.data pointer to point to the right place. This way, the
1200  ->p pointer will still point to the first pbuf, but the
1201  ->p->payload pointer will point to data in another pbuf.
1202 
1203  After we are done with adjusting the pbuf pointers we must
1204  adjust the ->data pointer in the seg and the segment
1205  length.*/
1206  //ȥ�����Ķ�����ݱ�ŵ���rcv_nxt�����
1207  off = pcb->rcv_nxt - seqno;
1208  p = inseg.p;
1209  LWIP_ASSERT("inseg.p != NULL", inseg.p);
1210  LWIP_ASSERT("insane offset!", (off < 0x7fff));
1211  if (inseg.p->len < off) {
1212  LWIP_ASSERT("pbuf too short!", (((s32_t)inseg.p->tot_len) >= off));
1213  new_tot_len = (u16_t)(inseg.p->tot_len - off);
1214  while (p->len < off) {
1215  off -= p->len;
1216  /* KJM following line changed (with addition of new_tot_len var)
1217  to fix bug #9076
1218  inseg.p->tot_len -= p->len; */
1219  p->tot_len = new_tot_len;
1220  p->len = 0;
1221  p = p->next;
1222  }
1223  if(pbuf_header(p, (s16_t)-off)) {
1224  /* Do we need to cope with this failing? Assert for now */
1225  LWIP_ASSERT("pbuf_header failed", 0);
1226  }
1227  } else {
1228  if(pbuf_header(inseg.p, (s16_t)-off)) {
1229  /* Do we need to cope with this failing? Assert for now */
1230  LWIP_ASSERT("pbuf_header failed", 0);
1231  }
1232  }
1233  inseg.len -= (u16_t)(pcb->rcv_nxt - seqno);
1234  inseg.tcphdr->seqno = seqno = pcb->rcv_nxt;
1235  }
1236  else {
1237  if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)){//seqno < rcv_nxt
1238  /* the whole segment is < rcv_nxt */
1239  /* must be a duplicate of a packet that has already been correctly handled */
1240  //���Ķ���������ݱ�ž�С��rcv_nxt����˱������ظ����ģ�
1241  //ֱ����Դ����ӦACK���Ĵ���
1242 
1243  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: duplicate seqno %"U32_F"\n", seqno));
1244  tcp_ack_now(pcb);
1245  }
1246  }
1247 
1248  /* The sequence number must be within the window (above rcv_nxt
1249  and below rcv_nxt + rcv_wnd) in order to be further
1250  processed. */
1251  if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt,
1252  pcb->rcv_nxt + pcb->rcv_wnd - 1)){//rcv_nxt < seqno < rcv_nxt + rcv_wnd - 1,������ڽ��շ�Χ��
1253  if (pcb->rcv_nxt == seqno) {
1254  /* The incoming segment is the next in sequence. We check if
1255  we have to trim the end of the segment and update rcv_nxt
1256  and pass the data to the application. */
1257  tcplen = TCP_TCPLEN(&inseg);//���㱨�Ķγ���
1258 
1259  if (tcplen > pcb->rcv_wnd) {//������մ��ڴ�С��������β���ض�
1261  ("tcp_receive: other end overran receive window"
1262  "seqno %"U32_F" len %"U16_F" right edge %"U32_F"\n",
1263  seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd));
1264  if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
1265  /* Must remove the FIN from the header as we're trimming
1266  * that byte of sequence-space from the packet */
1267  TCPH_FLAGS_SET(inseg.tcphdr, TCPH_FLAGS(inseg.tcphdr) &~ TCP_FIN);
1268  }
1269  /* Adjust length of segment to fit in the window. */
1270  inseg.len = pcb->rcv_wnd;
1271  if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) {
1272  inseg.len -= 1;
1273  }
1274  pbuf_realloc(inseg.p, inseg.len);
1275  tcplen = TCP_TCPLEN(&inseg);
1276  LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n",
1277  (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd));
1278  }
1279 #if TCP_QUEUE_OOSEQ
1280  /* Received in-sequence data, adjust ooseq data if:
1281  - FIN has been received or
1282  - inseq overlaps with ooseq */
1283  if (pcb->ooseq != NULL) {
1284  if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
1286  ("tcp_receive: received in-order FIN, binning ooseq queue\n"));
1287  /* Received in-order FIN means anything that was received
1288  * out of order must now have been received in-order, so
1289  * bin the ooseq queue */
1290  while (pcb->ooseq != NULL) {
1291  struct tcp_seg *old_ooseq = pcb->ooseq;
1292  pcb->ooseq = pcb->ooseq->next;
1293  tcp_seg_free(old_ooseq);
1294  }
1295  }
1296  else {
1297  next = pcb->ooseq;
1298  /* Remove all segments on ooseq that are covered by inseg already.
1299  * FIN is copied from ooseq to inseg if present. */
1300  while (next &&
1301  TCP_SEQ_GEQ(seqno + tcplen,
1302  next->tcphdr->seqno + next->len)) {
1303  /* inseg cannot have FIN here (already processed above) */
1304  if (TCPH_FLAGS(next->tcphdr) & TCP_FIN &&
1305  (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) == 0) {
1306  TCPH_SET_FLAG(inseg.tcphdr, TCP_FIN);
1307  tcplen = TCP_TCPLEN(&inseg);
1308  }
1309  prev = next;
1310  next = next->next;
1311  tcp_seg_free(prev);
1312  }
1313  /* Now trim right side of inseg if it overlaps with the first
1314  * segment on ooseq */
1315  if (next &&
1316  TCP_SEQ_GT(seqno + tcplen,
1317  next->tcphdr->seqno)) {
1318  /* inseg cannot have FIN here (already processed above) */
1319  inseg.len = (u16_t)(next->tcphdr->seqno - seqno);
1320  if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) {
1321  inseg.len -= 1;
1322  }
1323  pbuf_realloc(inseg.p, inseg.len);
1324  tcplen = TCP_TCPLEN(&inseg);
1325  LWIP_ASSERT("tcp_receive: segment not trimmed correctly to ooseq queue\n",
1326  (seqno + tcplen) == next->tcphdr->seqno);
1327  }
1328  pcb->ooseq = next;
1329  }
1330  }
1331 #endif /* TCP_QUEUE_OOSEQ */
1332 
1333  pcb->rcv_nxt = seqno + tcplen;
1334 
1335  /* Update the receiver's (our) window. */
1336  LWIP_ASSERT("tcp_receive: tcplen > rcv_wnd\n", pcb->rcv_wnd >= tcplen);
1337  pcb->rcv_wnd -= tcplen;
1338 
1339  tcp_update_rcv_ann_wnd(pcb);
1340 
1341  /* If there is data in the segment, we make preparations to
1342  pass this up to the application. The ->recv_data variable
1343  is used for holding the pbuf that goes to the
1344  application. The code for reassembling out-of-sequence data
1345  chains its data on this pbuf as well.
1346 
1347  If the segment was a FIN, we set the TF_GOT_FIN flag that will
1348  be used to indicate to the application that the remote side has
1349  closed its end of the connection. */
1350  if (inseg.p->tot_len > 0) {
1351  recv_data = inseg.p;
1352  /* Since this pbuf now is the responsibility of the
1353  application, we delete our reference to it so that we won't
1354  (mistakingly) deallocate it. */
1355  inseg.p = NULL;
1356  }
1357  if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
1358  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN.\n"));
1359  recv_flags |= TF_GOT_FIN;
1360  }
1361 
1362 #if TCP_QUEUE_OOSEQ
1363  /* We now check if we have segments on the ->ooseq queue that
1364  are now in sequence. */
1365  while (pcb->ooseq != NULL &&
1366  pcb->ooseq->tcphdr->seqno == pcb->rcv_nxt) {
1367 
1368  cseg = pcb->ooseq;
1369  seqno = pcb->ooseq->tcphdr->seqno;
1370 
1371  pcb->rcv_nxt += TCP_TCPLEN(cseg);
1372  LWIP_ASSERT("tcp_receive: ooseq tcplen > rcv_wnd\n",
1373  pcb->rcv_wnd >= TCP_TCPLEN(cseg));
1374  pcb->rcv_wnd -= TCP_TCPLEN(cseg);
1375 
1376  tcp_update_rcv_ann_wnd(pcb);
1377 
1378  if (cseg->p->tot_len > 0) {
1379  /* Chain this pbuf onto the pbuf that we will pass to
1380  the application. */
1381  if (recv_data) {
1382  pbuf_cat(recv_data, cseg->p);
1383  } else {
1384  recv_data = cseg->p;
1385  }
1386  cseg->p = NULL;
1387  }
1388  if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) {
1389  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN.\n"));
1390  recv_flags |= TF_GOT_FIN;
1391  if (pcb->state == ESTABLISHED) { /* force passive close or we can move to active close */
1392  pcb->state = CLOSE_WAIT;
1393  }
1394  }
1395 
1396  pcb->ooseq = cseg->next;
1397  tcp_seg_free(cseg);
1398  }
1399 #endif /* TCP_QUEUE_OOSEQ */
1400 
1401 
1402  /* Acknowledge the segment(s). */
1403  tcp_ack(pcb);
1404 
1405  } else {
1406  /* We get here if the incoming segment is out-of-sequence. */
1407  tcp_send_empty_ack(pcb);
1408 #if TCP_QUEUE_OOSEQ
1409  /* We queue the segment on the ->ooseq queue. */
1410  if (pcb->ooseq == NULL) {
1411  pcb->ooseq = tcp_seg_copy(&inseg);
1412  } else {
1413  /* If the queue is not empty, we walk through the queue and
1414  try to find a place where the sequence number of the
1415  incoming segment is between the sequence numbers of the
1416  previous and the next segment on the ->ooseq queue. That is
1417  the place where we put the incoming segment. If needed, we
1418  trim the second edges of the previous and the incoming
1419  segment so that it will fit into the sequence.
1420 
1421  If the incoming segment has the same sequence number as a
1422  segment on the ->ooseq queue, we discard the segment that
1423  contains less data. */
1424 
1425  prev = NULL;
1426  for(next = pcb->ooseq; next != NULL; next = next->next) {//��ooseqȡ�µ�M�����ĶΣ��ñ��Ķηǿգ�M++
1427  if (seqno == next->tcphdr->seqno) {//�ñ��Ķ���ʼ���== Ҫ����ı��Ķα��
1428  /* The sequence number of the incoming segment is the
1429  same as the sequence number of the segment on
1430  ->ooseq. We check the lengths to see which one to
1431  discard. */
1432  if (inseg.len > next->len) {//Ҫ����ı��Ķα�Ÿ�
1433  /* The incoming segment is larger than the old
1434  segment. We replace some segments with the new
1435  one. */
1436  cseg = tcp_seg_copy(&inseg);//Ҫ����ı��Ķδ����M�����Ķ�
1437  if (cseg != NULL) {
1438  if (prev != NULL) {
1439  prev->next = cseg;
1440  } else {
1441  pcb->ooseq = cseg;
1442  }
1443  tcp_oos_insert_segment(cseg, next);
1444  }
1445  break;
1446  } else {
1447  /* Either the lenghts are the same or the incoming
1448  segment was smaller than the old one; in either
1449  case, we ditch the incoming segment. */
1450  break;
1451  }
1452  } else {
1453  if (prev == NULL) {
1454  if (TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {
1455  /* The sequence number of the incoming segment is lower
1456  than the sequence number of the first segment on the
1457  queue. We put the incoming segment first on the
1458  queue. */
1459  cseg = tcp_seg_copy(&inseg);
1460  if (cseg != NULL) {
1461  pcb->ooseq = cseg;
1462  tcp_oos_insert_segment(cseg, next);
1463  }
1464  break;
1465  }
1466  } else {
1467  /*if (TCP_SEQ_LT(prev->tcphdr->seqno, seqno) &&
1468  TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {*/
1469  if (TCP_SEQ_BETWEEN(seqno, prev->tcphdr->seqno+1, next->tcphdr->seqno-1)) {
1470  /* The sequence number of the incoming segment is in
1471  between the sequence numbers of the previous and
1472  the next segment on ->ooseq. We trim trim the previous
1473  segment, delete next segments that included in received segment
1474  and trim received, if needed. */
1475  cseg = tcp_seg_copy(&inseg);
1476  if (cseg != NULL) {
1477  if (TCP_SEQ_GT(prev->tcphdr->seqno + prev->len, seqno)) {
1478  /* We need to trim the prev segment. */
1479  prev->len = (u16_t)(seqno - prev->tcphdr->seqno);
1480  pbuf_realloc(prev->p, prev->len);
1481  }
1482  prev->next = cseg;
1483  tcp_oos_insert_segment(cseg, next);
1484  }
1485  break;
1486  }
1487  }
1488  /* If the "next" segment is the last segment on the
1489  ooseq queue, we add the incoming segment to the end
1490  of the list. */
1491  if (next->next == NULL &&
1492  TCP_SEQ_GT(seqno, next->tcphdr->seqno)) {
1493  if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) {
1494  /* segment "next" already contains all data */
1495  break;
1496  }
1497  next->next = tcp_seg_copy(&inseg);
1498  if (next->next != NULL) {
1499  if (TCP_SEQ_GT(next->tcphdr->seqno + next->len, seqno)) {
1500  /* We need to trim the last segment. */
1501  next->len = (u16_t)(seqno - next->tcphdr->seqno);
1502  pbuf_realloc(next->p, next->len);
1503  }
1504  /* check if the remote side overruns our receive window */
1505  if ((u32_t)tcplen + seqno > pcb->rcv_nxt + (u32_t)pcb->rcv_wnd) {
1507  ("tcp_receive: other end overran receive window"
1508  "seqno %"U32_F" len %"U16_F" right edge %"U32_F"\n",
1509  seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd));
1510  if (TCPH_FLAGS(next->next->tcphdr) & TCP_FIN) {
1511  /* Must remove the FIN from the header as we're trimming
1512  * that byte of sequence-space from the packet */
1513  TCPH_FLAGS_SET(next->next->tcphdr, TCPH_FLAGS(next->next->tcphdr) &~ TCP_FIN);
1514  }
1515  /* Adjust length of segment to fit in the window. */
1516  next->next->len = pcb->rcv_nxt + pcb->rcv_wnd - seqno;
1517  pbuf_realloc(next->next->p, next->next->len);
1518  tcplen = TCP_TCPLEN(next->next);
1519  LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n",
1520  (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd));
1521  }
1522  }
1523  break;
1524  }
1525  }
1526  prev = next;
1527  }
1528  }
1529 #endif /* TCP_QUEUE_OOSEQ */
1530 
1531  }
1532  } else {
1533  /* The incoming segment is not withing the window. */
1534  tcp_send_empty_ack(pcb);
1535  }
1536  } else {
1537  /* Segments with length 0 is taken care of here. Segments that
1538  fall out of the window are ACKed. */
1539  /*if (TCP_SEQ_GT(pcb->rcv_nxt, seqno) ||
1540  TCP_SEQ_GEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {*/
1541  if(!TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd-1)){
1542  tcp_ack_now(pcb);//��Դ�˷���һ������ȷ�ϱ���
1543  }
1544  }
1545 }
1546 
1547 /**
1548  * Parses the options contained in the incoming segment.
1549  *
1550  * Called from tcp_listen_input() and tcp_process().
1551  * Currently, only the MSS option is supported!
1552  *
1553  * @param pcb the tcp_pcb for which a segment arrived
1554  */
1555 static void
1556 tcp_parseopt(struct tcp_pcb *pcb)
1557 {
1558  u16_t c, max_c;
1559  u16_t mss;
1560  u8_t *opts, opt;
1561 #if LWIP_TCP_TIMESTAMPS
1562  u32_t tsval;
1563 #endif
1564 
1565  opts = (u8_t *)tcphdr + TCP_HLEN;
1566 
1567  /* Parse the TCP MSS option, if present. */
1568  if(TCPH_HDRLEN(tcphdr) > 0x5) {
1569  max_c = (TCPH_HDRLEN(tcphdr) - 5) << 2;
1570  for (c = 0; c < max_c; ) {
1571  opt = opts[c];
1572  switch (opt) {
1573  case 0x00:
1574  /* End of options. */
1575  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: EOL\n"));
1576  return;
1577  case 0x01:
1578  /* NOP option. */
1579  ++c;
1580  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: NOP\n"));
1581  break;
1582  case 0x02:
1583  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: MSS\n"));
1584  if (opts[c + 1] != 0x04 || c + 0x04 > max_c) {
1585  /* Bad length */
1586  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
1587  return;
1588  }
1589  /* An MSS option with the right option length. */
1590  mss = (opts[c + 2] << 8) | opts[c + 3];
1591  /* Limit the mss to the configured TCP_MSS and prevent division by zero */
1592  pcb->mss = ((mss > TCP_MSS) || (mss == 0)) ? TCP_MSS : mss;
1593  /* Advance to next option */
1594  c += 0x04;
1595  break;
1596 #if LWIP_TCP_TIMESTAMPS
1597  case 0x08:
1598  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: TS\n"));
1599  if (opts[c + 1] != 0x0A || c + 0x0A > max_c) {
1600  /* Bad length */
1601  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
1602  return;
1603  }
1604  /* TCP timestamp option with valid length */
1605  tsval = (opts[c+2]) | (opts[c+3] << 8) |
1606  (opts[c+4] << 16) | (opts[c+5] << 24);
1607  if (flags & TCP_SYN) {
1608  pcb->ts_recent = ntohl(tsval);
1609  pcb->flags |= TF_TIMESTAMP;
1610  } else if (TCP_SEQ_BETWEEN(pcb->ts_lastacksent, seqno, seqno+tcplen)) {
1611  pcb->ts_recent = ntohl(tsval);
1612  }
1613  /* Advance to next option */
1614  c += 0x0A;
1615  break;
1616 #endif
1617  default:
1618  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: other\n"));
1619  if (opts[c + 1] == 0) {
1620  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
1621  /* If the length field is zero, the options are malformed
1622  and we don't process them further. */
1623  return;
1624  }
1625  /* All other options have a length field, so that we easily
1626  can skip past them. */
1627  c += opts[c + 1];
1628  }
1629  }
1630  }
1631 }
1632 
1633 #endif /* LWIP_TCP */
#define TCP_INPUT_DEBUG
Definition: opt.h:1931
u16_t tot_len
Definition: pbuf.h:90
void memp_free(memp_t type, void *mem) ICACHE_FLASH_ATTR
Definition: memp.c:438
#define TCP_QLEN_DEBUG
Definition: opt.h:1981
struct pbuf * next
Definition: pbuf.h:78
#define snmp_inc_tcpinsegs()
Definition: snmp.h:315
u16_t len
Definition: pbuf.h:93
#define ip_current_src_addr()
Definition: ip.h:199
#define snmp_inc_tcpinerrs()
Definition: snmp.h:318
#define U16_F
Definition: cc.h:61
signed short s16_t
Definition: cc.h:55
ip_addr_t current_iphdr_dest
Definition: ip.c:110
#define ERR_CLSD
Definition: err.h:65
#define NULL
Definition: def.h:47
#define TCP_CWND_DEBUG
Definition: opt.h:1953
#define PBUF_FLAG_PUSH
Definition: pbuf.h:69
#define PERF_STOP(x)
Definition: perf.h:38
#define IP_PROTO_TCP
Definition: ip.h:56
const ip_addr_t ip_addr_any ICACHE_RODATA_ATTR
Definition: ip_addr.c:44
#define ICACHE_FLASH_ATTR
Definition: c_types.h:99
#define MEMP_NUM_TCP_PCB
Definition: opt.h:251
#define TCP_RTO_DEBUG
Definition: opt.h:1946
#define ip_current_dest_addr()
Definition: ip.h:201
#define IPH_HL(hdr)
Definition: ip.h:145
#define ERR_RST
Definition: err.h:64
void pbuf_cat(struct pbuf *head, struct pbuf *tail) ICACHE_FLASH_ATTR
Definition: pbuf.c:823
#define ERR_ABRT
Definition: err.h:63
#define PERF_START
Definition: perf.h:37
#define TCP_WND_DEBUG
Definition: opt.h:1960
#define TCP_STATS_INC(x)
Definition: stats.h:171
#define TCP_WND
Definition: opt.h:903
#define U32_F
Definition: cc.h:65
#define ntohl(x)
Definition: def.h:84
u8_t flags
Definition: pbuf.h:99
unsigned long u32_t
Definition: cc.h:56
#define LWIP_DEBUGF(debug, message)
Definition: debug.h:94
#define ip_addr_cmp(addr1, addr2)
Definition: ip_addr.h:198
#define ip_addr_copy(dest, src)
Definition: ip_addr.h:162
#define ERR_OK
Definition: err.h:52
Definition: pbuf.h:76
s8_t err_t
Definition: err.h:47
Definition: netif.h:139
ip_addr_t current_iphdr_src
Definition: ip.c:108
#define TCP_DEBUG
Definition: opt.h:1924
#define ip_addr_isany(addr1)
Definition: ip_addr.h:200
u8_t pbuf_free(struct pbuf *p) ICACHE_FLASH_ATTR
Definition: pbuf.c:685
u16_t inet_chksum_pseudo(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, u8_t proto, u16_t proto_len) ICACHE_FLASH_ATTR
Definition: inet_chksum.c:272
#define ip_addr_isbroadcast(ipaddr, netif)
Definition: ip_addr.h:202
Definition: ip.h:116
u8_t pbuf_header(struct pbuf *p, s16_t header_size) ICACHE_FLASH_ATTR
Definition: pbuf.c:573
#define SOF_INHERITED
Definition: ip.h:109
unsigned char u8_t
Definition: cc.h:52
#define LWIP_ASSERT(message, assertion)
Definition: debug.h:65
#define TCP_MSS
Definition: opt.h:936
void * payload
Definition: pbuf.h:81
#define TCP_RST_DEBUG
Definition: opt.h:1974
signed long s32_t
Definition: cc.h:57
void pbuf_realloc(struct pbuf *p, u16_t size) ICACHE_FLASH_ATTR
Definition: pbuf.c:492
#define ip_addr_ismulticast(addr1)
Definition: ip_addr.h:208
#define ERR_MEM
Definition: err.h:53
#define snmp_inc_tcppassiveopens()
Definition: snmp.h:312
#define ntohs(x)
Definition: def.h:82
unsigned short u16_t
Definition: cc.h:54
u8_t pbuf_clen(struct pbuf *p) ICACHE_FLASH_ATTR
Definition: pbuf.c:782
#define X16_F
Definition: cc.h:62