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