ReactOS  0.4.15-dev-5455-g015cd25
tcp_out.c
Go to the documentation of this file.
1 
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/ip_addr.h"
50 #include "lwip/netif.h"
51 #include "lwip/inet_chksum.h"
52 #include "lwip/stats.h"
53 #include "lwip/snmp.h"
54 #if LWIP_TCP_TIMESTAMPS
55 #include "lwip/sys.h"
56 #endif
57 
58 #include <string.h>
59 
60 /* Define some copy-macros for checksum-on-copy so that the code looks
61  nicer by preventing too many ifdef's. */
62 #if TCP_CHECKSUM_ON_COPY
63 #define TCP_DATA_COPY(dst, src, len, seg) do { \
64  tcp_seg_add_chksum(LWIP_CHKSUM_COPY(dst, src, len), \
65  len, &seg->chksum, &seg->chksum_swapped); \
66  seg->flags |= TF_SEG_DATA_CHECKSUMMED; } while(0)
67 #define TCP_DATA_COPY2(dst, src, len, chksum, chksum_swapped) \
68  tcp_seg_add_chksum(LWIP_CHKSUM_COPY(dst, src, len), len, chksum, chksum_swapped);
69 #else /* TCP_CHECKSUM_ON_COPY*/
70 #define TCP_DATA_COPY(dst, src, len, seg) MEMCPY(dst, src, len)
71 #define TCP_DATA_COPY2(dst, src, len, chksum, chksum_swapped) MEMCPY(dst, src, len)
72 #endif /* TCP_CHECKSUM_ON_COPY*/
73 
76 #ifndef TCP_CHECKSUM_ON_COPY_SANITY_CHECK
77 #define TCP_CHECKSUM_ON_COPY_SANITY_CHECK 0
78 #endif
79 
80 /* Forward declarations.*/
81 static void tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb);
82 
93 static struct pbuf *
94 tcp_output_alloc_header(struct tcp_pcb *pcb, u16_t optlen, u16_t datalen,
95  u32_t seqno_be /* already in network byte order */)
96 {
97  struct tcp_hdr *tcphdr;
98  struct pbuf *p = pbuf_alloc(PBUF_IP, TCP_HLEN + optlen + datalen, PBUF_RAM);
99  if (p != NULL) {
100  LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr",
101  (p->len >= TCP_HLEN + optlen));
102  tcphdr = (struct tcp_hdr *)p->payload;
103  tcphdr->src = htons(pcb->local_port);
104  tcphdr->dest = htons(pcb->remote_port);
105  tcphdr->seqno = seqno_be;
106  tcphdr->ackno = htonl(pcb->rcv_nxt);
107  TCPH_HDRLEN_FLAGS_SET(tcphdr, (5 + optlen / 4), TCP_ACK);
108  tcphdr->wnd = htons(pcb->rcv_ann_wnd);
109  tcphdr->chksum = 0;
110  tcphdr->urgp = 0;
111 
112  /* If we're sending a packet, update the announced right window edge */
113  pcb->rcv_ann_right_edge = pcb->rcv_nxt + pcb->rcv_ann_wnd;
114  }
115  return p;
116 }
117 
124 err_t
125 tcp_send_fin(struct tcp_pcb *pcb)
126 {
127  /* first, try to add the fin to the last unsent segment */
128  if (pcb->unsent != NULL) {
129  struct tcp_seg *last_unsent;
130  for (last_unsent = pcb->unsent; last_unsent->next != NULL;
131  last_unsent = last_unsent->next);
132 
133  if ((TCPH_FLAGS(last_unsent->tcphdr) & (TCP_SYN | TCP_FIN | TCP_RST)) == 0) {
134  /* no SYN/FIN/RST flag in the header, we can add the FIN flag */
135  TCPH_SET_FLAG(last_unsent->tcphdr, TCP_FIN);
136  pcb->flags |= TF_FIN;
137  return ERR_OK;
138  }
139  }
140  /* no data, no length, flags, copy=1, no optdata */
141  return tcp_enqueue_flags(pcb, TCP_FIN);
142 }
143 
158 static struct tcp_seg *
159 tcp_create_segment(struct tcp_pcb *pcb, struct pbuf *p, u8_t flags, u32_t seqno, u8_t optflags)
160 {
161  struct tcp_seg *seg;
162  u8_t optlen = LWIP_TCP_OPT_LENGTH(optflags);
163 
164  if ((seg = (struct tcp_seg *)memp_malloc(MEMP_TCP_SEG)) == NULL) {
165  LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_create_segment: no memory.\n"));
166  pbuf_free(p);
167  return NULL;
168  }
169  seg->flags = optflags;
170  seg->next = NULL;
171  seg->p = p;
172  seg->len = p->tot_len - optlen;
173 #if TCP_OVERSIZE_DBGCHECK
174  seg->oversize_left = 0;
175 #endif /* TCP_OVERSIZE_DBGCHECK */
176 #if TCP_CHECKSUM_ON_COPY
177  seg->chksum = 0;
178  seg->chksum_swapped = 0;
179  /* check optflags */
180  LWIP_ASSERT("invalid optflags passed: TF_SEG_DATA_CHECKSUMMED",
181  (optflags & TF_SEG_DATA_CHECKSUMMED) == 0);
182 #endif /* TCP_CHECKSUM_ON_COPY */
183 
184  /* build TCP header */
185  if (pbuf_header(p, TCP_HLEN)) {
186  LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_create_segment: no room for TCP header in pbuf.\n"));
187  TCP_STATS_INC(tcp.err);
188  tcp_seg_free(seg);
189  return NULL;
190  }
191  seg->tcphdr = (struct tcp_hdr *)seg->p->payload;
192  seg->tcphdr->src = htons(pcb->local_port);
193  seg->tcphdr->dest = htons(pcb->remote_port);
194  seg->tcphdr->seqno = htonl(seqno);
195  /* ackno is set in tcp_output */
196  TCPH_HDRLEN_FLAGS_SET(seg->tcphdr, (5 + optlen / 4), flags);
197  /* wnd and chksum are set in tcp_output */
198  seg->tcphdr->urgp = 0;
199  return seg;
200 }
201 
217 #if TCP_OVERSIZE
218 static struct pbuf *
219 tcp_pbuf_prealloc(pbuf_layer layer, u16_t length, u16_t max_length,
220  u16_t *oversize, struct tcp_pcb *pcb, u8_t apiflags,
221  u8_t first_seg)
222 {
223  struct pbuf *p;
224  u16_t alloc = length;
225 
226 #if LWIP_NETIF_TX_SINGLE_PBUF
227  LWIP_UNUSED_ARG(max_length);
228  LWIP_UNUSED_ARG(pcb);
229  LWIP_UNUSED_ARG(apiflags);
230  LWIP_UNUSED_ARG(first_seg);
231  /* always create MSS-sized pbufs */
232  alloc = max_length;
233 #else /* LWIP_NETIF_TX_SINGLE_PBUF */
234  if (length < max_length) {
235  /* Should we allocate an oversized pbuf, or just the minimum
236  * length required? If tcp_write is going to be called again
237  * before this segment is transmitted, we want the oversized
238  * buffer. If the segment will be transmitted immediately, we can
239  * save memory by allocating only length. We use a simple
240  * heuristic based on the following information:
241  *
242  * Did the user set TCP_WRITE_FLAG_MORE?
243  *
244  * Will the Nagle algorithm defer transmission of this segment?
245  */
246  if ((apiflags & TCP_WRITE_FLAG_MORE) ||
247  (!(pcb->flags & TF_NODELAY) &&
248  (!first_seg ||
249  pcb->unsent != NULL ||
250  pcb->unacked != NULL))) {
252  }
253  }
254 #endif /* LWIP_NETIF_TX_SINGLE_PBUF */
256  if (p == NULL) {
257  return NULL;
258  }
259  LWIP_ASSERT("need unchained pbuf", p->next == NULL);
260  *oversize = p->len - length;
261  /* trim p->len to the currently used size */
262  p->len = p->tot_len = length;
263  return p;
264 }
265 #else /* TCP_OVERSIZE */
266 #define tcp_pbuf_prealloc(layer, length, mx, os, pcb, api, fst) pbuf_alloc((layer), (length), PBUF_RAM)
267 #endif /* TCP_OVERSIZE */
268 
269 #if TCP_CHECKSUM_ON_COPY
270 
271 static void
272 tcp_seg_add_chksum(u16_t chksum, u16_t len, u16_t *seg_chksum,
273  u8_t *seg_chksum_swapped)
274 {
275  u32_t helper;
276  /* add chksum to old chksum and fold to u16_t */
277  helper = chksum + *seg_chksum;
278  chksum = FOLD_U32T(helper);
279  if ((len & 1) != 0) {
280  *seg_chksum_swapped = 1 - *seg_chksum_swapped;
282  }
283  *seg_chksum = chksum;
284 }
285 #endif /* TCP_CHECKSUM_ON_COPY */
286 
293 static err_t
294 tcp_write_checks(struct tcp_pcb *pcb, u16_t len)
295 {
296  /* connection is in invalid state for data transmission? */
297  if ((pcb->state != ESTABLISHED) &&
298  (pcb->state != CLOSE_WAIT) &&
299  (pcb->state != SYN_SENT) &&
300  (pcb->state != SYN_RCVD)) {
301  LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_STATE | LWIP_DBG_LEVEL_SEVERE, ("tcp_write() called in invalid state\n"));
302  return ERR_CONN;
303  } else if (len == 0) {
304  return ERR_OK;
305  }
306 
307  /* fail on too much data */
308  if (len > pcb->snd_buf) {
309  LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_write: too much data (len=%"U16_F" > snd_buf=%"U16_F")\n",
310  len, pcb->snd_buf));
311  pcb->flags |= TF_NAGLEMEMERR;
312  return ERR_MEM;
313  }
314 
315  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_write: queuelen: %"U16_F"\n", (u16_t)pcb->snd_queuelen));
316 
317  /* If total number of pbufs on the unsent/unacked queues exceeds the
318  * configured maximum, return an error */
319  /* check for configured max queuelen and possible overflow */
320  if ((pcb->snd_queuelen >= TCP_SND_QUEUELEN) || (pcb->snd_queuelen > TCP_SNDQUEUELEN_OVERFLOW)) {
321  LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_write: too long queue %"U16_F" (max %"U16_F")\n",
322  pcb->snd_queuelen, TCP_SND_QUEUELEN));
323  TCP_STATS_INC(tcp.memerr);
324  pcb->flags |= TF_NAGLEMEMERR;
325  return ERR_MEM;
326  }
327  if (pcb->snd_queuelen != 0) {
328  LWIP_ASSERT("tcp_write: pbufs on queue => at least one queue non-empty",
329  pcb->unacked != NULL || pcb->unsent != NULL);
330  } else {
331  LWIP_ASSERT("tcp_write: no pbufs on queue => both queues empty",
332  pcb->unacked == NULL && pcb->unsent == NULL);
333  }
334  return ERR_OK;
335 }
336 
353 err_t
354 tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags)
355 {
356  struct pbuf *concat_p = NULL;
357  struct tcp_seg *last_unsent = NULL, *seg = NULL, *prev_seg = NULL, *queue = NULL;
358  u16_t pos = 0; /* position in 'arg' data */
359  u16_t queuelen;
360  u8_t optlen = 0;
361  u8_t optflags = 0;
362 #if TCP_OVERSIZE
363  u16_t oversize = 0;
364  u16_t oversize_used = 0;
365 #endif /* TCP_OVERSIZE */
366 #if TCP_CHECKSUM_ON_COPY
367  u16_t concat_chksum = 0;
368  u8_t concat_chksum_swapped = 0;
369  u16_t concat_chksummed = 0;
370 #endif /* TCP_CHECKSUM_ON_COPY */
371  err_t err;
372  /* don't allocate segments bigger than half the maximum window we ever received */
373  u16_t mss_local = LWIP_MIN(pcb->mss, pcb->snd_wnd_max/2);
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 = mss_local - (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 = mss_local - 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, mss_local, &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  LWIP_ASSERT("last_unsent->oversize_left >= oversize_used",
639  last_unsent->oversize_left >= oversize_used);
640  last_unsent->oversize_left -= oversize_used;
641 #endif /* TCP_OVERSIZE_DBGCHECK */
642  }
643  pcb->unsent_oversize = oversize;
644 #endif /* TCP_OVERSIZE */
645 
646  /*
647  * Phase 2: concat_p can be concatenated onto last_unsent->p
648  */
649  if (concat_p != NULL) {
650  LWIP_ASSERT("tcp_write: cannot concatenate when pcb->unsent is empty",
651  (last_unsent != NULL));
652  pbuf_cat(last_unsent->p, concat_p);
653  last_unsent->len += concat_p->tot_len;
654 #if TCP_CHECKSUM_ON_COPY
655  if (concat_chksummed) {
656  tcp_seg_add_chksum(concat_chksum, concat_chksummed, &last_unsent->chksum,
657  &last_unsent->chksum_swapped);
658  last_unsent->flags |= TF_SEG_DATA_CHECKSUMMED;
659  }
660 #endif /* TCP_CHECKSUM_ON_COPY */
661  }
662 
663  /*
664  * Phase 3: Append queue to pcb->unsent. Queue may be NULL, but that
665  * is harmless
666  */
667  if (last_unsent == NULL) {
668  pcb->unsent = queue;
669  } else {
670  last_unsent->next = queue;
671  }
672 
673  /*
674  * Finally update the pcb state.
675  */
676  pcb->snd_lbb += len;
677  pcb->snd_buf -= len;
678  pcb->snd_queuelen = queuelen;
679 
680  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_write: %"S16_F" (after enqueued)\n",
681  pcb->snd_queuelen));
682  if (pcb->snd_queuelen != 0) {
683  LWIP_ASSERT("tcp_write: valid queue length",
684  pcb->unacked != NULL || pcb->unsent != NULL);
685  }
686 
687  /* Set the PSH flag in the last segment that we enqueued. */
688  if (seg != NULL && seg->tcphdr != NULL && ((apiflags & TCP_WRITE_FLAG_MORE)==0)) {
689  TCPH_SET_FLAG(seg->tcphdr, TCP_PSH);
690  }
691 
692  return ERR_OK;
693 memerr:
694  pcb->flags |= TF_NAGLEMEMERR;
695  TCP_STATS_INC(tcp.memerr);
696 
697  if (concat_p != NULL) {
698  pbuf_free(concat_p);
699  }
700  if (queue != NULL) {
701  tcp_segs_free(queue);
702  }
703  if (pcb->snd_queuelen != 0) {
704  LWIP_ASSERT("tcp_write: valid queue length", pcb->unacked != NULL ||
705  pcb->unsent != NULL);
706  }
707  LWIP_DEBUGF(TCP_QLEN_DEBUG | LWIP_DBG_STATE, ("tcp_write: %"S16_F" (with mem err)\n", pcb->snd_queuelen));
708  return ERR_MEM;
709 }
710 
721 err_t
722 tcp_enqueue_flags(struct tcp_pcb *pcb, u8_t flags)
723 {
724  struct pbuf *p;
725  struct tcp_seg *seg;
726  u8_t optflags = 0;
727  u8_t optlen = 0;
728 
729  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue_flags: queuelen: %"U16_F"\n", (u16_t)pcb->snd_queuelen));
730 
731  LWIP_ASSERT("tcp_enqueue_flags: need either TCP_SYN or TCP_FIN in flags (programmer violates API)",
732  (flags & (TCP_SYN | TCP_FIN)) != 0);
733 
734  /* check for configured max queuelen and possible overflow */
735  if ((pcb->snd_queuelen >= TCP_SND_QUEUELEN) || (pcb->snd_queuelen > TCP_SNDQUEUELEN_OVERFLOW)) {
736  LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue_flags: too long queue %"U16_F" (max %"U16_F")\n",
737  pcb->snd_queuelen, TCP_SND_QUEUELEN));
738  TCP_STATS_INC(tcp.memerr);
739  pcb->flags |= TF_NAGLEMEMERR;
740  return ERR_MEM;
741  }
742 
743  if (flags & TCP_SYN) {
744  optflags = TF_SEG_OPTS_MSS;
745  }
746 #if LWIP_TCP_TIMESTAMPS
747  if ((pcb->flags & TF_TIMESTAMP)) {
748  optflags |= TF_SEG_OPTS_TS;
749  }
750 #endif /* LWIP_TCP_TIMESTAMPS */
751  optlen = LWIP_TCP_OPT_LENGTH(optflags);
752 
753  /* tcp_enqueue_flags is always called with either SYN or FIN in flags.
754  * We need one available snd_buf byte to do that.
755  * This means we can't send FIN while snd_buf==0. A better fix would be to
756  * not include SYN and FIN sequence numbers in the snd_buf count. */
757  if (pcb->snd_buf == 0) {
758  LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue_flags: no send buffer available\n"));
759  TCP_STATS_INC(tcp.memerr);
760  return ERR_MEM;
761  }
762 
763  /* Allocate pbuf with room for TCP header + options */
764  if ((p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) {
765  pcb->flags |= TF_NAGLEMEMERR;
766  TCP_STATS_INC(tcp.memerr);
767  return ERR_MEM;
768  }
769  LWIP_ASSERT("tcp_enqueue_flags: check that first pbuf can hold optlen",
770  (p->len >= optlen));
771 
772  /* Allocate memory for tcp_seg, and fill in fields. */
773  if ((seg = tcp_create_segment(pcb, p, flags, pcb->snd_lbb, optflags)) == NULL) {
774  pcb->flags |= TF_NAGLEMEMERR;
775  TCP_STATS_INC(tcp.memerr);
776  return ERR_MEM;
777  }
778  LWIP_ASSERT("seg->tcphdr not aligned", ((mem_ptr_t)seg->tcphdr % MEM_ALIGNMENT) == 0);
779  LWIP_ASSERT("tcp_enqueue_flags: invalid segment length", seg->len == 0);
780 
782  ("tcp_enqueue_flags: queueing %"U32_F":%"U32_F" (0x%"X16_F")\n",
783  ntohl(seg->tcphdr->seqno),
784  ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg),
785  (u16_t)flags));
786 
787  /* Now append seg to pcb->unsent queue */
788  if (pcb->unsent == NULL) {
789  pcb->unsent = seg;
790  } else {
791  struct tcp_seg *useg;
792  for (useg = pcb->unsent; useg->next != NULL; useg = useg->next);
793  useg->next = seg;
794  }
795 #if TCP_OVERSIZE
796  /* The new unsent tail has no space */
797  pcb->unsent_oversize = 0;
798 #endif /* TCP_OVERSIZE */
799 
800  /* SYN and FIN bump the sequence number */
801  if ((flags & TCP_SYN) || (flags & TCP_FIN)) {
802  pcb->snd_lbb++;
803  /* optlen does not influence snd_buf */
804  pcb->snd_buf--;
805  }
806  if (flags & TCP_FIN) {
807  pcb->flags |= TF_FIN;
808  }
809 
810  /* update number of segments on the queues */
811  pcb->snd_queuelen += pbuf_clen(seg->p);
812  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue_flags: %"S16_F" (after enqueued)\n", pcb->snd_queuelen));
813  if (pcb->snd_queuelen != 0) {
814  LWIP_ASSERT("tcp_enqueue_flags: invalid queue length",
815  pcb->unacked != NULL || pcb->unsent != NULL);
816  }
817 
818  return ERR_OK;
819 }
820 
821 #if LWIP_TCP_TIMESTAMPS
822 /* Build a timestamp option (12 bytes long) at the specified options pointer)
823  *
824  * @param pcb tcp_pcb
825  * @param opts option pointer where to store the timestamp option
826  */
827 static void
828 tcp_build_timestamp_option(struct tcp_pcb *pcb, u32_t *opts)
829 {
830  /* Pad with two NOP options to make everything nicely aligned */
831  opts[0] = PP_HTONL(0x0101080A);
832  opts[1] = htonl(sys_now());
833  opts[2] = htonl(pcb->ts_recent);
834 }
835 #endif
836 
841 err_t
842 tcp_send_empty_ack(struct tcp_pcb *pcb)
843 {
844  struct pbuf *p;
845  struct tcp_hdr *tcphdr;
846  u8_t optlen = 0;
847 
848 #if LWIP_TCP_TIMESTAMPS
849  if (pcb->flags & TF_TIMESTAMP) {
850  optlen = LWIP_TCP_OPT_LENGTH(TF_SEG_OPTS_TS);
851  }
852 #endif
853 
854  p = tcp_output_alloc_header(pcb, optlen, 0, htonl(pcb->snd_nxt));
855  if (p == NULL) {
856  LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: (ACK) could not allocate pbuf\n"));
857  return ERR_BUF;
858  }
859  tcphdr = (struct tcp_hdr *)p->payload;
861  ("tcp_output: sending ACK for %"U32_F"\n", pcb->rcv_nxt));
862  /* remove ACK flags from the PCB, as we send an empty ACK now */
863  pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
864 
865  /* NB. MSS option is only sent on SYNs, so ignore it here */
866 #if LWIP_TCP_TIMESTAMPS
867  pcb->ts_lastacksent = pcb->rcv_nxt;
868 
869  if (pcb->flags & TF_TIMESTAMP) {
870  tcp_build_timestamp_option(pcb, (u32_t *)(tcphdr + 1));
871  }
872 #endif
873 
874 #if CHECKSUM_GEN_TCP
875  tcphdr->chksum = inet_chksum_pseudo(p, &(pcb->local_ip), &(pcb->remote_ip),
876  IP_PROTO_TCP, p->tot_len);
877 #endif
878 #if LWIP_NETIF_HWADDRHINT
879  ip_output_hinted(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
880  IP_PROTO_TCP, &(pcb->addr_hint));
881 #else /* LWIP_NETIF_HWADDRHINT*/
882  ip_output(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
883  IP_PROTO_TCP);
884 #endif /* LWIP_NETIF_HWADDRHINT*/
885  pbuf_free(p);
886 
887  return ERR_OK;
888 }
889 
897 err_t
898 tcp_output(struct tcp_pcb *pcb)
899 {
900  struct tcp_seg *seg, *useg;
901  u32_t wnd, snd_nxt;
902 #if TCP_CWND_DEBUG
903  s16_t i = 0;
904 #endif /* TCP_CWND_DEBUG */
905 
906  /* pcb->state LISTEN not allowed here */
907  LWIP_ASSERT("don't call tcp_output for listen-pcbs",
908  pcb->state != LISTEN);
909 
910  /* First, check if we are invoked by the TCP input processing
911  code. If so, we do not output anything. Instead, we rely on the
912  input processing code to call us when input processing is done
913  with. */
914  if (tcp_input_pcb == pcb) {
915  return ERR_OK;
916  }
917 
918  wnd = LWIP_MIN(pcb->snd_wnd, pcb->cwnd);
919 
920  seg = pcb->unsent;
921 
922  /* If the TF_ACK_NOW flag is set and no data will be sent (either
923  * because the ->unsent queue is empty or because the window does
924  * not allow it), construct an empty ACK segment and send it.
925  *
926  * If data is to be sent, we will just piggyback the ACK (see below).
927  */
928  if (pcb->flags & TF_ACK_NOW &&
929  (seg == NULL ||
930  ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len > wnd)) {
931  return tcp_send_empty_ack(pcb);
932  }
933 
934  /* useg should point to last segment on unacked queue */
935  useg = pcb->unacked;
936  if (useg != NULL) {
937  for (; useg->next != NULL; useg = useg->next);
938  }
939 
940 #if TCP_OUTPUT_DEBUG
941  if (seg == NULL) {
942  LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: nothing to send (%p)\n",
943  (void*)pcb->unsent));
944  }
945 #endif /* TCP_OUTPUT_DEBUG */
946 #if TCP_CWND_DEBUG
947  if (seg == NULL) {
948  LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"U16_F
949  ", cwnd %"U16_F", wnd %"U32_F
950  ", seg == NULL, ack %"U32_F"\n",
951  pcb->snd_wnd, pcb->cwnd, wnd, pcb->lastack));
952  } else {
954  ("tcp_output: snd_wnd %"U16_F", cwnd %"U16_F", wnd %"U32_F
955  ", effwnd %"U32_F", seq %"U32_F", ack %"U32_F"\n",
956  pcb->snd_wnd, pcb->cwnd, wnd,
957  ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len,
958  ntohl(seg->tcphdr->seqno), pcb->lastack));
959  }
960 #endif /* TCP_CWND_DEBUG */
961  /* data available and window allows it to be sent? */
962  while (seg != NULL &&
963  ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) {
964  LWIP_ASSERT("RST not expected here!",
965  (TCPH_FLAGS(seg->tcphdr) & TCP_RST) == 0);
966  /* Stop sending if the nagle algorithm would prevent it
967  * Don't stop:
968  * - if tcp_write had a memory error before (prevent delayed ACK timeout) or
969  * - if FIN was already enqueued for this PCB (SYN is always alone in a segment -
970  * either seg->next != NULL or pcb->unacked == NULL;
971  * RST is no sent using tcp_write/tcp_output.
972  */
973  if((tcp_do_output_nagle(pcb) == 0) &&
974  ((pcb->flags & (TF_NAGLEMEMERR | TF_FIN)) == 0)){
975  break;
976  }
977 #if TCP_CWND_DEBUG
978  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",
979  pcb->snd_wnd, pcb->cwnd, wnd,
980  ntohl(seg->tcphdr->seqno) + seg->len -
981  pcb->lastack,
982  ntohl(seg->tcphdr->seqno), pcb->lastack, i));
983  ++i;
984 #endif /* TCP_CWND_DEBUG */
985 
986  pcb->unsent = seg->next;
987 
988  if (pcb->state != SYN_SENT) {
989  TCPH_SET_FLAG(seg->tcphdr, TCP_ACK);
990  pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
991  }
992 
993  tcp_output_segment(seg, pcb);
994  snd_nxt = ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg);
995  if (TCP_SEQ_LT(pcb->snd_nxt, snd_nxt)) {
996  pcb->snd_nxt = snd_nxt;
997  }
998  /* put segment on unacknowledged list if length > 0 */
999  if (TCP_TCPLEN(seg) > 0) {
1000  seg->next = NULL;
1001  /* unacked list is empty? */
1002  if (pcb->unacked == NULL) {
1003  pcb->unacked = seg;
1004  useg = seg;
1005  /* unacked list is not empty? */
1006  } else {
1007  /* In the case of fast retransmit, the packet should not go to the tail
1008  * of the unacked queue, but rather somewhere before it. We need to check for
1009  * this case. -STJ Jul 27, 2004 */
1010  if (TCP_SEQ_LT(ntohl(seg->tcphdr->seqno), ntohl(useg->tcphdr->seqno))) {
1011  /* add segment to before tail of unacked list, keeping the list sorted */
1012  struct tcp_seg **cur_seg = &(pcb->unacked);
1013  while (*cur_seg &&
1014  TCP_SEQ_LT(ntohl((*cur_seg)->tcphdr->seqno), ntohl(seg->tcphdr->seqno))) {
1015  cur_seg = &((*cur_seg)->next );
1016  }
1017  seg->next = (*cur_seg);
1018  (*cur_seg) = seg;
1019  } else {
1020  /* add segment to tail of unacked list */
1021  useg->next = seg;
1022  useg = useg->next;
1023  }
1024  }
1025  /* do not queue empty segments on the unacked list */
1026  } else {
1027  tcp_seg_free(seg);
1028  }
1029  seg = pcb->unsent;
1030  }
1031 #if TCP_OVERSIZE
1032  if (pcb->unsent == NULL) {
1033  /* last unsent has been removed, reset unsent_oversize */
1034  pcb->unsent_oversize = 0;
1035  }
1036 #endif /* TCP_OVERSIZE */
1037 
1038  pcb->flags &= ~TF_NAGLEMEMERR;
1039  return ERR_OK;
1040 }
1041 
1048 static void
1049 tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb)
1050 {
1051  u16_t len;
1052  struct netif *netif;
1053  u32_t *opts;
1054 
1057 
1058  /* The TCP header has already been constructed, but the ackno and
1059  wnd fields remain. */
1060  seg->tcphdr->ackno = htonl(pcb->rcv_nxt);
1061 
1062  /* advertise our receive window size in this TCP segment */
1063  seg->tcphdr->wnd = htons(pcb->rcv_ann_wnd);
1064 
1065  pcb->rcv_ann_right_edge = pcb->rcv_nxt + pcb->rcv_ann_wnd;
1066 
1067  /* Add any requested options. NB MSS option is only set on SYN
1068  packets, so ignore it here */
1069  opts = (u32_t *)(void *)(seg->tcphdr + 1);
1070  if (seg->flags & TF_SEG_OPTS_MSS) {
1071  u16_t mss;
1072 #if TCP_CALCULATE_EFF_SEND_MSS
1073  mss = tcp_eff_send_mss(TCP_MSS, &pcb->remote_ip);
1074 #else /* TCP_CALCULATE_EFF_SEND_MSS */
1075  mss = TCP_MSS;
1076 #endif /* TCP_CALCULATE_EFF_SEND_MSS */
1077  *opts = TCP_BUILD_MSS_OPTION(mss);
1078  opts += 1;
1079  }
1080 #if LWIP_TCP_TIMESTAMPS
1081  pcb->ts_lastacksent = pcb->rcv_nxt;
1082 
1083  if (seg->flags & TF_SEG_OPTS_TS) {
1084  tcp_build_timestamp_option(pcb, opts);
1085  opts += 3;
1086  }
1087 #endif
1088 
1089  /* Set retransmission timer running if it is not currently enabled
1090  This must be set before checking the route. */
1091  if (pcb->rtime == -1) {
1092  pcb->rtime = 0;
1093  }
1094 
1095  /* If we don't have a local IP address, we get one by
1096  calling ip_route(). */
1097  if (ip_addr_isany(&(pcb->local_ip))) {
1098  netif = ip_route(&(pcb->remote_ip));
1099  if (netif == NULL) {
1100  return;
1101  }
1102  ip_addr_copy(pcb->local_ip, netif->ip_addr);
1103  }
1104 
1105  if (pcb->rttest == 0) {
1106  pcb->rttest = tcp_ticks;
1107  pcb->rtseq = ntohl(seg->tcphdr->seqno);
1108 
1109  LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_output_segment: rtseq %"U32_F"\n", pcb->rtseq));
1110  }
1111  LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output_segment: %"U32_F":%"U32_F"\n",
1112  htonl(seg->tcphdr->seqno), htonl(seg->tcphdr->seqno) +
1113  seg->len));
1114 
1115  len = (u16_t)((u8_t *)seg->tcphdr - (u8_t *)seg->p->payload);
1116 
1117  seg->p->len -= len;
1118  seg->p->tot_len -= len;
1119 
1120  seg->p->payload = seg->tcphdr;
1121 
1122  seg->tcphdr->chksum = 0;
1123 #if CHECKSUM_GEN_TCP
1124 #if TCP_CHECKSUM_ON_COPY
1125  {
1126  u32_t acc;
1127 #if TCP_CHECKSUM_ON_COPY_SANITY_CHECK
1128  u16_t chksum_slow = inet_chksum_pseudo(seg->p, &(pcb->local_ip),
1129  &(pcb->remote_ip),
1130  IP_PROTO_TCP, seg->p->tot_len);
1131 #endif /* TCP_CHECKSUM_ON_COPY_SANITY_CHECK */
1132  if ((seg->flags & TF_SEG_DATA_CHECKSUMMED) == 0) {
1133  LWIP_ASSERT("data included but not checksummed",
1134  seg->p->tot_len == (TCPH_HDRLEN(seg->tcphdr) * 4));
1135  }
1136 
1137  /* rebuild TCP header checksum (TCP header changes for retransmissions!) */
1138  acc = inet_chksum_pseudo_partial(seg->p, &(pcb->local_ip),
1139  &(pcb->remote_ip),
1140  IP_PROTO_TCP, seg->p->tot_len, TCPH_HDRLEN(seg->tcphdr) * 4);
1141  /* add payload checksum */
1142  if (seg->chksum_swapped) {
1143  seg->chksum = SWAP_BYTES_IN_WORD(seg->chksum);
1144  seg->chksum_swapped = 0;
1145  }
1146  acc += (u16_t)~(seg->chksum);
1147  seg->tcphdr->chksum = FOLD_U32T(acc);
1148 #if TCP_CHECKSUM_ON_COPY_SANITY_CHECK
1149  if (chksum_slow != seg->tcphdr->chksum) {
1151  ("tcp_output_segment: calculated checksum is %"X16_F" instead of %"X16_F"\n",
1152  seg->tcphdr->chksum, chksum_slow));
1153  seg->tcphdr->chksum = chksum_slow;
1154  }
1155 #endif /* TCP_CHECKSUM_ON_COPY_SANITY_CHECK */
1156  }
1157 #else /* TCP_CHECKSUM_ON_COPY */
1158  seg->tcphdr->chksum = inet_chksum_pseudo(seg->p, &(pcb->local_ip),
1159  &(pcb->remote_ip),
1160  IP_PROTO_TCP, seg->p->tot_len);
1161 #endif /* TCP_CHECKSUM_ON_COPY */
1162 #endif /* CHECKSUM_GEN_TCP */
1163  TCP_STATS_INC(tcp.xmit);
1164 
1165 #if LWIP_NETIF_HWADDRHINT
1166  ip_output_hinted(seg->p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
1167  IP_PROTO_TCP, &(pcb->addr_hint));
1168 #else /* LWIP_NETIF_HWADDRHINT*/
1169  ip_output(seg->p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
1170  IP_PROTO_TCP);
1171 #endif /* LWIP_NETIF_HWADDRHINT*/
1172 }
1173 
1194 void
1195 tcp_rst(u32_t seqno, u32_t ackno,
1196  ip_addr_t *local_ip, ip_addr_t *remote_ip,
1197  u16_t local_port, u16_t remote_port)
1198 {
1199  struct pbuf *p;
1200  struct tcp_hdr *tcphdr;
1201  p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM);
1202  if (p == NULL) {
1203  LWIP_DEBUGF(TCP_DEBUG, ("tcp_rst: could not allocate memory for pbuf\n"));
1204  return;
1205  }
1206  LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr",
1207  (p->len >= sizeof(struct tcp_hdr)));
1208 
1209  tcphdr = (struct tcp_hdr *)p->payload;
1210  tcphdr->src = htons(local_port);
1211  tcphdr->dest = htons(remote_port);
1212  tcphdr->seqno = htonl(seqno);
1213  tcphdr->ackno = htonl(ackno);
1214  TCPH_HDRLEN_FLAGS_SET(tcphdr, TCP_HLEN/4, TCP_RST | TCP_ACK);
1215  tcphdr->wnd = PP_HTONS(TCP_WND);
1216  tcphdr->chksum = 0;
1217  tcphdr->urgp = 0;
1218 
1219 #if CHECKSUM_GEN_TCP
1220  tcphdr->chksum = inet_chksum_pseudo(p, local_ip, remote_ip,
1221  IP_PROTO_TCP, p->tot_len);
1222 #endif
1223  TCP_STATS_INC(tcp.xmit);
1225  /* Send output with hardcoded TTL since we have no access to the pcb */
1226  ip_output(p, local_ip, remote_ip, TCP_TTL, 0, IP_PROTO_TCP);
1227  pbuf_free(p);
1228  LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_rst: seqno %"U32_F" ackno %"U32_F".\n", seqno, ackno));
1229 }
1230 
1238 void
1239 tcp_rexmit_rto(struct tcp_pcb *pcb)
1240 {
1241  struct tcp_seg *seg;
1242 
1243  if (pcb->unacked == NULL) {
1244  return;
1245  }
1246 
1247  /* Move all unacked segments to the head of the unsent queue */
1248  for (seg = pcb->unacked; seg->next != NULL; seg = seg->next);
1249  /* concatenate unsent queue after unacked queue */
1250  seg->next = pcb->unsent;
1251  /* unsent queue is the concatenated queue (of unacked, unsent) */
1252  pcb->unsent = pcb->unacked;
1253  /* unacked queue is now empty */
1254  pcb->unacked = NULL;
1255  /* last unsent hasn't changed, no need to reset unsent_oversize */
1256 
1257  /* increment number of retransmissions */
1258  ++pcb->nrtx;
1259 
1260  /* Don't take any RTT measurements after retransmitting. */
1261  pcb->rttest = 0;
1262 
1263  /* Do the actual retransmission */
1264  tcp_output(pcb);
1265 }
1266 
1274 void
1275 tcp_rexmit(struct tcp_pcb *pcb)
1276 {
1277  struct tcp_seg *seg;
1278  struct tcp_seg **cur_seg;
1279 
1280  if (pcb->unacked == NULL) {
1281  return;
1282  }
1283 
1284  /* Move the first unacked segment to the unsent queue */
1285  /* Keep the unsent queue sorted. */
1286  seg = pcb->unacked;
1287  pcb->unacked = seg->next;
1288 
1289  cur_seg = &(pcb->unsent);
1290  while (*cur_seg &&
1291  TCP_SEQ_LT(ntohl((*cur_seg)->tcphdr->seqno), ntohl(seg->tcphdr->seqno))) {
1292  cur_seg = &((*cur_seg)->next );
1293  }
1294  seg->next = *cur_seg;
1295  *cur_seg = seg;
1296 #if TCP_OVERSIZE
1297  if (seg->next == NULL) {
1298  /* the retransmitted segment is last in unsent, so reset unsent_oversize */
1299  pcb->unsent_oversize = 0;
1300  }
1301 #endif /* TCP_OVERSIZE */
1302 
1303  ++pcb->nrtx;
1304 
1305  /* Don't take any rtt measurements after retransmitting. */
1306  pcb->rttest = 0;
1307 
1308  /* Do the actual retransmission. */
1310  /* No need to call tcp_output: we are always called from tcp_input()
1311  and thus tcp_output directly returns. */
1312 }
1313 
1314 
1320 void
1321 tcp_rexmit_fast(struct tcp_pcb *pcb)
1322 {
1323  if (pcb->unacked != NULL && !(pcb->flags & TF_INFR)) {
1324  /* This is fast retransmit. Retransmit the first unacked segment. */
1326  ("tcp_receive: dupacks %"U16_F" (%"U32_F
1327  "), fast retransmit %"U32_F"\n",
1328  (u16_t)pcb->dupacks, pcb->lastack,
1329  ntohl(pcb->unacked->tcphdr->seqno)));
1330  tcp_rexmit(pcb);
1331 
1332  /* Set ssthresh to half of the minimum of the current
1333  * cwnd and the advertised window */
1334  if (pcb->cwnd > pcb->snd_wnd) {
1335  pcb->ssthresh = pcb->snd_wnd / 2;
1336  } else {
1337  pcb->ssthresh = pcb->cwnd / 2;
1338  }
1339 
1340  /* The minimum value for ssthresh should be 2 MSS */
1341  if (pcb->ssthresh < 2*pcb->mss) {
1343  ("tcp_receive: The minimum value for ssthresh %"U16_F
1344  " should be min 2 mss %"U16_F"...\n",
1345  pcb->ssthresh, 2*pcb->mss));
1346  pcb->ssthresh = 2*pcb->mss;
1347  }
1348 
1349  pcb->cwnd = pcb->ssthresh + 3 * pcb->mss;
1350  pcb->flags |= TF_INFR;
1351  }
1352 }
1353 
1354 
1363 void
1364 tcp_keepalive(struct tcp_pcb *pcb)
1365 {
1366  struct pbuf *p;
1367  struct tcp_hdr *tcphdr;
1368 
1369  LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: sending KEEPALIVE probe to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
1370  ip4_addr1_16(&pcb->remote_ip), ip4_addr2_16(&pcb->remote_ip),
1371  ip4_addr3_16(&pcb->remote_ip), ip4_addr4_16(&pcb->remote_ip)));
1372 
1373  LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: tcp_ticks %"U32_F" pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n",
1374  tcp_ticks, pcb->tmr, pcb->keep_cnt_sent));
1375 
1376  p = tcp_output_alloc_header(pcb, 0, 0, htonl(pcb->snd_nxt - 1));
1377  if(p == NULL) {
1379  ("tcp_keepalive: could not allocate memory for pbuf\n"));
1380  return;
1381  }
1382  tcphdr = (struct tcp_hdr *)p->payload;
1383 
1384 #if CHECKSUM_GEN_TCP
1385  tcphdr->chksum = inet_chksum_pseudo(p, &pcb->local_ip, &pcb->remote_ip,
1386  IP_PROTO_TCP, p->tot_len);
1387 #endif
1388  TCP_STATS_INC(tcp.xmit);
1389 
1390  /* Send output to IP */
1391 #if LWIP_NETIF_HWADDRHINT
1392  ip_output_hinted(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP,
1393  &(pcb->addr_hint));
1394 #else /* LWIP_NETIF_HWADDRHINT*/
1395  ip_output(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP);
1396 #endif /* LWIP_NETIF_HWADDRHINT*/
1397 
1398  pbuf_free(p);
1399 
1400  LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: seqno %"U32_F" ackno %"U32_F".\n",
1401  pcb->snd_nxt - 1, pcb->rcv_nxt));
1402 }
1403 
1404 
1413 void
1414 tcp_zero_window_probe(struct tcp_pcb *pcb)
1415 {
1416  struct pbuf *p;
1417  struct tcp_hdr *tcphdr;
1418  struct tcp_seg *seg;
1419  u16_t len;
1420  u8_t is_fin;
1421 
1423  ("tcp_zero_window_probe: sending ZERO WINDOW probe to %"
1424  U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
1425  ip4_addr1_16(&pcb->remote_ip), ip4_addr2_16(&pcb->remote_ip),
1426  ip4_addr3_16(&pcb->remote_ip), ip4_addr4_16(&pcb->remote_ip)));
1427 
1429  ("tcp_zero_window_probe: tcp_ticks %"U32_F
1430  " pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n",
1431  tcp_ticks, pcb->tmr, pcb->keep_cnt_sent));
1432 
1433  seg = pcb->unacked;
1434 
1435  if(seg == NULL) {
1436  seg = pcb->unsent;
1437  }
1438  if(seg == NULL) {
1439  return;
1440  }
1441 
1442  is_fin = ((TCPH_FLAGS(seg->tcphdr) & TCP_FIN) != 0) && (seg->len == 0);
1443  /* we want to send one seqno: either FIN or data (no options) */
1444  len = is_fin ? 0 : 1;
1445 
1446  p = tcp_output_alloc_header(pcb, 0, len, seg->tcphdr->seqno);
1447  if(p == NULL) {
1448  LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: no memory for pbuf\n"));
1449  return;
1450  }
1451  tcphdr = (struct tcp_hdr *)p->payload;
1452 
1453  if (is_fin) {
1454  /* FIN segment, no data */
1455  TCPH_FLAGS_SET(tcphdr, TCP_ACK | TCP_FIN);
1456  } else {
1457  /* Data segment, copy in one byte from the head of the unacked queue */
1458  char *d = ((char *)p->payload + TCP_HLEN);
1459  /* Depending on whether the segment has already been sent (unacked) or not
1460  (unsent), seg->p->payload points to the IP header or TCP header.
1461  Ensure we copy the first TCP data byte: */
1462  pbuf_copy_partial(seg->p, d, 1, seg->p->tot_len - seg->len);
1463  }
1464 
1465 #if CHECKSUM_GEN_TCP
1466  tcphdr->chksum = inet_chksum_pseudo(p, &pcb->local_ip, &pcb->remote_ip,
1467  IP_PROTO_TCP, p->tot_len);
1468 #endif
1469  TCP_STATS_INC(tcp.xmit);
1470 
1471  /* Send output to IP */
1472 #if LWIP_NETIF_HWADDRHINT
1473  ip_output_hinted(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP,
1474  &(pcb->addr_hint));
1475 #else /* LWIP_NETIF_HWADDRHINT*/
1476  ip_output(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP);
1477 #endif /* LWIP_NETIF_HWADDRHINT*/
1478 
1479  pbuf_free(p);
1480 
1481  LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: seqno %"U32_F
1482  " ackno %"U32_F".\n",
1483  pcb->snd_nxt - 1, pcb->rcv_nxt));
1484 }
1485 #endif /* LWIP_TCP */
#define PP_HTONL(x)
Definition: def.h:90
#define CHECKSUM_GEN_TCP
Definition: opt.h:1805
#define ERR_CONN
Definition: err.h:68
u16_t tot_len
Definition: pbuf.h:93
#define ERR_ARG
Definition: err.h:70
#define ip_addr_copy(dest, src)
Definition: ip_addr.h:162
FxIoQueue * queue
#define TCP_QLEN_DEBUG
Definition: opt.h:2067
#define MEM_ALIGNMENT
Definition: d3d9_helpers.c:15
u32_t sys_now(void)
Definition: sys_arch.c:28
#define S16_F
Definition: cc.h:37
struct pbuf * tcp_create_segment(ip_addr_t *src_ip, ip_addr_t *dst_ip, u16_t src_port, u16_t dst_port, void *data, size_t data_len, u32_t seqno, u32_t ackno, u8_t headerflags)
Definition: tcp_helper.c:105
#define TCP_DEBUG
Definition: tcpcore.h:1815
u8_t pbuf_header(struct pbuf *p, s16_t header_size_increment)
Definition: pbuf.c:511
#define U32_F
Definition: cc.h:39
u16_t inet_chksum_pseudo(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, u8_t proto, u16_t proto_len)
Definition: inet_chksum.c:272
#define ip4_addr1_16(ipaddr)
Definition: ip_addr.h:226
#define TCP_CWND_DEBUG
Definition: opt.h:2039
typedefPACK_STRUCT_END struct ip_addr ip_addr_t
Definition: ip_addr.h:64
if(dx==0 &&dy==0)
Definition: linetemp.h:174
int const JOCTET unsigned int datalen
Definition: jpeglib.h:1030
#define TCP_RTO_DEBUG
Definition: opt.h:2032
#define htonl(x)
Definition: module.h:212
#define LWIP_ASSERT(message, assertion)
Definition: debug.h:66
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
Definition: pbuf.c:207
void tcp_send_fin(struct sock *sk)
Definition: pbuf.h:58
struct netif * ip_route(ip_addr_t *dest)
Definition: ip.c:124
#define TCP_OUTPUT_DEBUG
Definition: opt.h:2053
#define LWIP_DBG_LEVEL_SEVERE
Definition: debug.h:48
#define TCP_STATS_INC(x)
Definition: stats.h:171
#define IP_PROTO_TCP
Definition: ip.h:56
#define snmp_inc_tcpretranssegs()
Definition: snmp.h:317
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
#define LWIP_MIN(x, y)
Definition: def.h:44
#define TCP_WND
Definition: opt.h:923
#define TCP_TTL
Definition: opt.h:915
Definition: _queue.h:59
u8_t pbuf_free(struct pbuf *p)
Definition: pbuf.c:618
Definition: pbuf.h:54
s8_t err_t
Definition: err.h:47
#define LWIP_DEBUGF(debug, message)
Definition: debug.h:95
#define PP_HTONS(x)
Definition: def.h:88
#define ip4_addr2_16(ipaddr)
Definition: ip_addr.h:227
u16_t inet_chksum(void *dataptr, u16_t len)
Definition: inet_chksum.c:396
#define U16_F
Definition: cc.h:36
#define snmp_inc_tcpoutsegs()
Definition: snmp.h:316
#define LWIP_MEM_ALIGN_SIZE(size)
Definition: mem.h:101
#define ERR_OK
Definition: err.h:52
GLenum GLuint GLint GLint layer
Definition: glext.h:7007
Definition: pbuf.h:79
unsigned long u32_t
Definition: cc.h:25
#define SWAP_BYTES_IN_WORD(w)
Definition: inet_chksum.h:47
#define FOLD_U32T(u)
Definition: inet_chksum.h:53
#define X16_F
Definition: cc.h:38
Definition: netif.h:136
GLint left
Definition: glext.h:7726
Definition: pbuf.h:59
#define TCP_OVERSIZE
Definition: opt.h:1053
GLbitfield flags
Definition: glext.h:7161
Definition: tcpdef.h:22
#define TCP_FR_DEBUG
Definition: opt.h:2024
ip_addr_t ip_addr
Definition: netif.h:141
#define LWIP_DBG_LEVEL_WARNING
Definition: debug.h:46
#define ip4_addr3_16(ipaddr)
Definition: ip_addr.h:228
static const WCHAR space[]
Definition: ConsoleCP.c:24
GLenum GLsizei len
Definition: glext.h:6722
#define err(...)
ULONG_PTR mem_ptr_t
Definition: cc.h:33
err_t ip_output(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, u8_t ttl, u8_t tos, u8_t proto)
Definition: ip.c:818
#define ip4_addr4_16(ipaddr)
Definition: ip_addr.h:229
u16_t pbuf_copy_partial(struct pbuf *buf, void *dataptr, u16_t len, u16_t offset)
Definition: pbuf.c:918
u8_t pbuf_clen(struct pbuf *p)
Definition: pbuf.c:704
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define LWIP_ERROR(message, expression, handler)
Definition: debug.h:74
static u32_t chksum(void *dataptr, u16_t len)
Definition: inet6.c:55
#define htons(x)
Definition: module.h:213
#define ip_addr_isany(addr1)
Definition: ip_addr.h:200
#define ERR_MEM
Definition: fontsub.h:52
struct define * next
Definition: compiler.c:65
void pbuf_cat(struct pbuf *h, struct pbuf *t)
Definition: pbuf.c:745
#define ERR_BUF
Definition: err.h:54
unsigned char u8_t
Definition: cc.h:23
#define LWIP_DBG_TRACE
Definition: debug.h:57
#define alloc
Definition: rosglue.h:13
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)
Definition: inet_chksum.c:332
#define NULL
Definition: types.h:112
#define TCP_MSS
Definition: opt.h:956
#define ntohl(x)
Definition: module.h:203
void * payload
Definition: pbuf.h:84
#define LWIP_DBG_STATE
Definition: debug.h:59
Definition: pbuf.h:52
#define TCP_RST_DEBUG
Definition: opt.h:2060
__u16 dest
Definition: tcpdef.h:24
#define TCP_SND_QUEUELEN
Definition: opt.h:985
unsigned short u16_t
Definition: cc.h:24
pbuf_layer
Definition: pbuf.h:50
void * memp_malloc(memp_t type)
Definition: memp.c:390
GLfloat GLfloat p
Definition: glext.h:8902
#define LWIP_UNUSED_ARG(x)
Definition: arch.h:73
#define snmp_inc_tcpoutrsts()
Definition: snmp.h:319
#define d
Definition: ke_i.h:81
signed short s16_t
Definition: cc.h:29