MeterLogger
tcp_out.c
Go to the documentation of this file.
1 /**
2  * @file
3  * Transmission Control Protocol, outgoing traffic
4  *
5  * The output functions of TCP.
6  *
7  */
8 
9 /*
10  * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
11  * All rights reserved.
12  *
13  * Redistribution and use in source and binary forms, with or without modification,
14  * are permitted provided that the following conditions are met:
15  *
16  * 1. Redistributions of source code must retain the above copyright notice,
17  * this list of conditions and the following disclaimer.
18  * 2. Redistributions in binary form must reproduce the above copyright notice,
19  * this list of conditions and the following disclaimer in the documentation
20  * and/or other materials provided with the distribution.
21  * 3. The name of the author may not be used to endorse or promote products
22  * derived from this software without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
25  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
26  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
27  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
29  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
32  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
33  * OF SUCH DAMAGE.
34  *
35  * This file is part of the lwIP TCP/IP stack.
36  *
37  * Author: Adam Dunkels <adam@sics.se>
38  *
39  */
40 
41 #include "lwip/opt.h"
42 
43 #if LWIP_TCP /* don't build if not configured for use in lwipopts.h */
44 
45 #include "lwip/tcp_impl.h"
46 #include "lwip/def.h"
47 #include "lwip/mem.h"
48 #include "lwip/memp.h"
49 #include "lwip/sys.h"
50 #include "lwip/ip_addr.h"
51 #include "lwip/netif.h"
52 #include "lwip/inet_chksum.h"
53 #include "lwip/stats.h"
54 #include "lwip/snmp.h"
55 #include "netif/etharp.h"
56 
57 #include <string.h>
58 
59 #ifdef MEMLEAK_DEBUG
60 static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__;
61 #endif
62 
63 /* Define some copy-macros for checksum-on-copy so that the code looks
64  nicer by preventing too many ifdef's. */
65 #if TCP_CHECKSUM_ON_COPY
66 #define TCP_DATA_COPY(dst, src, len, seg) do { \
67  tcp_seg_add_chksum(LWIP_CHKSUM_COPY(dst, src, len), \
68  len, &seg->chksum, &seg->chksum_swapped); \
69  seg->flags |= TF_SEG_DATA_CHECKSUMMED; } while(0)
70 #define TCP_DATA_COPY2(dst, src, len, chksum, chksum_swapped) \
71  tcp_seg_add_chksum(LWIP_CHKSUM_COPY(dst, src, len), len, chksum, chksum_swapped);
72 #else /* TCP_CHECKSUM_ON_COPY*/
73 #define TCP_DATA_COPY(dst, src, len, seg) MEMCPY(dst, src, len)
74 #define TCP_DATA_COPY2(dst, src, len, chksum, chksum_swapped) MEMCPY(dst, src, len)
75 #endif /* TCP_CHECKSUM_ON_COPY*/
76 
77 /** Define this to 1 for an extra check that the output checksum is valid
78  * (usefule when the checksum is generated by the application, not the stack) */
79 #ifndef TCP_CHECKSUM_ON_COPY_SANITY_CHECK
80 #define TCP_CHECKSUM_ON_COPY_SANITY_CHECK 0
81 #endif
82 
83 /* Forward declarations.*/
84 static void tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb);
85 
86 /** Allocate a pbuf and create a tcphdr at p->payload, used for output
87  * functions other than the default tcp_output -> tcp_output_segment
88  * (e.g. tcp_send_empty_ack, etc.)
89  *
90  * @param pcb tcp pcb for which to send a packet (used to initialize tcp_hdr)
91  * @param optlen length of header-options
92  * @param datalen length of tcp data to reserve in pbuf
93  * @param seqno_be seqno in network byte order (big-endian)
94  * @return pbuf with p->payload being the tcp_hdr
95  */
96 static struct pbuf *ICACHE_FLASH_ATTR
97 tcp_output_alloc_header(struct tcp_pcb *pcb, u16_t optlen, u16_t datalen,
98  u32_t seqno_be /* already in network byte order */)
99 {
100  struct tcp_hdr *tcphdr;
101  struct pbuf *p = pbuf_alloc(PBUF_IP, TCP_HLEN + optlen + datalen, PBUF_RAM);
102  if (p != NULL) {
103  LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr",
104  (p->len >= TCP_HLEN + optlen));
105  tcphdr = (struct tcp_hdr *)p->payload;
106  tcphdr->src = htons(pcb->local_port);
107  tcphdr->dest = htons(pcb->remote_port);
108  tcphdr->seqno = seqno_be;
109  tcphdr->ackno = htonl(pcb->rcv_nxt);
110  TCPH_HDRLEN_FLAGS_SET(tcphdr, (5 + optlen / 4), TCP_ACK);
111  tcphdr->wnd = htons(pcb->rcv_ann_wnd);
112  tcphdr->chksum = 0;
113  tcphdr->urgp = 0;
114 
115  /* If we're sending a packet, update the announced right window edge */
116  pcb->rcv_ann_right_edge = pcb->rcv_nxt + pcb->rcv_ann_wnd;
117  }
118  return p;
119 }
120 
121 /**
122  * Called by tcp_close() to send a segment including FIN flag but not data.
123  *
124  * @param pcb the tcp_pcb over which to send a segment
125  * @return ERR_OK if sent, another err_t otherwise
126  */
127 err_t
128 tcp_send_fin(struct tcp_pcb *pcb)
129 {
130  /* first, try to add the fin to the last unsent segment */
131  if (pcb->unsent != NULL) {
132  struct tcp_seg *last_unsent;
133  for (last_unsent = pcb->unsent; last_unsent->next != NULL;
134  last_unsent = last_unsent->next);
135 
136  if ((TCPH_FLAGS(last_unsent->tcphdr) & (TCP_SYN | TCP_FIN | TCP_RST)) == 0) {
137  /* no SYN/FIN/RST flag in the header, we can add the FIN flag */
138  TCPH_SET_FLAG(last_unsent->tcphdr, TCP_FIN);
139  return ERR_OK;
140  }
141  }
142  /* no data, no length, flags, copy=1, no optdata */
143  return tcp_enqueue_flags(pcb, TCP_FIN);
144 }
145 
146 /**
147  * Create a TCP segment with prefilled header.
148  *
149  * Called by tcp_write and tcp_enqueue_flags.
150  *
151  * @param pcb Protocol control block for the TCP connection.
152  * @param p pbuf that is used to hold the TCP header.
153  * @param flags TCP flags for header.
154  * @param seqno TCP sequence number of this packet
155  * @param optflags options to include in TCP header
156  * @return a new tcp_seg pointing to p, or NULL.
157  * The TCP header is filled in except ackno and wnd.
158  * p is freed on failure.
159  */
160 static struct tcp_seg *ICACHE_FLASH_ATTR
161 tcp_create_segment(struct tcp_pcb *pcb, struct pbuf *p, u8_t flags, u32_t seqno, u8_t optflags)
162 {
163  struct tcp_seg *seg;
164  u8_t optlen = LWIP_TCP_OPT_LENGTH(optflags);
165 
166  if ((seg = (struct tcp_seg *)memp_malloc(MEMP_TCP_SEG)) == NULL) {
167  LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_create_segment: no memory.\n"));
168  pbuf_free(p);
169  return NULL;
170  }
171  seg->flags = optflags;
172  seg->next = NULL;
173  seg->p = p;
174  seg->len = p->tot_len - optlen;
175 #if TCP_OVERSIZE_DBGCHECK
176  seg->oversize_left = 0;
177 #endif /* TCP_OVERSIZE_DBGCHECK */
178 #if TCP_CHECKSUM_ON_COPY
179  seg->chksum = 0;
180  seg->chksum_swapped = 0;
181  /* check optflags */
182  LWIP_ASSERT("invalid optflags passed: TF_SEG_DATA_CHECKSUMMED",
183  (optflags & TF_SEG_DATA_CHECKSUMMED) == 0);
184 #endif /* TCP_CHECKSUM_ON_COPY */
185 
186  /* build TCP header */
187  if (pbuf_header(p, TCP_HLEN)) {
188  LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_create_segment: no room for TCP header in pbuf.\n"));
189  TCP_STATS_INC(tcp.err);
190  tcp_seg_free(seg);
191  return NULL;
192  }
193  seg->tcphdr = (struct tcp_hdr *)seg->p->payload;
194  seg->tcphdr->src = htons(pcb->local_port);
195  seg->tcphdr->dest = htons(pcb->remote_port);
196  seg->tcphdr->seqno = htonl(seqno);
197  /* ackno is set in tcp_output */
198  TCPH_HDRLEN_FLAGS_SET(seg->tcphdr, (5 + optlen / 4), flags);
199  /* wnd and chksum are set in tcp_output */
200  seg->tcphdr->urgp = 0;
201  return seg;
202 }
203 
204 /**
205  * Allocate a PBUF_RAM pbuf, perhaps with extra space at the end.
206  *
207  * This function is like pbuf_alloc(layer, length, PBUF_RAM) except
208  * there may be extra bytes available at the end.
209  *
210  * @param layer flag to define header size.
211  * @param length size of the pbuf's payload.
212  * @param max_length maximum usable size of payload+oversize.
213  * @param oversize pointer to a u16_t that will receive the number of usable tail bytes.
214  * @param pcb The TCP connection that willo enqueue the pbuf.
215  * @param apiflags API flags given to tcp_write.
216  * @param first_seg true when this pbuf will be used in the first enqueued segment.
217  * @param
218  */
219 #if TCP_OVERSIZE
220 static struct pbuf *ICACHE_FLASH_ATTR
221 tcp_pbuf_prealloc(pbuf_layer layer, u16_t length, u16_t max_length,
222  u16_t *oversize, struct tcp_pcb *pcb, u8_t apiflags,
223  u8_t first_seg)
224 {
225  struct pbuf *p;
226  u16_t alloc = length;
227 
228 #if LWIP_NETIF_TX_SINGLE_PBUF
229  LWIP_UNUSED_ARG(max_length);
230  LWIP_UNUSED_ARG(pcb);
231  LWIP_UNUSED_ARG(apiflags);
232  LWIP_UNUSED_ARG(first_seg);
233  /* always create MSS-sized pbufs */
234  alloc = TCP_MSS;
235 #else /* LWIP_NETIF_TX_SINGLE_PBUF */
236  if (length < max_length) {
237  /* Should we allocate an oversized pbuf, or just the minimum
238  * length required? If tcp_write is going to be called again
239  * before this segment is transmitted, we want the oversized
240  * buffer. If the segment will be transmitted immediately, we can
241  * save memory by allocating only length. We use a simple
242  * heuristic based on the following information:
243  *
244  * Did the user set TCP_WRITE_FLAG_MORE?
245  *
246  * Will the Nagle algorithm defer transmission of this segment?
247  */
248  if ((apiflags & TCP_WRITE_FLAG_MORE) ||
249  (!(pcb->flags & TF_NODELAY) &&
250  (!first_seg ||
251  pcb->unsent != NULL ||
252  pcb->unacked != NULL))) {
253  alloc = LWIP_MIN(max_length, LWIP_MEM_ALIGN_SIZE(length + TCP_OVERSIZE));
254  }
255  }
256 #endif /* LWIP_NETIF_TX_SINGLE_PBUF */
257  p = pbuf_alloc(layer, alloc, PBUF_RAM);
258  if (p == NULL) {
259  return NULL;
260  }
261  LWIP_ASSERT("need unchained pbuf", p->next == NULL);
262  *oversize = p->len - length;
263  /* trim p->len to the currently used size */
264  p->len = p->tot_len = length;
265  return p;
266 }
267 #else /* TCP_OVERSIZE */
268 #define tcp_pbuf_prealloc(layer, length, mx, os, pcb, api, fst) pbuf_alloc((layer), (length), PBUF_RAM)
269 #endif /* TCP_OVERSIZE */
270 
271 #if TCP_CHECKSUM_ON_COPY
272 /** Add a checksum of newly added data to the segment */
273 static void ICACHE_FLASH_ATTR
274 tcp_seg_add_chksum(u16_t chksum, u16_t len, u16_t *seg_chksum,
275  u8_t *seg_chksum_swapped)
276 {
277  u32_t helper;
278  /* add chksum to old chksum and fold to u16_t */
279  helper = chksum + *seg_chksum;
280  chksum = FOLD_U32T(helper);
281  if ((len & 1) != 0) {
282  *seg_chksum_swapped = 1 - *seg_chksum_swapped;
283  chksum = SWAP_BYTES_IN_WORD(chksum);
284  }
285  *seg_chksum = chksum;
286 }
287 #endif /* TCP_CHECKSUM_ON_COPY */
288 
289 /** Checks if tcp_write is allowed or not (checks state, snd_buf and snd_queuelen).
290  *
291  * @param pcb the tcp pcb to check for
292  * @param len length of data to send (checked agains snd_buf)
293  * @return ERR_OK if tcp_write is allowed to proceed, another err_t otherwise
294  */
296 tcp_write_checks(struct tcp_pcb *pcb, u16_t len)
297 {
298  /* connection is in invalid state for data transmission? */
299  if ((pcb->state != ESTABLISHED) &&
300  (pcb->state != CLOSE_WAIT) &&
301  (pcb->state != SYN_SENT) &&
302  (pcb->state != SYN_RCVD)) {
303  LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_STATE | LWIP_DBG_LEVEL_SEVERE, ("tcp_write() called in invalid state\n"));
304  return ERR_CONN;
305  } else if (len == 0) {
306  return ERR_OK;
307  }
308 
309  /* fail on too much data */
310  if (len > pcb->snd_buf) {
311  LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_write: too much data (len=%"U16_F" > snd_buf=%"U16_F")\n",
312  len, pcb->snd_buf));
313  pcb->flags |= TF_NAGLEMEMERR;
314  return ERR_MEM;
315  }
316 
317  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_write: queuelen: %"U16_F"\n", (u16_t)pcb->snd_queuelen));
318 
319  /* If total number of pbufs on the unsent/unacked queues exceeds the
320  * configured maximum, return an error */
321  /* check for configured max queuelen and possible overflow */
322  if ((pcb->snd_queuelen >= TCP_SND_QUEUELEN) || (pcb->snd_queuelen > TCP_SNDQUEUELEN_OVERFLOW)) {
323  LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_write: too long queue %"U16_F" (max %"U16_F")\n",
324  pcb->snd_queuelen, TCP_SND_QUEUELEN));
325  TCP_STATS_INC(tcp.memerr);
326  pcb->flags |= TF_NAGLEMEMERR;
327  return ERR_MEM;
328  }
329  if (pcb->snd_queuelen != 0) {
330  LWIP_ASSERT("tcp_write: pbufs on queue => at least one queue non-empty",
331  pcb->unacked != NULL || pcb->unsent != NULL);
332  } else {
333  LWIP_ASSERT("tcp_write: no pbufs on queue => both queues empty",
334  pcb->unacked == NULL && pcb->unsent == NULL);
335  }
336  return ERR_OK;
337 }
338 
339 /**
340  * Write data for sending (but does not send it immediately).
341  *��������һ��������ݣ��ú�����һ�����Ķβ����ڿ��ƿ黺�������
342  * It waits in the expectation of more data being sent soon (as
343  * it can send them more efficiently by combining them together).
344  * To prompt the system to send data now, call tcp_output() after
345  * calling tcp_write().
346  *
347  * @param pcb Protocol control block for the TCP connection to enqueue data for.��Ӧ���ӿ��ƿ�
348  * @param arg Pointer to the data to be enqueued for sending.���������ʼ��ַ
349  * @param len Data length in bytes������ݳ���
350  * @param apiflags combination of following flags :����Ƿ���п������Լ����Ķ��ײ��Ƿ������PSH��־
351  * - TCP_WRITE_FLAG_COPY (0x01) data will be copied into memory belonging to the stack
352  * - TCP_WRITE_FLAG_MORE (0x02) for TCP connection, PSH flag will be set on last segment sent,
353  * @return ERR_OK if enqueued, another err_t on error
354  */
355 err_t
356 tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags)
357 {
358  struct pbuf *concat_p = NULL;
359  struct tcp_seg *last_unsent = NULL, *seg = NULL, *prev_seg = NULL, *queue = NULL;
360  u16_t pos = 0; /* position in 'arg' data */
361  u16_t queuelen;
362  u8_t optlen = 0;
363  u8_t optflags = 0;
364 #if TCP_OVERSIZE
365  u16_t oversize = 0;
366  u16_t oversize_used = 0;
367 #endif /* TCP_OVERSIZE */
368 #if TCP_CHECKSUM_ON_COPY
369  u16_t concat_chksum = 0;
370  u8_t concat_chksum_swapped = 0;
371  u16_t concat_chksummed = 0;
372 #endif /* TCP_CHECKSUM_ON_COPY */
373  err_t err;
374 
375 #if LWIP_NETIF_TX_SINGLE_PBUF
376  /* Always copy to try to create single pbufs for TX */
377  apiflags |= TCP_WRITE_FLAG_COPY;
378 #endif /* LWIP_NETIF_TX_SINGLE_PBUF */
379 
380  LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_write(pcb=%p, data=%p, len=%"U16_F", apiflags=%"U16_F")\n",
381  (void *)pcb, arg, len, (u16_t)apiflags));
382  LWIP_ERROR("tcp_write: arg == NULL (programmer violates API)",
383  arg != NULL, return ERR_ARG;);
384 
385  err = tcp_write_checks(pcb, len);
386  if (err != ERR_OK) {
387  return err;
388  }
389  queuelen = pcb->snd_queuelen;
390 
391 #if LWIP_TCP_TIMESTAMPS
392  if ((pcb->flags & TF_TIMESTAMP)) {
393  optflags = TF_SEG_OPTS_TS;
394  optlen = LWIP_TCP_OPT_LENGTH(TF_SEG_OPTS_TS);
395  }
396 #endif /* LWIP_TCP_TIMESTAMPS */
397 
398 
399  /*
400  * TCP segmentation is done in three phases with increasing complexity:
401  *
402  * 1. Copy data directly into an oversized pbuf.
403  * 2. Chain a new pbuf to the end of pcb->unsent.
404  * 3. Create new segments.
405  *
406  * We may run out of memory at any point. In that case we must
407  * return ERR_MEM and not change anything in pcb. Therefore, all
408  * changes are recorded in local variables and committed at the end
409  * of the function. Some pcb fields are maintained in local copies:
410  *
411  * queuelen = pcb->snd_queuelen
412  * oversize = pcb->unsent_oversize
413  *
414  * These variables are set consistently by the phases:
415  *
416  * seg points to the last segment tampered with.
417  *
418  * pos records progress as data is segmented.
419  */
420 
421  /* Find the tail of the unsent queue. */
422  if (pcb->unsent != NULL) {
423  u16_t space;
424  u16_t unsent_optlen;
425 
426  /* @todo: this could be sped up by keeping last_unsent in the pcb */
427  for (last_unsent = pcb->unsent; last_unsent->next != NULL;
428  last_unsent = last_unsent->next);
429 
430  /* Usable space at the end of the last unsent segment */
431  unsent_optlen = LWIP_TCP_OPT_LENGTH(last_unsent->flags);
432  space = pcb->mss - (last_unsent->len + unsent_optlen);
433 
434  /*
435  * Phase 1: Copy data directly into an oversized pbuf.
436  *
437  * The number of bytes copied is recorded in the oversize_used
438  * variable. The actual copying is done at the bottom of the
439  * function.
440  */
441 #if TCP_OVERSIZE
442 #if TCP_OVERSIZE_DBGCHECK
443  /* check that pcb->unsent_oversize matches last_unsent->unsent_oversize */
444  LWIP_ASSERT("unsent_oversize mismatch (pcb vs. last_unsent)",
445  pcb->unsent_oversize == last_unsent->oversize_left);
446 #endif /* TCP_OVERSIZE_DBGCHECK */
447  oversize = pcb->unsent_oversize;
448  if (oversize > 0) {
449  LWIP_ASSERT("inconsistent oversize vs. space", oversize_used <= space);
450  seg = last_unsent;
451  oversize_used = oversize < len ? oversize : len;
452  pos += oversize_used;
453  oversize -= oversize_used;
454  space -= oversize_used;
455  }
456  /* now we are either finished or oversize is zero */
457  LWIP_ASSERT("inconsistend oversize vs. len", (oversize == 0) || (pos == len));
458 #endif /* TCP_OVERSIZE */
459 
460  /*
461  * Phase 2: Chain a new pbuf to the end of pcb->unsent.
462  *
463  * We don't extend segments containing SYN/FIN flags or options
464  * (len==0). The new pbuf is kept in concat_p and pbuf_cat'ed at
465  * the end.
466  */
467  if ((pos < len) && (space > 0) && (last_unsent->len > 0)) {
468  u16_t seglen = space < len - pos ? space : len - pos;
469  seg = last_unsent;
470 
471  /* Create a pbuf with a copy or reference to seglen bytes. We
472  * can use PBUF_RAW here since the data appears in the middle of
473  * a segment. A header will never be prepended. */
474  if (apiflags & TCP_WRITE_FLAG_COPY) {
475  /* Data is copied */
476  if ((concat_p = tcp_pbuf_prealloc(PBUF_RAW, seglen, space, &oversize, pcb, apiflags, 1)) == NULL) {
478  ("tcp_write : could not allocate memory for pbuf copy size %"U16_F"\n",
479  seglen));
480  goto memerr;
481  }
482 #if TCP_OVERSIZE_DBGCHECK
483  last_unsent->oversize_left = oversize;
484 #endif /* TCP_OVERSIZE_DBGCHECK */
485  TCP_DATA_COPY2(concat_p->payload, (u8_t*)arg + pos, seglen, &concat_chksum, &concat_chksum_swapped);
486 #if TCP_CHECKSUM_ON_COPY
487  concat_chksummed += seglen;
488 #endif /* TCP_CHECKSUM_ON_COPY */
489  } else {
490  /* Data is not copied */
491  if ((concat_p = pbuf_alloc(PBUF_RAW, seglen, PBUF_ROM)) == NULL) {
493  ("tcp_write: could not allocate memory for zero-copy pbuf\n"));
494  goto memerr;
495  }
496 #if TCP_CHECKSUM_ON_COPY
497  /* calculate the checksum of nocopy-data */
498  tcp_seg_add_chksum(~inet_chksum((u8_t*)arg + pos, seglen), seglen,
499  &concat_chksum, &concat_chksum_swapped);
500  concat_chksummed += seglen;
501 #endif /* TCP_CHECKSUM_ON_COPY */
502  /* reference the non-volatile payload data */
503  concat_p->payload = (u8_t*)arg + pos;
504  }
505 
506  pos += seglen;
507  queuelen += pbuf_clen(concat_p);
508  }
509  } else {
510 #if TCP_OVERSIZE
511  LWIP_ASSERT("unsent_oversize mismatch (pcb->unsent is NULL)",
512  pcb->unsent_oversize == 0);
513 #endif /* TCP_OVERSIZE */
514  }
515 
516  /*
517  * Phase 3: Create new segments.
518  *
519  * The new segments are chained together in the local 'queue'
520  * variable, ready to be appended to pcb->unsent.
521  */
522  while (pos < len) {
523  struct pbuf *p;
524  u16_t left = len - pos;
525  u16_t max_len = pcb->mss - optlen;
526  u16_t seglen = left > max_len ? max_len : left;
527 #if TCP_CHECKSUM_ON_COPY
528  u16_t chksum = 0;
529  u8_t chksum_swapped = 0;
530 #endif /* TCP_CHECKSUM_ON_COPY */
531 
532  if (apiflags & TCP_WRITE_FLAG_COPY) {
533  /* If copy is set, memory should be allocated and data copied
534  * into pbuf */
535  if ((p = tcp_pbuf_prealloc(PBUF_TRANSPORT, seglen + optlen, pcb->mss, &oversize, pcb, apiflags, queue == NULL)) == NULL) {
536  LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_write : could not allocate memory for pbuf copy size %"U16_F"\n", seglen));
537  goto memerr;
538  }
539  LWIP_ASSERT("tcp_write: check that first pbuf can hold the complete seglen",
540  (p->len >= seglen));
541  TCP_DATA_COPY2((char *)p->payload + optlen, (u8_t*)arg + pos, seglen, &chksum, &chksum_swapped);
542  } else {
543  /* Copy is not set: First allocate a pbuf for holding the data.
544  * Since the referenced data is available at least until it is
545  * sent out on the link (as it has to be ACKed by the remote
546  * party) we can safely use PBUF_ROM instead of PBUF_REF here.
547  */
548  struct pbuf *p2;
549 #if TCP_OVERSIZE
550  LWIP_ASSERT("oversize == 0", oversize == 0);
551 #endif /* TCP_OVERSIZE */
552  if ((p2 = pbuf_alloc(PBUF_TRANSPORT, seglen, PBUF_ROM)) == NULL) {
553  LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_write: could not allocate memory for zero-copy pbuf\n"));
554  goto memerr;
555  }
556 #if TCP_CHECKSUM_ON_COPY
557  /* calculate the checksum of nocopy-data */
558  chksum = ~inet_chksum((u8_t*)arg + pos, seglen);
559 #endif /* TCP_CHECKSUM_ON_COPY */
560  /* reference the non-volatile payload data */
561  p2->payload = (u8_t*)arg + pos;
562 
563  /* Second, allocate a pbuf for the headers. */
564  if ((p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) {
565  /* If allocation fails, we have to deallocate the data pbuf as
566  * well. */
567  pbuf_free(p2);
568  LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_write: could not allocate memory for header pbuf\n"));
569  goto memerr;
570  }
571  /* Concatenate the headers and data pbufs together. */
572  pbuf_cat(p/*header*/, p2/*data*/);
573  }
574 
575  queuelen += pbuf_clen(p);
576 
577  /* Now that there are more segments queued, we check again if the
578  * length of the queue exceeds the configured maximum or
579  * overflows. */
580  if ((queuelen > TCP_SND_QUEUELEN) || (queuelen > TCP_SNDQUEUELEN_OVERFLOW)) {
581  LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_write: queue too long %"U16_F" (%"U16_F")\n", queuelen, TCP_SND_QUEUELEN));
582  pbuf_free(p);
583  goto memerr;
584  }
585 
586  if ((seg = tcp_create_segment(pcb, p, 0, pcb->snd_lbb + pos, optflags)) == NULL) {
587  goto memerr;
588  }
589 #if TCP_OVERSIZE_DBGCHECK
590  seg->oversize_left = oversize;
591 #endif /* TCP_OVERSIZE_DBGCHECK */
592 #if TCP_CHECKSUM_ON_COPY
593  seg->chksum = chksum;
594  seg->chksum_swapped = chksum_swapped;
595  seg->flags |= TF_SEG_DATA_CHECKSUMMED;
596 #endif /* TCP_CHECKSUM_ON_COPY */
597 
598  /* first segment of to-be-queued data? */
599  if (queue == NULL) {
600  queue = seg;
601  } else {
602  /* Attach the segment to the end of the queued segments */
603  LWIP_ASSERT("prev_seg != NULL", prev_seg != NULL);
604  prev_seg->next = seg;
605  }
606  /* remember last segment of to-be-queued data for next iteration */
607  prev_seg = seg;
608 
609  LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_TRACE, ("tcp_write: queueing %"U32_F":%"U32_F"\n",
610  ntohl(seg->tcphdr->seqno),
611  ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg)));
612 
613  pos += seglen;
614  }
615 
616  /*
617  * All three segmentation phases were successful. We can commit the
618  * transaction.
619  */
620 
621  /*
622  * Phase 1: If data has been added to the preallocated tail of
623  * last_unsent, we update the length fields of the pbuf chain.
624  */
625 #if TCP_OVERSIZE
626  if (oversize_used > 0) {
627  struct pbuf *p;
628  /* Bump tot_len of whole chain, len of tail */
629  for (p = last_unsent->p; p; p = p->next) {
630  p->tot_len += oversize_used;
631  if (p->next == NULL) {
632  TCP_DATA_COPY((char *)p->payload + p->len, arg, oversize_used, last_unsent);
633  p->len += oversize_used;
634  }
635  }
636  last_unsent->len += oversize_used;
637 #if TCP_OVERSIZE_DBGCHECK
638  last_unsent->oversize_left -= oversize_used;
639 #endif /* TCP_OVERSIZE_DBGCHECK */
640  }
641  pcb->unsent_oversize = oversize;
642 #endif /* TCP_OVERSIZE */
643 
644  /*
645  * Phase 2: concat_p can be concatenated onto last_unsent->p
646  */
647  if (concat_p != NULL) {
648  LWIP_ASSERT("tcp_write: cannot concatenate when pcb->unsent is empty",
649  (last_unsent != NULL));
650  pbuf_cat(last_unsent->p, concat_p);
651  last_unsent->len += concat_p->tot_len;
652 #if TCP_CHECKSUM_ON_COPY
653  if (concat_chksummed) {
654  tcp_seg_add_chksum(concat_chksum, concat_chksummed, &last_unsent->chksum,
655  &last_unsent->chksum_swapped);
656  last_unsent->flags |= TF_SEG_DATA_CHECKSUMMED;
657  }
658 #endif /* TCP_CHECKSUM_ON_COPY */
659  }
660 
661  /*
662  * Phase 3: Append queue to pcb->unsent. Queue may be NULL, but that
663  * is harmless
664  */
665  if (last_unsent == NULL) {
666  pcb->unsent = queue;
667  } else {
668  last_unsent->next = queue;
669  }
670 
671  /*
672  * Finally update the pcb state.
673  */
674  pcb->snd_lbb += len;
675  pcb->snd_buf -= len;
676  pcb->snd_queuelen = queuelen;
677 
678  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_write: %"S16_F" (after enqueued)\n",
679  pcb->snd_queuelen));
680  if (pcb->snd_queuelen != 0) {
681  LWIP_ASSERT("tcp_write: valid queue length",
682  pcb->unacked != NULL || pcb->unsent != NULL);
683  }
684 
685  /* Set the PSH flag in the last segment that we enqueued. */
686  if (seg != NULL && seg->tcphdr != NULL && ((apiflags & TCP_WRITE_FLAG_MORE)==0)) {
687  TCPH_SET_FLAG(seg->tcphdr, TCP_PSH);
688  }
689 
690  return ERR_OK;
691 memerr:
692  pcb->flags |= TF_NAGLEMEMERR;
693  TCP_STATS_INC(tcp.memerr);
694 
695  if (concat_p != NULL) {
696  pbuf_free(concat_p);
697  }
698  if (queue != NULL) {
699  tcp_segs_free(queue);
700  }
701  if (pcb->snd_queuelen != 0) {
702  LWIP_ASSERT("tcp_write: valid queue length", pcb->unacked != NULL ||
703  pcb->unsent != NULL);
704  }
705  LWIP_DEBUGF(TCP_QLEN_DEBUG | LWIP_DBG_STATE, ("tcp_write: %"S16_F" (with mem err)\n", pcb->snd_queuelen));
706  return ERR_MEM;
707 }
708 
709 /**
710  * Enqueue TCP options for transmission.
711  *
712  * Called by tcp_connect(), tcp_listen_input(), and tcp_send_ctrl().
713  *
714  * @param pcb Protocol control block for the TCP connection.
715  * @param flags TCP header flags to set in the outgoing segment.
716  * @param optdata pointer to TCP options, or NULL.
717  * @param optlen length of TCP options in bytes.
718  */
719 err_t
720 tcp_enqueue_flags(struct tcp_pcb *pcb, u8_t flags)
721 {
722  struct pbuf *p;
723  struct tcp_seg *seg;
724  u8_t optflags = 0;
725  u8_t optlen = 0;
726 
727  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue_flags: queuelen: %"U16_F"\n", (u16_t)pcb->snd_queuelen));
728 
729  LWIP_ASSERT("tcp_enqueue_flags: need either TCP_SYN or TCP_FIN in flags (programmer violates API)",
730  (flags & (TCP_SYN | TCP_FIN)) != 0);
731 
732  /* check for configured max queuelen and possible overflow */
733  if ((pcb->snd_queuelen >= TCP_SND_QUEUELEN) || (pcb->snd_queuelen > TCP_SNDQUEUELEN_OVERFLOW)) {
734  LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue_flags: too long queue %"U16_F" (max %"U16_F")\n",
735  pcb->snd_queuelen, TCP_SND_QUEUELEN));
736  TCP_STATS_INC(tcp.memerr);
737  pcb->flags |= TF_NAGLEMEMERR;
738  return ERR_MEM;
739  }
740 
741  if (flags & TCP_SYN) {
742  optflags = TF_SEG_OPTS_MSS;
743  }
744 #if LWIP_TCP_TIMESTAMPS
745  if ((pcb->flags & TF_TIMESTAMP)) {
746  optflags |= TF_SEG_OPTS_TS;
747  }
748 #endif /* LWIP_TCP_TIMESTAMPS */
749  optlen = LWIP_TCP_OPT_LENGTH(optflags);
750 
751  /* tcp_enqueue_flags is always called with either SYN or FIN in flags.
752  * We need one available snd_buf byte to do that.
753  * This means we can't send FIN while snd_buf==0. A better fix would be to
754  * not include SYN and FIN sequence numbers in the snd_buf count. */
755  if (pcb->snd_buf == 0) {
756  LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue_flags: no send buffer available\n"));
757  TCP_STATS_INC(tcp.memerr);
758  return ERR_MEM;
759  }
760 
761  /* Allocate pbuf with room for TCP header + options */
762  if ((p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) {
763  pcb->flags |= TF_NAGLEMEMERR;
764  TCP_STATS_INC(tcp.memerr);
765  return ERR_MEM;
766  }
767  LWIP_ASSERT("tcp_enqueue_flags: check that first pbuf can hold optlen",
768  (p->len >= optlen));
769 
770  /* Allocate memory for tcp_seg, and fill in fields. */
771  if ((seg = tcp_create_segment(pcb, p, flags, pcb->snd_lbb, optflags)) == NULL) {
772  pcb->flags |= TF_NAGLEMEMERR;
773  TCP_STATS_INC(tcp.memerr);
774  return ERR_MEM;
775  }
776  LWIP_ASSERT("seg->tcphdr not aligned", ((mem_ptr_t)seg->tcphdr % MEM_ALIGNMENT) == 0);
777  LWIP_ASSERT("tcp_enqueue_flags: invalid segment length", seg->len == 0);
778 
780  ("tcp_enqueue_flags: queueing %"U32_F":%"U32_F" (0x%"X16_F")\n",
781  ntohl(seg->tcphdr->seqno),
782  ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg),
783  (u16_t)flags));
784 
785  /* Now append seg to pcb->unsent queue */
786  if (pcb->unsent == NULL) {
787  pcb->unsent = seg;
788  } else {
789  struct tcp_seg *useg;
790  for (useg = pcb->unsent; useg->next != NULL; useg = useg->next);
791  useg->next = seg;
792  }
793 #if TCP_OVERSIZE
794  /* The new unsent tail has no space */
795  pcb->unsent_oversize = 0;
796 #endif /* TCP_OVERSIZE */
797 
798  /* SYN and FIN bump the sequence number */
799  if ((flags & TCP_SYN) || (flags & TCP_FIN)) {
800  pcb->snd_lbb++;
801  /* optlen does not influence snd_buf */
802  pcb->snd_buf--;
803  }
804  if (flags & TCP_FIN) {
805  pcb->flags |= TF_FIN;
806  }
807 
808  /* update number of segments on the queues */
809  pcb->snd_queuelen += pbuf_clen(seg->p);
810  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue_flags: %"S16_F" (after enqueued)\n", pcb->snd_queuelen));
811  if (pcb->snd_queuelen != 0) {
812  LWIP_ASSERT("tcp_enqueue_flags: invalid queue length",
813  pcb->unacked != NULL || pcb->unsent != NULL);
814  }
815 
816  return ERR_OK;
817 }
818 
819 
820 #if LWIP_TCP_TIMESTAMPS
821 /* Build a timestamp option (12 bytes long) at the specified options pointer)
822  *
823  * @param pcb tcp_pcb
824  * @param opts option pointer where to store the timestamp option
825  */
826 static void ICACHE_FLASH_ATTR
827 tcp_build_timestamp_option(struct tcp_pcb *pcb, u32_t *opts)
828 {
829  /* Pad with two NOP options to make everything nicely aligned */
830  opts[0] = PP_HTONL(0x0101080A);
831  opts[1] = htonl(sys_now());
832  opts[2] = htonl(pcb->ts_recent);
833 }
834 #endif
835 
836 /** Send an ACK without data.
837  *
838  * @param pcb Protocol control block for the TCP connection to send the ACK
839  */
840 err_t
841 tcp_send_empty_ack(struct tcp_pcb *pcb)
842 {
843  struct pbuf *p;
844  struct tcp_hdr *tcphdr;
845  u8_t optlen = 0;
846 
847 #if LWIP_TCP_TIMESTAMPS
848  if (pcb->flags & TF_TIMESTAMP) {
849  optlen = LWIP_TCP_OPT_LENGTH(TF_SEG_OPTS_TS);
850  }
851 #endif
852 
853  p = tcp_output_alloc_header(pcb, optlen, 0, htonl(pcb->snd_nxt));
854  if (p == NULL) {
855  LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: (ACK) could not allocate pbuf\n"));
856  return ERR_BUF;
857  }
858  tcphdr = (struct tcp_hdr *)p->payload;
860  ("tcp_output: sending ACK for %"U32_F"\n", pcb->rcv_nxt));
861  /* remove ACK flags from the PCB, as we send an empty ACK now */
862  pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
863 
864  /* NB. MSS option is only sent on SYNs, so ignore it here */
865 #if LWIP_TCP_TIMESTAMPS
866  pcb->ts_lastacksent = pcb->rcv_nxt;
867 
868  if (pcb->flags & TF_TIMESTAMP) {
869  tcp_build_timestamp_option(pcb, (u32_t *)(tcphdr + 1));
870  }
871 #endif
872 
873 #if CHECKSUM_GEN_TCP
874  tcphdr->chksum = inet_chksum_pseudo(p, &(pcb->local_ip), &(pcb->remote_ip),
875  IP_PROTO_TCP, p->tot_len);
876 #endif
877 #if LWIP_NETIF_HWADDRHINT
878  ip_output_hinted(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
879  IP_PROTO_TCP, &(pcb->addr_hint));
880 #else /* LWIP_NETIF_HWADDRHINT*/
881  ip_output(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
882  IP_PROTO_TCP);
883 #endif /* LWIP_NETIF_HWADDRHINT*/
884  pbuf_free(p);
885 
886  return ERR_OK;
887 }
888 
889 /**
890  * Find out what we can send and send it
891  *���Ϳ��ƿ黺����еı��Ķ�
892  * @param pcb Protocol control block for the TCP connection to send data
893  * @return ERR_OK if data has been sent or nothing to send
894  * another err_t on error
895  */
897 tcp_output(struct tcp_pcb *pcb)
898 {
899  struct tcp_seg *seg, *useg;
900  u32_t wnd, snd_nxt;
901 #if TCP_CWND_DEBUG
902  s16_t i = 0;
903 #endif /* TCP_CWND_DEBUG */
904  /* First, check if we are invoked by the TCP input processing
905  code. If so, we do not output anything. Instead, we rely on the
906  input processing code to call us when input processing is done
907  with. �����ƿ鵱ǰ������ݱ����?ֱ�ӷ���*/
908  if (tcp_input_pcb == pcb) {
909  return ERR_OK;
910  }
911 
912  wnd = LWIP_MIN(pcb->snd_wnd, pcb->cwnd);//�ӷ��ʹ��ں������ȡС�ߵõ���Ч���ʹ���
913 
914  seg = pcb->unsent;
915 
916  /* If the TF_ACK_NOW flag is set and no data will be sent (either
917  * because the ->unsent queue is empty or because the window does
918  * not allow it), construct an empty ACK segment and send it.
919  *
920  * If data is to be sent, we will just piggyback the ACK (see below).
921  */
922  if (pcb->flags & TF_ACK_NOW &&
923  (seg == NULL ||
924  ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len > wnd)) {
925  return tcp_send_empty_ack(pcb);//����ֻ��ACK�ı��Ķ�
926  }
927 
928  /* useg should point to last segment on unacked queue */
929  useg = pcb->unacked;
930  if (useg != NULL) {
931  for (; useg->next != NULL; useg = useg->next);//�õ�β��
932  }
933 
934 #if TCP_OUTPUT_DEBUG
935  if (seg == NULL) {
936  LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: nothing to send (%p)\n",
937  (void*)pcb->unsent));
938  }
939 #endif /* TCP_OUTPUT_DEBUG */
940 #if TCP_CWND_DEBUG
941  if (seg == NULL) {
942  LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"U16_F
943  ", cwnd %"U16_F", wnd %"U32_F
944  ", seg == NULL, ack %"U32_F"\n",
945  pcb->snd_wnd, pcb->cwnd, wnd, pcb->lastack));
946  } else {
948  ("tcp_output: snd_wnd %"U16_F", cwnd %"U16_F", wnd %"U32_F
949  ", effwnd %"U32_F", seq %"U32_F", ack %"U32_F"\n",
950  pcb->snd_wnd, pcb->cwnd, wnd,
951  ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len,
952  ntohl(seg->tcphdr->seqno), pcb->lastack));
953  }
954 #endif /* TCP_CWND_DEBUG */
955  /* data available and window allows it to be sent?
956  *��ǰ��Ч�������?�ķ��ͣ�ѭ�����ͱ��ģ�ֱ�������*/
957  while (seg != NULL &&
958  ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) {
959  LWIP_ASSERT("RST not expected here!",
960  (TCPH_FLAGS(seg->tcphdr) & TCP_RST) == 0);
961  /* Stop sending if the nagle algorithm would prevent it
962  * Don't stop:
963  * - if tcp_write had a memory error before (prevent delayed ACK timeout) or
964  * - if FIN was already enqueued for this PCB (SYN is always alone in a segment -
965  * either seg->next != NULL or pcb->unacked == NULL;
966  * RST is no sent using tcp_write/tcp_output.
967  */
968  if((tcp_do_output_nagle(pcb) == 0) &&
969  ((pcb->flags & (TF_NAGLEMEMERR | TF_FIN)) == 0)){
970  break;
971  }
972 #if TCP_CWND_DEBUG
973  LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"U16_F", cwnd %"U16_F", wnd %"U32_F", effwnd %"U32_F", seq %"U32_F", ack %"U32_F", i %"S16_F"\n",
974  pcb->snd_wnd, pcb->cwnd, wnd,
975  ntohl(seg->tcphdr->seqno) + seg->len -
976  pcb->lastack,
977  ntohl(seg->tcphdr->seqno), pcb->lastack, i));
978  ++i;
979 #endif /* TCP_CWND_DEBUG */
980 
981  pcb->unsent = seg->next;
982 
983  if (pcb->state != SYN_SENT) {
984  TCPH_SET_FLAG(seg->tcphdr, TCP_ACK);//��д�ײ�ACK��־
985  pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);//����־λ
986  }
987 
988  tcp_output_segment(seg, pcb);//���ú����ͱ��Ķ�
989 
990  snd_nxt = ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg);//����snd_nxt
991  if (TCP_SEQ_LT(pcb->snd_nxt, snd_nxt)) {
992  pcb->snd_nxt = snd_nxt;//����Ҫ���͵���ݱ��
993  }
994  /* put segment on unacknowledged list if length > 0
995  */
996  if (TCP_TCPLEN(seg) > 0) {
997  seg->next = NULL;
998  /* unacked list is empty? ֱ�ӹҽ�*/
999  if (pcb->unacked == NULL) {
1000  pcb->unacked = seg;
1001  useg = seg;
1002  /* unacked list is not empty?����ǰ���İ�˳����֯�ڶ����� */
1003  } else {
1004  /* In the case of fast retransmit, the packet should not go to the tail
1005  * of the unacked queue, but rather somewhere before it. We need to check for
1006  * this case. -STJ Jul 27, 2004 */ //���ǰ���ĵ����кŵ��ڶ���β���������кţ�
1007  //�Ӷ����ײ���ʼ
1008  if (TCP_SEQ_LT(ntohl(seg->tcphdr->seqno), ntohl(useg->tcphdr->seqno))) {
1009  /* add segment to before tail of unacked list, keeping the list sorted */
1010  struct tcp_seg **cur_seg = &(pcb->unacked);
1011  while (*cur_seg &&
1012  TCP_SEQ_LT(ntohl((*cur_seg)->tcphdr->seqno), ntohl(seg->tcphdr->seqno))) {
1013  cur_seg = &((*cur_seg)->next );
1014  }
1015  seg->next = (*cur_seg);
1016  (*cur_seg) = seg;
1017  } else {//���������ߣ������δȷ�϶���ĩβ
1018  /* add segment to tail of unacked list */
1019  useg->next = seg;
1020  useg = useg->next;
1021  }
1022  }
1023  /* do not queue empty segments on the unacked list */
1024  } else {//���Ķγ���Ϊ0��ֱ��ɾ�������ش�
1025  tcp_seg_free(seg);
1026  }
1027  seg = pcb->unsent;//������һ�����Ķ�
1028  }
1029 #if TCP_OVERSIZE
1030  if (pcb->unsent == NULL) {
1031  /* last unsent has been removed, reset unsent_oversize */
1032  pcb->unsent_oversize = 0;
1033  }
1034 #endif /* TCP_OVERSIZE */
1035 
1036 //���ʹ��������±��IJ��ܷ��ͣ��������㴰��̽�⡣
1037  if (seg != NULL && pcb->persist_backoff == 0 &&
1038  ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len > pcb->snd_wnd) {
1039  /* prepare for persist timer */
1040  pcb->persist_cnt = 0;
1041  pcb->persist_backoff = 1;
1042  }
1043 
1044  pcb->flags &= ~TF_NAGLEMEMERR;//���ڴ�����־
1045  return ERR_OK;
1046 }
1047 
1048 /**
1049  * Called by tcp_output() to actually send a TCP segment over IP.
1050  *
1051  * @param seg the tcp_seg to send
1052  * @param pcb the tcp_pcb for the TCP connection used to send the segment
1053  */
1054 
1055 static void
1056 tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb)
1057 {
1058  u16_t len;
1059  struct netif *netif;
1060  u32_t *opts;
1061  /** @bug Exclude retransmitted segments from this count. */
1063 
1064  /* The TCP header has already been constructed, but the ackno and
1065  wnd fields remain. */
1066  seg->tcphdr->ackno = htonl(pcb->rcv_nxt);
1067 
1068  /* advertise our receive window size in this TCP segment */
1069  seg->tcphdr->wnd = htons(pcb->rcv_ann_wnd);
1070 
1071  pcb->rcv_ann_right_edge = pcb->rcv_nxt + pcb->rcv_ann_wnd;
1072 
1073  /* Add any requested options. NB MSS option is only set on SYN
1074  packets, so ignore it here */
1075  LWIP_ASSERT("seg->tcphdr not aligned", ((mem_ptr_t)seg->tcphdr % MEM_ALIGNMENT) == 0);
1076  opts = (u32_t *)(void *)(seg->tcphdr + 1);
1077  if (seg->flags & TF_SEG_OPTS_MSS) {
1078  TCP_BUILD_MSS_OPTION(*opts);
1079  opts += 1;
1080  }
1081 #if LWIP_TCP_TIMESTAMPS
1082  pcb->ts_lastacksent = pcb->rcv_nxt;
1083 
1084  if (seg->flags & TF_SEG_OPTS_TS) {
1085  tcp_build_timestamp_option(pcb, opts);
1086  opts += 3;
1087  }
1088 #endif
1089 
1090  /* Set retransmission timer running if it is not currently enabled
1091  This must be set before checking the route. modify by ives at 2014.4.24*/
1092  if (pcb->rtime == -1) {
1093  pcb->rtime = 0;
1094  }
1095 
1096  /* If we don't have a local IP address, we get one by
1097  calling ip_route(). */
1098  if (ip_addr_isany(&(pcb->local_ip))) {
1099  netif = ip_route(&(pcb->remote_ip));
1100  if (netif == NULL) {
1101  return;
1102  }
1103  ip_addr_copy(pcb->local_ip, netif->ip_addr);
1104  }
1105 
1106  if (pcb->rttest == 0) {
1107  pcb->rttest = tcp_ticks;
1108  pcb->rtseq = ntohl(seg->tcphdr->seqno);
1109 
1110  LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_output_segment: rtseq %"U32_F"\n", pcb->rtseq));
1111  }
1112  LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output_segment: %"U32_F":%"U32_F"\n",
1113  htonl(seg->tcphdr->seqno), htonl(seg->tcphdr->seqno) +
1114  seg->len));
1115 
1116  len = (u16_t)((u8_t *)seg->tcphdr - (u8_t *)seg->p->payload);
1117 
1118  seg->p->len -= len;
1119  seg->p->tot_len -= len;
1120 
1121  seg->p->payload = seg->tcphdr;
1122 
1123  seg->tcphdr->chksum = 0;
1124 #if CHECKSUM_GEN_TCP
1125 #if TCP_CHECKSUM_ON_COPY
1126  {
1127  u32_t acc;
1128 #if TCP_CHECKSUM_ON_COPY_SANITY_CHECK
1129  u16_t chksum_slow = inet_chksum_pseudo(seg->p, &(pcb->local_ip),
1130  &(pcb->remote_ip),
1131  IP_PROTO_TCP, seg->p->tot_len);
1132 #endif /* TCP_CHECKSUM_ON_COPY_SANITY_CHECK */
1133  if ((seg->flags & TF_SEG_DATA_CHECKSUMMED) == 0) {
1134  LWIP_ASSERT("data included but not checksummed",
1135  seg->p->tot_len == (TCPH_HDRLEN(seg->tcphdr) * 4));
1136  }
1137 
1138  /* rebuild TCP header checksum (TCP header changes for retransmissions!) */
1139  acc = inet_chksum_pseudo_partial(seg->p, &(pcb->local_ip),
1140  &(pcb->remote_ip),
1141  IP_PROTO_TCP, seg->p->tot_len, TCPH_HDRLEN(seg->tcphdr) * 4);
1142  /* add payload checksum */
1143  if (seg->chksum_swapped) {
1144  seg->chksum = SWAP_BYTES_IN_WORD(seg->chksum);
1145  seg->chksum_swapped = 0;
1146  }
1147  acc += (u16_t)~(seg->chksum);
1148  seg->tcphdr->chksum = FOLD_U32T(acc);
1149 #if TCP_CHECKSUM_ON_COPY_SANITY_CHECK
1150  if (chksum_slow != seg->tcphdr->chksum) {
1152  ("tcp_output_segment: calculated checksum is %"X16_F" instead of %"X16_F"\n",
1153  seg->tcphdr->chksum, chksum_slow));
1154  seg->tcphdr->chksum = chksum_slow;
1155  }
1156 #endif /* TCP_CHECKSUM_ON_COPY_SANITY_CHECK */
1157  }
1158 #else /* TCP_CHECKSUM_ON_COPY */
1159  seg->tcphdr->chksum = inet_chksum_pseudo(seg->p, &(pcb->local_ip),
1160  &(pcb->remote_ip),
1161  IP_PROTO_TCP, seg->p->tot_len);
1162 #endif /* TCP_CHECKSUM_ON_COPY */
1163 #endif /* CHECKSUM_GEN_TCP */
1164  TCP_STATS_INC(tcp.xmit);
1165 
1166 #if LWIP_NETIF_HWADDRHINT
1167  ip_output_hinted(seg->p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
1168  IP_PROTO_TCP, &(pcb->addr_hint));
1169 #else /* LWIP_NETIF_HWADDRHINT*/
1170  ip_output(seg->p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
1171  IP_PROTO_TCP);
1172 #endif /* LWIP_NETIF_HWADDRHINT*/
1173 }
1174 
1175 /**
1176  * Send a TCP RESET packet (empty segment with RST flag set) either to
1177  * abort a connection or to show that there is no matching local connection
1178  * for a received segment.
1179  *
1180  * Called by tcp_abort() (to abort a local connection), tcp_input() (if no
1181  * matching local pcb was found), tcp_listen_input() (if incoming segment
1182  * has ACK flag set) and tcp_process() (received segment in the wrong state)
1183  *
1184  * Since a RST segment is in most cases not sent for an active connection,
1185  * tcp_rst() has a number of arguments that are taken from a tcp_pcb for
1186  * most other segment output functions.
1187  *
1188  * @param seqno the sequence number to use for the outgoing segment
1189  * @param ackno the acknowledge number to use for the outgoing segment
1190  * @param local_ip the local IP address to send the segment from
1191  * @param remote_ip the remote IP address to send the segment to
1192  * @param local_port the local TCP port to send the segment from
1193  * @param remote_port the remote TCP port to send the segment to
1194  */
1195 void
1196 tcp_rst(u32_t seqno, u32_t ackno,
1197  ip_addr_t *local_ip, ip_addr_t *remote_ip,
1198  u16_t local_port, u16_t remote_port)
1199 {
1200  struct pbuf *p;
1201  struct tcp_hdr *tcphdr;
1202  p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM);
1203  if (p == NULL) {
1204  LWIP_DEBUGF(TCP_DEBUG, ("tcp_rst: could not allocate memory for pbuf\n"));
1205  return;
1206  }
1207  LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr",
1208  (p->len >= sizeof(struct tcp_hdr)));
1209 
1210  tcphdr = (struct tcp_hdr *)p->payload;
1211  tcphdr->src = htons(local_port);
1212  tcphdr->dest = htons(remote_port);
1213  tcphdr->seqno = htonl(seqno);
1214  tcphdr->ackno = htonl(ackno);
1215  TCPH_HDRLEN_FLAGS_SET(tcphdr, TCP_HLEN/4, TCP_RST | TCP_ACK);
1216  tcphdr->wnd = PP_HTONS(TCP_WND);
1217  tcphdr->chksum = 0;
1218  tcphdr->urgp = 0;
1219 
1220 #if CHECKSUM_GEN_TCP
1221  tcphdr->chksum = inet_chksum_pseudo(p, local_ip, remote_ip,
1222  IP_PROTO_TCP, p->tot_len);
1223 #endif
1224  TCP_STATS_INC(tcp.xmit);
1226  /* Send output with hardcoded TTL since we have no access to the pcb */
1227  ip_output(p, local_ip, remote_ip, TCP_TTL, 0, IP_PROTO_TCP);
1228  pbuf_free(p);
1229  LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_rst: seqno %"U32_F" ackno %"U32_F".\n", seqno, ackno));
1230 }
1231 
1232 /**
1233  * Requeue all unacked segments for retransmission
1234  *
1235  * Called by tcp_slowtmr() for slow retransmission.
1236  *
1237  * @param pcb the tcp_pcb for which to re-enqueue all unacked segments
1238  */
1239 void
1240 tcp_rexmit_rto(struct tcp_pcb *pcb)
1241 {
1242  struct tcp_seg *seg;
1243  struct tcp_seg *t0_head = NULL, *t0_tail = NULL; /* keep in unacked */
1244  struct tcp_seg *t1_head = NULL, *t1_tail = NULL; /* link to unsent */
1245  bool t0_1st = true, t1_1st = true;
1246 
1247  if (pcb->unacked == NULL) {
1248  return;
1249  }
1250 
1251 #if 1 /* by Snake: resolve the bug of pbuf reuse */
1252  seg = pcb->unacked;
1253  while (seg != NULL) {
1254  if (seg->p->eb) {
1255  if (t0_1st) {
1256  t0_head = t0_tail = seg;
1257  t0_1st = false;
1258  } else {
1259  t0_tail->next = seg;
1260  t0_tail = seg;
1261  }
1262  seg = seg->next;
1263  t0_tail->next = NULL;
1264  } else {
1265  if (t1_1st) {
1266  t1_head = t1_tail = seg;
1267  t1_1st = false;
1268  } else {
1269  t1_tail->next = seg;
1270  t1_tail = seg;
1271  }
1272  seg = seg->next;
1273  t1_tail->next = NULL;
1274  }
1275  }
1276  if (t1_head && t1_tail) {
1277  t1_tail->next = pcb->unsent;
1278  pcb->unsent = t1_head;
1279  }
1280  pcb->unacked = t0_head;
1281 
1282 #else
1283 
1284  /* Move all unacked segments to the head of the unsent queue */
1285  for (seg = pcb->unacked; seg->next != NULL; seg = seg->next);
1286  /* concatenate unsent queue after unacked queue */
1287  seg->next = pcb->unsent;
1288  /* unsent queue is the concatenated queue (of unacked, unsent) */
1289  pcb->unsent = pcb->unacked;
1290  /* unacked queue is now empty */
1291  pcb->unacked = NULL;
1292 #endif
1293 
1294  /* increment number of retransmissions */
1295  ++pcb->nrtx;
1296 
1297  /* Don't take any RTT measurements after retransmitting. */
1298  pcb->rttest = 0;
1299 
1300  /* Do the actual retransmission */
1301  tcp_output(pcb);
1302 }
1303 
1304 /**
1305  * Requeue the first unacked segment for retransmission
1306  *
1307  * Called by tcp_receive() for fast retramsmit.
1308  *
1309  * @param pcb the tcp_pcb for which to retransmit the first unacked segment
1310  */
1311 void
1312 tcp_rexmit(struct tcp_pcb *pcb)
1313 {
1314  struct tcp_seg *seg;
1315  struct tcp_seg **cur_seg;
1316 
1317  if (pcb->unacked == NULL) {
1318  return;
1319  }
1320 
1321  /* Move the first unacked segment to the unsent queue */
1322  /* Keep the unsent queue sorted. */
1323  seg = pcb->unacked;
1324  pcb->unacked = seg->next;
1325 
1326  cur_seg = &(pcb->unsent);
1327  while (*cur_seg &&
1328  TCP_SEQ_LT(ntohl((*cur_seg)->tcphdr->seqno), ntohl(seg->tcphdr->seqno))) {
1329  cur_seg = &((*cur_seg)->next );
1330  }
1331  seg->next = *cur_seg;
1332  *cur_seg = seg;
1333 
1334  ++pcb->nrtx;
1335 
1336  /* Don't take any rtt measurements after retransmitting. */
1337  pcb->rttest = 0;
1338 
1339  /* Do the actual retransmission. */
1341  /* No need to call tcp_output: we are always called from tcp_input()
1342  and thus tcp_output directly returns. */
1343 }
1344 
1345 
1346 /**
1347  * Handle retransmission after three dupacks received
1348  *
1349  * @param pcb the tcp_pcb for which to retransmit the first unacked segment
1350  */
1351 void
1352 tcp_rexmit_fast(struct tcp_pcb *pcb)
1353 {
1354  if (pcb->unacked != NULL && !(pcb->flags & TF_INFR)) {
1355  /* This is fast retransmit. Retransmit the first unacked segment. */
1357  ("tcp_receive: dupacks %"U16_F" (%"U32_F
1358  "), fast retransmit %"U32_F"\n",
1359  (u16_t)pcb->dupacks, pcb->lastack,
1360  ntohl(pcb->unacked->tcphdr->seqno)));
1361  tcp_rexmit(pcb);
1362 
1363  /* Set ssthresh to half of the minimum of the current
1364  * cwnd and the advertised window */
1365  if (pcb->cwnd > pcb->snd_wnd) {
1366  pcb->ssthresh = pcb->snd_wnd / 2;
1367  } else {
1368  pcb->ssthresh = pcb->cwnd / 2;
1369  }
1370 
1371  /* The minimum value for ssthresh should be 2 MSS */
1372  if (pcb->ssthresh < 2*pcb->mss) {
1374  ("tcp_receive: The minimum value for ssthresh %"U16_F
1375  " should be min 2 mss %"U16_F"...\n",
1376  pcb->ssthresh, 2*pcb->mss));
1377  pcb->ssthresh = 2*pcb->mss;
1378  }
1379 
1380  pcb->cwnd = pcb->ssthresh + 3 * pcb->mss;
1381  pcb->flags |= TF_INFR;
1382  }
1383 }
1384 
1385 
1386 /**
1387  * Send keepalive packets to keep a connection active although
1388  * no data is sent over it.
1389  *
1390  * Called by tcp_slowtmr()
1391  *
1392  * @param pcb the tcp_pcb for which to send a keepalive packet
1393  */
1394 void
1395 tcp_keepalive(struct tcp_pcb *pcb)
1396 {
1397  struct pbuf *p;
1398  struct tcp_hdr *tcphdr;
1399 
1400  LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: sending KEEPALIVE probe to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
1401  ip4_addr1_16(&pcb->remote_ip), ip4_addr2_16(&pcb->remote_ip),
1402  ip4_addr3_16(&pcb->remote_ip), ip4_addr4_16(&pcb->remote_ip)));
1403 
1404  LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: tcp_ticks %"U32_F" pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n",
1405  tcp_ticks, pcb->tmr, pcb->keep_cnt_sent));
1406 
1407  p = tcp_output_alloc_header(pcb, 0, 0, htonl(pcb->snd_nxt - 1));
1408  if(p == NULL) {
1410  ("tcp_keepalive: could not allocate memory for pbuf\n"));
1411  return;
1412  }
1413  tcphdr = (struct tcp_hdr *)p->payload;
1414 
1415 #if CHECKSUM_GEN_TCP
1416  tcphdr->chksum = inet_chksum_pseudo(p, &pcb->local_ip, &pcb->remote_ip,
1417  IP_PROTO_TCP, p->tot_len);
1418 #endif
1419  TCP_STATS_INC(tcp.xmit);
1420 
1421  /* Send output to IP */
1422 #if LWIP_NETIF_HWADDRHINT
1423  ip_output_hinted(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP,
1424  &(pcb->addr_hint));
1425 #else /* LWIP_NETIF_HWADDRHINT*/
1426  ip_output(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP);
1427 #endif /* LWIP_NETIF_HWADDRHINT*/
1428 
1429  pbuf_free(p);
1430 
1431  LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: seqno %"U32_F" ackno %"U32_F".\n",
1432  pcb->snd_nxt - 1, pcb->rcv_nxt));
1433 }
1434 
1435 
1436 /**
1437  * Send persist timer zero-window probes to keep a connection active
1438  * when a window update is lost.
1439  *
1440  * Called by tcp_slowtmr()
1441  *
1442  * @param pcb the tcp_pcb for which to send a zero-window probe packet
1443  */
1444 void
1445 tcp_zero_window_probe(struct tcp_pcb *pcb)
1446 {
1447  struct pbuf *p;
1448  struct tcp_hdr *tcphdr;
1449  struct tcp_seg *seg;
1450  u16_t offset = 0;
1451  u16_t len;
1452  u8_t is_fin;
1453 
1455  ("tcp_zero_window_probe: sending ZERO WINDOW probe to %"
1456  U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
1457  ip4_addr1_16(&pcb->remote_ip), ip4_addr2_16(&pcb->remote_ip),
1458  ip4_addr3_16(&pcb->remote_ip), ip4_addr4_16(&pcb->remote_ip)));
1459 
1461  ("tcp_zero_window_probe: tcp_ticks %"U32_F
1462  " pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n",
1463  tcp_ticks, pcb->tmr, pcb->keep_cnt_sent));
1464 
1465  seg = pcb->unacked;
1466 
1467  if(seg == NULL) {
1468  seg = pcb->unsent;
1469  } else {
1470  struct ip_hdr *iphdr = NULL;
1471  iphdr = (struct ip_hdr *)((char*)seg->p->payload + SIZEOF_ETH_HDR);
1472  offset = IPH_HL(iphdr)*4;
1473  offset += SIZEOF_ETH_HDR;
1474  }
1475  if(seg == NULL) {
1476  return;
1477  }
1478 
1479  is_fin = ((TCPH_FLAGS(seg->tcphdr) & TCP_FIN) != 0) && (seg->len == 0);
1480  /* we want to send one seqno: either FIN or data (no options) */
1481  len = is_fin ? 0 : 1;
1482 
1483  p = tcp_output_alloc_header(pcb, 0, len, seg->tcphdr->seqno);
1484  if(p == NULL) {
1485  LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: no memory for pbuf\n"));
1486  return;
1487  }
1488  tcphdr = (struct tcp_hdr *)p->payload;
1489 
1490  if (is_fin) {
1491  /* FIN segment, no data */
1492  TCPH_FLAGS_SET(tcphdr, TCP_ACK | TCP_FIN);
1493  } else {
1494  /* Data segment, copy in one byte from the head of the unacked queue */
1495  struct tcp_hdr *thdr = (struct tcp_hdr *)seg->p->payload;
1496  char *d = ((char *)p->payload + TCP_HLEN);
1497  if (pcb->unacked == NULL)
1498  pbuf_copy_partial(seg->p, d, 1, TCPH_HDRLEN(thdr) * 4);
1499  else {
1500  thdr = (struct tcp_hdr *)((char*)seg->p->payload + offset);
1501  pbuf_copy_partial(seg->p, d, 1, TCPH_HDRLEN(thdr) * 4 + offset);
1502  }
1503  }
1504 
1505 #if CHECKSUM_GEN_TCP
1506  tcphdr->chksum = inet_chksum_pseudo(p, &pcb->local_ip, &pcb->remote_ip,
1507  IP_PROTO_TCP, p->tot_len);
1508 #endif
1509  TCP_STATS_INC(tcp.xmit);
1510 
1511  /* Send output to IP */
1512 #if LWIP_NETIF_HWADDRHINT
1513  ip_output_hinted(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP,
1514  &(pcb->addr_hint));
1515 #else /* LWIP_NETIF_HWADDRHINT*/
1516  ip_output(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP);
1517 #endif /* LWIP_NETIF_HWADDRHINT*/
1518 
1519  pbuf_free(p);
1520 
1521  LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: seqno %"U32_F
1522  " ackno %"U32_F".\n",
1523  pcb->snd_nxt - 1, pcb->rcv_nxt));
1524 }
1525 #endif /* LWIP_TCP */
#define PP_HTONL(x)
Definition: def.h:94
#define CHECKSUM_GEN_TCP
Definition: opt.h:1754
u16_t tot_len
Definition: pbuf.h:90
#define ERR_CONN
Definition: err.h:66
#define ip4_addr3_16(ipaddr)
Definition: ip_addr.h:228
#define TCP_QLEN_DEBUG
Definition: opt.h:1981
struct pbuf * next
Definition: pbuf.h:78
u16_t len
Definition: pbuf.h:93
u16_t inet_chksum(void *dataptr, u16_t len) ICACHE_FLASH_ATTR
Definition: inet_chksum.c:396
#define U16_F
Definition: cc.h:61
signed short s16_t
Definition: cc.h:55
#define snmp_inc_tcpoutsegs()
Definition: snmp.h:316
#define NULL
Definition: def.h:47
#define TCP_CWND_DEBUG
Definition: opt.h:1953
#define htons(x)
Definition: def.h:81
#define IP_PROTO_TCP
Definition: ip.h:56
#define LWIP_DBG_TRACE
Definition: debug.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 TCP_RTO_DEBUG
Definition: opt.h:1946
#define MEM_ALIGNMENT
Definition: opt.h:124
void * memp_malloc(memp_t type) ICACHE_FLASH_ATTR
Definition: memp.c:393
#define IPH_HL(hdr)
Definition: ip.h:145
#define LWIP_DBG_LEVEL_SEVERE
Definition: debug.h:47
Definition: pbuf.h:58
void pbuf_cat(struct pbuf *head, struct pbuf *tail) ICACHE_FLASH_ATTR
Definition: pbuf.c:823
#define TCP_OUTPUT_DEBUG
Definition: opt.h:1967
#define LWIP_ERROR(message, expression, handler)
Definition: debug.h:73
static u32_t sys_now(void) ICACHE_FLASH_ATTR
Definition: sys.h:235
#define TCP_STATS_INC(x)
Definition: stats.h:171
#define LWIP_MIN(x, y)
Definition: def.h:44
#define TCP_WND
Definition: opt.h:903
struct netif * ip_route(ip_addr_t *dest) ICACHE_FLASH_ATTR
Definition: ip.c:125
#define TCP_TTL
Definition: opt.h:895
#define U32_F
Definition: cc.h:65
Definition: pbuf.h:54
#define ntohl(x)
Definition: def.h:84
#define PP_HTONS(x)
Definition: def.h:92
#define LWIP_MEM_ALIGN_SIZE(size)
Definition: mem.h:144
unsigned long u32_t
Definition: cc.h:56
#define LWIP_DEBUGF(debug, message)
Definition: debug.h:94
#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
#define SWAP_BYTES_IN_WORD(w)
Definition: inet_chksum.h:47
#define FOLD_U32T(u)
Definition: inet_chksum.h:53
typedefPACK_STRUCT_END struct ip_addr ip_addr_t
Definition: ip_addr.h:64
#define LWIP_DBG_STATE
Definition: debug.h:58
unsigned long mem_ptr_t
Definition: cc.h:58
#define LWIP_DBG_LEVEL_WARNING
Definition: debug.h:45
Definition: netif.h:139
Definition: pbuf.h:59
#define TCP_OVERSIZE
Definition: opt.h:1016
#define ip4_addr4_16(ipaddr)
Definition: ip_addr.h:229
#define TCP_FR_DEBUG
Definition: opt.h:1938
ip_addr_t ip_addr
Definition: netif.h:144
#define TCP_DEBUG
Definition: opt.h:1924
#define ip_addr_isany(addr1)
Definition: ip_addr.h:200
#define S16_F
Definition: cc.h:60
#define ERR_ARG
Definition: err.h:68
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
u16_t inet_chksum_pseudo_partial(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, u8_t proto, u16_t proto_len, u16_t chksum_len) ICACHE_FLASH_ATTR
Definition: inet_chksum.c:332
Definition: ip.h:116
u8_t pbuf_header(struct pbuf *p, s16_t header_size) ICACHE_FLASH_ATTR
Definition: pbuf.c:573
#define ip4_addr1_16(ipaddr)
Definition: ip_addr.h:226
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 snmp_inc_tcpretranssegs()
Definition: snmp.h:317
#define snmp_inc_tcpoutrsts()
Definition: snmp.h:319
u16_t pbuf_copy_partial(struct pbuf *p, void *dataptr, u16_t len, u16_t offset) ICACHE_FLASH_ATTR
Definition: pbuf.c:996
Definition: pbuf.h:52
#define TCP_RST_DEBUG
Definition: opt.h:1974
#define TCP_SND_QUEUELEN
Definition: opt.h:964
#define ip4_addr2_16(ipaddr)
Definition: ip_addr.h:227
err_t ip_output(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, u8_t ttl, u8_t tos, u8_t proto) ICACHE_FLASH_ATTR
Definition: ip.c:1435
pbuf_layer
Definition: pbuf.h:50
#define ERR_MEM
Definition: err.h:53
#define LWIP_UNUSED_ARG(x)
Definition: arch.h:73
#define htonl(x)
Definition: def.h:83
struct pbuf * pbuf_alloc(pbuf_layer l, u16_t length, pbuf_type type) ICACHE_FLASH_ATTR
Definition: pbuf.c:234
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
#define ERR_BUF
Definition: err.h:54