]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/ankh/lib/lwip/lib/contrib/src/core/tcp_out.c
update
[l4.git] / l4 / pkg / ankh / lib / lwip / lib / contrib / src / core / tcp_out.c
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/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 #include "lwip/ip6.h"
55 #include "lwip/ip6_addr.h"
56 #include "lwip/inet_chksum.h"
57 #if LWIP_TCP_TIMESTAMPS
58 #include "lwip/sys.h"
59 #endif
60
61 #include <string.h>
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 *
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 *
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 *
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
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  */
295 static err_t
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 :
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) {
477           LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2,
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) {
492           LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2,
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
779   LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_TRACE,
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 #if LWIP_TCP_TIMESTAMPS
820 /* Build a timestamp option (12 bytes long) at the specified options pointer)
821  *
822  * @param pcb tcp_pcb
823  * @param opts option pointer where to store the timestamp option
824  */
825 static void
826 tcp_build_timestamp_option(struct tcp_pcb *pcb, u32_t *opts)
827 {
828   /* Pad with two NOP options to make everything nicely aligned */
829   opts[0] = PP_HTONL(0x0101080A);
830   opts[1] = htonl(sys_now());
831   opts[2] = htonl(pcb->ts_recent);
832 }
833 #endif
834
835 /** Send an ACK without data.
836  *
837  * @param pcb Protocol control block for the TCP connection to send the ACK
838  */
839 err_t
840 tcp_send_empty_ack(struct tcp_pcb *pcb)
841 {
842   struct pbuf *p;
843   struct tcp_hdr *tcphdr;
844   u8_t optlen = 0;
845
846 #if LWIP_TCP_TIMESTAMPS
847   if (pcb->flags & TF_TIMESTAMP) {
848     optlen = LWIP_TCP_OPT_LENGTH(TF_SEG_OPTS_TS);
849   }
850 #endif
851
852   p = tcp_output_alloc_header(pcb, optlen, 0, htonl(pcb->snd_nxt));
853   if (p == NULL) {
854     LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: (ACK) could not allocate pbuf\n"));
855     return ERR_BUF;
856   }
857   tcphdr = (struct tcp_hdr *)p->payload;
858   LWIP_DEBUGF(TCP_OUTPUT_DEBUG, 
859               ("tcp_output: sending ACK for %"U32_F"\n", pcb->rcv_nxt));
860   /* remove ACK flags from the PCB, as we send an empty ACK now */
861   pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
862
863   /* NB. MSS option is only sent on SYNs, so ignore it here */
864 #if LWIP_TCP_TIMESTAMPS
865   pcb->ts_lastacksent = pcb->rcv_nxt;
866
867   if (pcb->flags & TF_TIMESTAMP) {
868     tcp_build_timestamp_option(pcb, (u32_t *)(tcphdr + 1));
869   }
870 #endif 
871
872 #if CHECKSUM_GEN_TCP
873   tcphdr->chksum = ipX_chksum_pseudo(PCB_ISIPV6(pcb), p, IP_PROTO_TCP, p->tot_len,
874     &pcb->local_ip, &pcb->remote_ip);
875 #endif
876 #if LWIP_NETIF_HWADDRHINT
877   ipX_output_hinted(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, pcb->tos,
878       IP_PROTO_TCP, &pcb->addr_hint);
879 #else /* LWIP_NETIF_HWADDRHINT*/
880   ipX_output(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, pcb->tos,
881       IP_PROTO_TCP);
882 #endif /* LWIP_NETIF_HWADDRHINT*/
883   pbuf_free(p);
884
885   return ERR_OK;
886 }
887
888 /**
889  * Find out what we can send and send it
890  *
891  * @param pcb Protocol control block for the TCP connection to send data
892  * @return ERR_OK if data has been sent or nothing to send
893  *         another err_t on error
894  */
895 err_t
896 tcp_output(struct tcp_pcb *pcb)
897 {
898   struct tcp_seg *seg, *useg;
899   u32_t wnd, snd_nxt;
900 #if TCP_CWND_DEBUG
901   s16_t i = 0;
902 #endif /* TCP_CWND_DEBUG */
903
904   /* pcb->state LISTEN not allowed here */
905   LWIP_ASSERT("don't call tcp_output for listen-pcbs",
906     pcb->state != LISTEN);
907
908   /* First, check if we are invoked by the TCP input processing
909      code. If so, we do not output anything. Instead, we rely on the
910      input processing code to call us when input processing is done
911      with. */
912   if (tcp_input_pcb == pcb) {
913     return ERR_OK;
914   }
915
916   wnd = LWIP_MIN(pcb->snd_wnd, pcb->cwnd);
917
918   seg = pcb->unsent;
919
920   /* If the TF_ACK_NOW flag is set and no data will be sent (either
921    * because the ->unsent queue is empty or because the window does
922    * not allow it), construct an empty ACK segment and send it.
923    *
924    * If data is to be sent, we will just piggyback the ACK (see below).
925    */
926   if (pcb->flags & TF_ACK_NOW &&
927      (seg == NULL ||
928       ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len > wnd)) {
929      return tcp_send_empty_ack(pcb);
930   }
931
932   /* useg should point to last segment on unacked queue */
933   useg = pcb->unacked;
934   if (useg != NULL) {
935     for (; useg->next != NULL; useg = useg->next);
936   }
937
938 #if TCP_OUTPUT_DEBUG
939   if (seg == NULL) {
940     LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: nothing to send (%p)\n",
941                                    (void*)pcb->unsent));
942   }
943 #endif /* TCP_OUTPUT_DEBUG */
944 #if TCP_CWND_DEBUG
945   if (seg == NULL) {
946     LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"U16_F
947                                  ", cwnd %"U16_F", wnd %"U32_F
948                                  ", seg == NULL, ack %"U32_F"\n",
949                                  pcb->snd_wnd, pcb->cwnd, wnd, pcb->lastack));
950   } else {
951     LWIP_DEBUGF(TCP_CWND_DEBUG, 
952                 ("tcp_output: snd_wnd %"U16_F", cwnd %"U16_F", wnd %"U32_F
953                  ", effwnd %"U32_F", seq %"U32_F", ack %"U32_F"\n",
954                  pcb->snd_wnd, pcb->cwnd, wnd,
955                  ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len,
956                  ntohl(seg->tcphdr->seqno), pcb->lastack));
957   }
958 #endif /* TCP_CWND_DEBUG */
959   /* data available and window allows it to be sent? */
960   while (seg != NULL &&
961          ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) {
962     LWIP_ASSERT("RST not expected here!", 
963                 (TCPH_FLAGS(seg->tcphdr) & TCP_RST) == 0);
964     /* Stop sending if the nagle algorithm would prevent it
965      * Don't stop:
966      * - if tcp_write had a memory error before (prevent delayed ACK timeout) or
967      * - if FIN was already enqueued for this PCB (SYN is always alone in a segment -
968      *   either seg->next != NULL or pcb->unacked == NULL;
969      *   RST is no sent using tcp_write/tcp_output.
970      */
971     if((tcp_do_output_nagle(pcb) == 0) &&
972       ((pcb->flags & (TF_NAGLEMEMERR | TF_FIN)) == 0)){
973       break;
974     }
975 #if TCP_CWND_DEBUG
976     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",
977                             pcb->snd_wnd, pcb->cwnd, wnd,
978                             ntohl(seg->tcphdr->seqno) + seg->len -
979                             pcb->lastack,
980                             ntohl(seg->tcphdr->seqno), pcb->lastack, i));
981     ++i;
982 #endif /* TCP_CWND_DEBUG */
983
984     pcb->unsent = seg->next;
985
986     if (pcb->state != SYN_SENT) {
987       TCPH_SET_FLAG(seg->tcphdr, TCP_ACK);
988       pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
989     }
990
991     tcp_output_segment(seg, pcb);
992     snd_nxt = ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg);
993     if (TCP_SEQ_LT(pcb->snd_nxt, snd_nxt)) {
994       pcb->snd_nxt = snd_nxt;
995     }
996     /* put segment on unacknowledged list if length > 0 */
997     if (TCP_TCPLEN(seg) > 0) {
998       seg->next = NULL;
999       /* unacked list is empty? */
1000       if (pcb->unacked == NULL) {
1001         pcb->unacked = seg;
1002         useg = seg;
1003       /* unacked list is not empty? */
1004       } else {
1005         /* In the case of fast retransmit, the packet should not go to the tail
1006          * of the unacked queue, but rather somewhere before it. We need to check for
1007          * this case. -STJ Jul 27, 2004 */
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 {
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   if (seg != NULL && pcb->persist_backoff == 0 && 
1037       ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len > pcb->snd_wnd) {
1038     /* prepare for persist timer */
1039     pcb->persist_cnt = 0;
1040     pcb->persist_backoff = 1;
1041   }
1042
1043   pcb->flags &= ~TF_NAGLEMEMERR;
1044   return ERR_OK;
1045 }
1046
1047 /**
1048  * Called by tcp_output() to actually send a TCP segment over IP.
1049  *
1050  * @param seg the tcp_seg to send
1051  * @param pcb the tcp_pcb for the TCP connection used to send the segment
1052  */
1053 static void
1054 tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb)
1055 {
1056   u16_t len;
1057   u32_t *opts;
1058
1059   /** @bug Exclude retransmitted segments from this count. */
1060   snmp_inc_tcpoutsegs();
1061
1062   /* The TCP header has already been constructed, but the ackno and
1063    wnd fields remain. */
1064   seg->tcphdr->ackno = htonl(pcb->rcv_nxt);
1065
1066   /* advertise our receive window size in this TCP segment */
1067   seg->tcphdr->wnd = htons(pcb->rcv_ann_wnd);
1068
1069   pcb->rcv_ann_right_edge = pcb->rcv_nxt + pcb->rcv_ann_wnd;
1070
1071   /* Add any requested options.  NB MSS option is only set on SYN
1072      packets, so ignore it here */
1073   LWIP_ASSERT("seg->tcphdr not aligned", ((mem_ptr_t)seg->tcphdr % MEM_ALIGNMENT) == 0);
1074   opts = (u32_t *)(void *)(seg->tcphdr + 1);
1075   if (seg->flags & TF_SEG_OPTS_MSS) {
1076     TCP_BUILD_MSS_OPTION(*opts);
1077     opts += 1;
1078   }
1079 #if LWIP_TCP_TIMESTAMPS
1080   pcb->ts_lastacksent = pcb->rcv_nxt;
1081
1082   if (seg->flags & TF_SEG_OPTS_TS) {
1083     tcp_build_timestamp_option(pcb, opts);
1084     opts += 3;
1085   }
1086 #endif
1087
1088   /* Set retransmission timer running if it is not currently enabled 
1089      This must be set before checking the route. */
1090   if (pcb->rtime == -1) {
1091     pcb->rtime = 0;
1092   }
1093
1094   /* If we don't have a local IP address, we get one by
1095      calling ip_route(). */
1096   if (ipX_addr_isany(PCB_ISIPV6(pcb), &pcb->local_ip)) {
1097     struct netif *netif;
1098     ipX_addr_t *local_ip;
1099     ipX_route_get_local_ipX(PCB_ISIPV6(pcb), &pcb->local_ip, &pcb->remote_ip, netif, local_ip);
1100     if ((netif == NULL) || (local_ip == NULL)) {
1101       return;
1102     }
1103     ipX_addr_copy(PCB_ISIPV6(pcb), pcb->local_ip, *local_ip);
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 TCP_CHECKSUM_ON_COPY
1125   {
1126     u32_t acc;
1127 #if TCP_CHECKSUM_ON_COPY_SANITY_CHECK
1128     u16_t chksum_slow = ipX_chksum_pseudo(PCB_ISIPV6(pcb), seg->p, IP_PROTO_TCP,
1129       seg->p->tot_len, &pcb->local_ip, &pcb->remote_ip);
1130 #endif /* TCP_CHECKSUM_ON_COPY_SANITY_CHECK */
1131     if ((seg->flags & TF_SEG_DATA_CHECKSUMMED) == 0) {
1132       LWIP_ASSERT("data included but not checksummed",
1133         seg->p->tot_len == (TCPH_HDRLEN(seg->tcphdr) * 4));
1134     }
1135
1136     /* rebuild TCP header checksum (TCP header changes for retransmissions!) */
1137     acc = ipX_chksum_pseudo_partial(PCB_ISIPV6(pcb), seg->p, IP_PROTO_TCP,
1138       seg->p->tot_len, TCPH_HDRLEN(seg->tcphdr) * 4, &pcb->local_ip, &pcb->remote_ip);
1139     /* add payload checksum */
1140     if (seg->chksum_swapped) {
1141       seg->chksum = SWAP_BYTES_IN_WORD(seg->chksum);
1142       seg->chksum_swapped = 0;
1143     }
1144     acc += (u16_t)~(seg->chksum);
1145     seg->tcphdr->chksum = FOLD_U32T(acc);
1146 #if TCP_CHECKSUM_ON_COPY_SANITY_CHECK
1147     if (chksum_slow != seg->tcphdr->chksum) {
1148       LWIP_DEBUGF(TCP_DEBUG | LWIP_DBG_LEVEL_WARNING,
1149                   ("tcp_output_segment: calculated checksum is %"X16_F" instead of %"X16_F"\n",
1150                   seg->tcphdr->chksum, chksum_slow));
1151       seg->tcphdr->chksum = chksum_slow;
1152     }
1153 #endif /* TCP_CHECKSUM_ON_COPY_SANITY_CHECK */
1154   }
1155 #else /* TCP_CHECKSUM_ON_COPY */
1156 #if CHECKSUM_GEN_TCP
1157   seg->tcphdr->chksum = ipX_chksum_pseudo(PCB_ISIPV6(pcb), seg->p, IP_PROTO_TCP,
1158     seg->p->tot_len, &pcb->local_ip, &pcb->remote_ip);
1159 #endif /* CHECKSUM_GEN_TCP */
1160 #endif /* TCP_CHECKSUM_ON_COPY */
1161   TCP_STATS_INC(tcp.xmit);
1162
1163 #if LWIP_NETIF_HWADDRHINT
1164   ipX_output_hinted(PCB_ISIPV6(pcb), seg->p, &pcb->local_ip, &pcb->remote_ip,
1165     pcb->ttl, pcb->tos, IP_PROTO_TCP, &pcb->addr_hint);
1166 #else /* LWIP_NETIF_HWADDRHINT*/
1167   ipX_output(PCB_ISIPV6(pcb), seg->p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl,
1168     pcb->tos, IP_PROTO_TCP);
1169 #endif /* LWIP_NETIF_HWADDRHINT*/
1170 }
1171
1172 /**
1173  * Send a TCP RESET packet (empty segment with RST flag set) either to
1174  * abort a connection or to show that there is no matching local connection
1175  * for a received segment.
1176  *
1177  * Called by tcp_abort() (to abort a local connection), tcp_input() (if no
1178  * matching local pcb was found), tcp_listen_input() (if incoming segment
1179  * has ACK flag set) and tcp_process() (received segment in the wrong state)
1180  *
1181  * Since a RST segment is in most cases not sent for an active connection,
1182  * tcp_rst() has a number of arguments that are taken from a tcp_pcb for
1183  * most other segment output functions.
1184  *
1185  * @param seqno the sequence number to use for the outgoing segment
1186  * @param ackno the acknowledge number to use for the outgoing segment
1187  * @param local_ip the local IP address to send the segment from
1188  * @param remote_ip the remote IP address to send the segment to
1189  * @param local_port the local TCP port to send the segment from
1190  * @param remote_port the remote TCP port to send the segment to
1191  */
1192 void
1193 tcp_rst_impl(u32_t seqno, u32_t ackno,
1194   ipX_addr_t *local_ip, ipX_addr_t *remote_ip,
1195   u16_t local_port, u16_t remote_port
1196 #if LWIP_IPV6
1197   , u8_t isipv6
1198 #endif /* LWIP_IPV6 */
1199   )
1200 {
1201   struct pbuf *p;
1202   struct tcp_hdr *tcphdr;
1203   p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM);
1204   if (p == NULL) {
1205       LWIP_DEBUGF(TCP_DEBUG, ("tcp_rst: could not allocate memory for pbuf\n"));
1206       return;
1207   }
1208   LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr",
1209               (p->len >= sizeof(struct tcp_hdr)));
1210
1211   tcphdr = (struct tcp_hdr *)p->payload;
1212   tcphdr->src = htons(local_port);
1213   tcphdr->dest = htons(remote_port);
1214   tcphdr->seqno = htonl(seqno);
1215   tcphdr->ackno = htonl(ackno);
1216   TCPH_HDRLEN_FLAGS_SET(tcphdr, TCP_HLEN/4, TCP_RST | TCP_ACK);
1217   tcphdr->wnd = PP_HTONS(TCP_WND);
1218   tcphdr->chksum = 0;
1219   tcphdr->urgp = 0;
1220
1221   TCP_STATS_INC(tcp.xmit);
1222   snmp_inc_tcpoutrsts();
1223
1224 #if CHECKSUM_GEN_TCP
1225   tcphdr->chksum = ipX_chksum_pseudo(isipv6, p, IP_PROTO_TCP, p->tot_len,
1226                                      local_ip, remote_ip);
1227 #endif
1228   /* Send output with hardcoded TTL/HL since we have no access to the pcb */
1229   ipX_output(isipv6, p, local_ip, remote_ip, TCP_TTL, 0, IP_PROTO_TCP);
1230   pbuf_free(p);
1231   LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_rst: seqno %"U32_F" ackno %"U32_F".\n", seqno, ackno));
1232 }
1233
1234 /**
1235  * Requeue all unacked segments for retransmission
1236  *
1237  * Called by tcp_slowtmr() for slow retransmission.
1238  *
1239  * @param pcb the tcp_pcb for which to re-enqueue all unacked segments
1240  */
1241 void
1242 tcp_rexmit_rto(struct tcp_pcb *pcb)
1243 {
1244   struct tcp_seg *seg;
1245
1246   if (pcb->unacked == NULL) {
1247     return;
1248   }
1249
1250   /* Move all unacked segments to the head of the unsent queue */
1251   for (seg = pcb->unacked; seg->next != NULL; seg = seg->next);
1252   /* concatenate unsent queue after unacked queue */
1253   seg->next = pcb->unsent;
1254   /* unsent queue is the concatenated queue (of unacked, unsent) */
1255   pcb->unsent = pcb->unacked;
1256   /* unacked queue is now empty */
1257   pcb->unacked = NULL;
1258
1259   /* increment number of retransmissions */
1260   ++pcb->nrtx;
1261
1262   /* Don't take any RTT measurements after retransmitting. */
1263   pcb->rttest = 0;
1264
1265   /* Do the actual retransmission */
1266   tcp_output(pcb);
1267 }
1268
1269 /**
1270  * Requeue the first unacked segment for retransmission
1271  *
1272  * Called by tcp_receive() for fast retramsmit.
1273  *
1274  * @param pcb the tcp_pcb for which to retransmit the first unacked segment
1275  */
1276 void
1277 tcp_rexmit(struct tcp_pcb *pcb)
1278 {
1279   struct tcp_seg *seg;
1280   struct tcp_seg **cur_seg;
1281
1282   if (pcb->unacked == NULL) {
1283     return;
1284   }
1285
1286   /* Move the first unacked segment to the unsent queue */
1287   /* Keep the unsent queue sorted. */
1288   seg = pcb->unacked;
1289   pcb->unacked = seg->next;
1290
1291   cur_seg = &(pcb->unsent);
1292   while (*cur_seg &&
1293     TCP_SEQ_LT(ntohl((*cur_seg)->tcphdr->seqno), ntohl(seg->tcphdr->seqno))) {
1294       cur_seg = &((*cur_seg)->next );
1295   }
1296   seg->next = *cur_seg;
1297   *cur_seg = seg;
1298
1299   ++pcb->nrtx;
1300
1301   /* Don't take any rtt measurements after retransmitting. */
1302   pcb->rttest = 0;
1303
1304   /* Do the actual retransmission. */
1305   snmp_inc_tcpretranssegs();
1306   /* No need to call tcp_output: we are always called from tcp_input()
1307      and thus tcp_output directly returns. */
1308 }
1309
1310
1311 /**
1312  * Handle retransmission after three dupacks received
1313  *
1314  * @param pcb the tcp_pcb for which to retransmit the first unacked segment
1315  */
1316 void 
1317 tcp_rexmit_fast(struct tcp_pcb *pcb)
1318 {
1319   if (pcb->unacked != NULL && !(pcb->flags & TF_INFR)) {
1320     /* This is fast retransmit. Retransmit the first unacked segment. */
1321     LWIP_DEBUGF(TCP_FR_DEBUG, 
1322                 ("tcp_receive: dupacks %"U16_F" (%"U32_F
1323                  "), fast retransmit %"U32_F"\n",
1324                  (u16_t)pcb->dupacks, pcb->lastack,
1325                  ntohl(pcb->unacked->tcphdr->seqno)));
1326     tcp_rexmit(pcb);
1327
1328     /* Set ssthresh to half of the minimum of the current
1329      * cwnd and the advertised window */
1330     if (pcb->cwnd > pcb->snd_wnd) {
1331       pcb->ssthresh = pcb->snd_wnd / 2;
1332     } else {
1333       pcb->ssthresh = pcb->cwnd / 2;
1334     }
1335     
1336     /* The minimum value for ssthresh should be 2 MSS */
1337     if (pcb->ssthresh < 2*pcb->mss) {
1338       LWIP_DEBUGF(TCP_FR_DEBUG, 
1339                   ("tcp_receive: The minimum value for ssthresh %"U16_F
1340                    " should be min 2 mss %"U16_F"...\n",
1341                    pcb->ssthresh, 2*pcb->mss));
1342       pcb->ssthresh = 2*pcb->mss;
1343     }
1344     
1345     pcb->cwnd = pcb->ssthresh + 3 * pcb->mss;
1346     pcb->flags |= TF_INFR;
1347   } 
1348 }
1349
1350
1351 /**
1352  * Send keepalive packets to keep a connection active although
1353  * no data is sent over it.
1354  *
1355  * Called by tcp_slowtmr()
1356  *
1357  * @param pcb the tcp_pcb for which to send a keepalive packet
1358  */
1359 void
1360 tcp_keepalive(struct tcp_pcb *pcb)
1361 {
1362   struct pbuf *p;
1363   struct tcp_hdr *tcphdr;
1364
1365   LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: sending KEEPALIVE probe to "));
1366   ipX_addr_debug_print(PCB_ISIPV6(pcb), TCP_DEBUG, &pcb->remote_ip);
1367   LWIP_DEBUGF(TCP_DEBUG, ("\n"));
1368
1369   LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: tcp_ticks %"U32_F"   pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n", 
1370                           tcp_ticks, pcb->tmr, pcb->keep_cnt_sent));
1371    
1372   p = tcp_output_alloc_header(pcb, 0, 0, htonl(pcb->snd_nxt - 1));
1373   if(p == NULL) {
1374     LWIP_DEBUGF(TCP_DEBUG, 
1375                 ("tcp_keepalive: could not allocate memory for pbuf\n"));
1376     return;
1377   }
1378   tcphdr = (struct tcp_hdr *)p->payload;
1379
1380   tcphdr->chksum = ipX_chksum_pseudo(PCB_ISIPV6(pcb), p, IP_PROTO_TCP, p->tot_len,
1381       &pcb->local_ip, &pcb->remote_ip);
1382   TCP_STATS_INC(tcp.xmit);
1383
1384   /* Send output to IP */
1385 #if LWIP_NETIF_HWADDRHINT
1386   ipX_output_hinted(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip,
1387     pcb->ttl, 0, IP_PROTO_TCP, &pcb->addr_hint);
1388 #else /* LWIP_NETIF_HWADDRHINT*/
1389   ipX_output(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl,
1390     0, IP_PROTO_TCP);
1391 #endif /* LWIP_NETIF_HWADDRHINT*/
1392
1393   pbuf_free(p);
1394
1395   LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: seqno %"U32_F" ackno %"U32_F".\n",
1396                           pcb->snd_nxt - 1, pcb->rcv_nxt));
1397 }
1398
1399
1400 /**
1401  * Send persist timer zero-window probes to keep a connection active
1402  * when a window update is lost.
1403  *
1404  * Called by tcp_slowtmr()
1405  *
1406  * @param pcb the tcp_pcb for which to send a zero-window probe packet
1407  */
1408 void
1409 tcp_zero_window_probe(struct tcp_pcb *pcb)
1410 {
1411   struct pbuf *p;
1412   struct tcp_hdr *tcphdr;
1413   struct tcp_seg *seg;
1414   u16_t len;
1415   u8_t is_fin;
1416
1417   LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: sending ZERO WINDOW probe to "));
1418   ipX_addr_debug_print(PCB_ISIPV6(pcb), TCP_DEBUG, &pcb->remote_ip);
1419   LWIP_DEBUGF(TCP_DEBUG, ("\n"));
1420
1421   LWIP_DEBUGF(TCP_DEBUG, 
1422               ("tcp_zero_window_probe: tcp_ticks %"U32_F
1423                "   pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n", 
1424                tcp_ticks, pcb->tmr, pcb->keep_cnt_sent));
1425
1426   seg = pcb->unacked;
1427
1428   if(seg == NULL) {
1429     seg = pcb->unsent;
1430   }
1431   if(seg == NULL) {
1432     return;
1433   }
1434
1435   is_fin = ((TCPH_FLAGS(seg->tcphdr) & TCP_FIN) != 0) && (seg->len == 0);
1436   /* we want to send one seqno: either FIN or data (no options) */
1437   len = is_fin ? 0 : 1;
1438
1439   p = tcp_output_alloc_header(pcb, 0, len, seg->tcphdr->seqno);
1440   if(p == NULL) {
1441     LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: no memory for pbuf\n"));
1442     return;
1443   }
1444   tcphdr = (struct tcp_hdr *)p->payload;
1445
1446   if (is_fin) {
1447     /* FIN segment, no data */
1448     TCPH_FLAGS_SET(tcphdr, TCP_ACK | TCP_FIN);
1449   } else {
1450     /* Data segment, copy in one byte from the head of the unacked queue */
1451     struct tcp_hdr *thdr = (struct tcp_hdr *)seg->p->payload;
1452     char *d = ((char *)p->payload + TCP_HLEN);
1453     pbuf_copy_partial(seg->p, d, 1, TCPH_HDRLEN(thdr) * 4);
1454   }
1455
1456 #if CHECKSUM_GEN_TCP
1457   tcphdr->chksum = ipX_chksum_pseudo(PCB_ISIPV6(pcb), p, IP_PROTO_TCP, p->tot_len,
1458       &pcb->local_ip, &pcb->remote_ip);
1459 #endif
1460   TCP_STATS_INC(tcp.xmit);
1461
1462   /* Send output to IP */
1463 #if LWIP_NETIF_HWADDRHINT
1464   ipX_output_hinted(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl,
1465     0, IP_PROTO_TCP, &pcb->addr_hint);
1466 #else /* LWIP_NETIF_HWADDRHINT*/
1467   ipX_output(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP);
1468 #endif /* LWIP_NETIF_HWADDRHINT*/
1469
1470   pbuf_free(p);
1471
1472   LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: seqno %"U32_F
1473                           " ackno %"U32_F".\n",
1474                           pcb->snd_nxt - 1, pcb->rcv_nxt));
1475 }
1476 #endif /* LWIP_TCP */