Bonjour/Zerconf library

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers tcp_out.c Source File

tcp_out.c

Go to the documentation of this file.
00001 /**
00002  * @file
00003  * Transmission Control Protocol, outgoing traffic
00004  *
00005  * The output functions of TCP.
00006  *
00007  */
00008 
00009 /*
00010  * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
00011  * All rights reserved.
00012  *
00013  * Redistribution and use in source and binary forms, with or without modification,
00014  * are permitted provided that the following conditions are met:
00015  *
00016  * 1. Redistributions of source code must retain the above copyright notice,
00017  *    this list of conditions and the following disclaimer.
00018  * 2. Redistributions in binary form must reproduce the above copyright notice,
00019  *    this list of conditions and the following disclaimer in the documentation
00020  *    and/or other materials provided with the distribution.
00021  * 3. The name of the author may not be used to endorse or promote products
00022  *    derived from this software without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
00025  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00026  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
00027  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00028  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
00029  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00030  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00031  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
00032  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
00033  * OF SUCH DAMAGE.
00034  *
00035  * This file is part of the lwIP TCP/IP stack.
00036  *
00037  * Author: Adam Dunkels <adam@sics.se>
00038  *
00039  */
00040 
00041 #include "lwip/opt.h"
00042 
00043 #if LWIP_TCP /* don't build if not configured for use in lwipopts.h */
00044 
00045 #include "lwip/tcp_impl.h"
00046 #include "lwip/def.h"
00047 #include "lwip/mem.h"
00048 #include "lwip/memp.h"
00049 #include "lwip/sys.h"
00050 #include "lwip/ip_addr.h"
00051 #include "lwip/netif.h"
00052 #include "lwip/inet_chksum.h"
00053 #include "lwip/stats.h"
00054 #include "lwip/snmp.h"
00055 
00056 #include <string.h>
00057 
00058 /* Define some copy-macros for checksum-on-copy so that the code looks
00059    nicer by preventing too many ifdef's. */
00060 #if TCP_CHECKSUM_ON_COPY
00061 #define TCP_DATA_COPY(dst, src, len, seg) do { \
00062   tcp_seg_add_chksum(LWIP_CHKSUM_COPY(dst, src, len), \
00063                      len, &seg->chksum, &seg->chksum_swapped); \
00064   seg->flags |= TF_SEG_DATA_CHECKSUMMED; } while(0)
00065 #define TCP_DATA_COPY2(dst, src, len, chksum, chksum_swapped)  \
00066   tcp_seg_add_chksum(LWIP_CHKSUM_COPY(dst, src, len), len, chksum, chksum_swapped);
00067 #else /* TCP_CHECKSUM_ON_COPY*/
00068 #define TCP_DATA_COPY(dst, src, len, seg)                     MEMCPY(dst, src, len)
00069 #define TCP_DATA_COPY2(dst, src, len, chksum, chksum_swapped) MEMCPY(dst, src, len)
00070 #endif /* TCP_CHECKSUM_ON_COPY*/
00071 
00072 /** Define this to 1 for an extra check that the output checksum is valid
00073  * (usefule when the checksum is generated by the application, not the stack) */
00074 #ifndef TCP_CHECKSUM_ON_COPY_SANITY_CHECK
00075 #define TCP_CHECKSUM_ON_COPY_SANITY_CHECK   0
00076 #endif
00077 
00078 /* Forward declarations.*/
00079 static void tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb);
00080 
00081 /** Allocate a pbuf and create a tcphdr at p->payload, used for output
00082  * functions other than the default tcp_output -> tcp_output_segment
00083  * (e.g. tcp_send_empty_ack, etc.)
00084  *
00085  * @param pcb tcp pcb for which to send a packet (used to initialize tcp_hdr)
00086  * @param optlen length of header-options
00087  * @param datalen length of tcp data to reserve in pbuf
00088  * @param seqno_be seqno in network byte order (big-endian)
00089  * @return pbuf with p->payload being the tcp_hdr
00090  */
00091 static struct pbuf *
00092 tcp_output_alloc_header(struct tcp_pcb *pcb, u16_t optlen, u16_t datalen,
00093                       u32_t seqno_be /* already in network byte order */)
00094 {
00095   struct tcp_hdr *tcphdr;
00096   struct pbuf *p = pbuf_alloc(PBUF_IP, TCP_HLEN + optlen + datalen, PBUF_RAM);
00097   if (p != NULL) {
00098     LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr",
00099                  (p->len >= TCP_HLEN + optlen));
00100     tcphdr = (struct tcp_hdr *)p->payload;
00101     tcphdr->src = htons(pcb->local_port);
00102     tcphdr->dest = htons(pcb->remote_port);
00103     tcphdr->seqno = seqno_be;
00104     tcphdr->ackno = htonl(pcb->rcv_nxt);
00105     TCPH_HDRLEN_FLAGS_SET(tcphdr, (5 + optlen / 4), TCP_ACK);
00106     tcphdr->wnd = htons(pcb->rcv_ann_wnd);
00107     tcphdr->chksum = 0;
00108     tcphdr->urgp = 0;
00109 
00110     /* If we're sending a packet, update the announced right window edge */
00111     pcb->rcv_ann_right_edge = pcb->rcv_nxt + pcb->rcv_ann_wnd;
00112   }
00113   return p;
00114 }
00115 
00116 /**
00117  * Called by tcp_close() to send a segment including FIN flag but not data.
00118  *
00119  * @param pcb the tcp_pcb over which to send a segment
00120  * @return ERR_OK if sent, another err_t otherwise
00121  */
00122 err_t
00123 tcp_send_fin(struct tcp_pcb *pcb)
00124 {
00125   /* first, try to add the fin to the last unsent segment */
00126   if (pcb->unsent != NULL) {
00127     struct tcp_seg *last_unsent;
00128     for (last_unsent = pcb->unsent; last_unsent->next != NULL;
00129          last_unsent = last_unsent->next);
00130 
00131     if ((TCPH_FLAGS(last_unsent->tcphdr) & (TCP_SYN | TCP_FIN | TCP_RST)) == 0) {
00132       /* no SYN/FIN/RST flag in the header, we can add the FIN flag */
00133       TCPH_SET_FLAG(last_unsent->tcphdr, TCP_FIN);
00134       return ERR_OK;
00135     }
00136   }
00137   /* no data, no length, flags, copy=1, no optdata */
00138   return tcp_enqueue_flags(pcb, TCP_FIN);
00139 }
00140 
00141 /**
00142  * Create a TCP segment with prefilled header.
00143  *
00144  * Called by tcp_write and tcp_enqueue_flags.
00145  *
00146  * @param pcb Protocol control block for the TCP connection.
00147  * @param p pbuf that is used to hold the TCP header.
00148  * @param flags TCP flags for header.
00149  * @param seqno TCP sequence number of this packet
00150  * @param optflags options to include in TCP header
00151  * @return a new tcp_seg pointing to p, or NULL.
00152  * The TCP header is filled in except ackno and wnd.
00153  * p is freed on failure.
00154  */
00155 static struct tcp_seg *
00156 tcp_create_segment(struct tcp_pcb *pcb, struct pbuf *p, u8_t flags, u32_t seqno, u8_t optflags)
00157 {
00158   struct tcp_seg *seg;
00159   u8_t optlen = LWIP_TCP_OPT_LENGTH(optflags);
00160 
00161   if ((seg = (struct tcp_seg *)memp_malloc(MEMP_TCP_SEG)) == NULL) {
00162     LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_create_segment: no memory.\n"));
00163     pbuf_free(p);
00164     return NULL;
00165   }
00166   seg->flags = optflags;
00167   seg->next = NULL;
00168   seg->p = p;
00169   seg->dataptr = p->payload;
00170   seg->len = p->tot_len - optlen;
00171 #if TCP_OVERSIZE_DBGCHECK
00172   seg->oversize_left = 0;
00173 #endif /* TCP_OVERSIZE_DBGCHECK */
00174 #if TCP_CHECKSUM_ON_COPY
00175   seg->chksum = 0;
00176   seg->chksum_swapped = 0;
00177   /* check optflags */
00178   LWIP_ASSERT("invalid optflags passed: TF_SEG_DATA_CHECKSUMMED",
00179               (optflags & TF_SEG_DATA_CHECKSUMMED) == 0);
00180 #endif /* TCP_CHECKSUM_ON_COPY */
00181 
00182   /* build TCP header */
00183   if (pbuf_header(p, TCP_HLEN)) {
00184     LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_create_segment: no room for TCP header in pbuf.\n"));
00185     TCP_STATS_INC(tcp.err);
00186     tcp_seg_free(seg);
00187     return NULL;
00188   }
00189   seg->tcphdr = (struct tcp_hdr *)seg->p->payload;
00190   seg->tcphdr->src = htons(pcb->local_port);
00191   seg->tcphdr->dest = htons(pcb->remote_port);
00192   seg->tcphdr->seqno = htonl(seqno);
00193   /* ackno is set in tcp_output */
00194   TCPH_HDRLEN_FLAGS_SET(seg->tcphdr, (5 + optlen / 4), flags);
00195   /* wnd and chksum are set in tcp_output */
00196   seg->tcphdr->urgp = 0;
00197   return seg;
00198 } 
00199 
00200 /**
00201  * Allocate a PBUF_RAM pbuf, perhaps with extra space at the end.
00202  *
00203  * This function is like pbuf_alloc(layer, length, PBUF_RAM) except
00204  * there may be extra bytes available at the end.
00205  *
00206  * @param layer flag to define header size.
00207  * @param length size of the pbuf's payload.
00208  * @param max_length maximum usable size of payload+oversize.
00209  * @param oversize pointer to a u16_t that will receive the number of usable tail bytes.
00210  * @param pcb The TCP connection that willo enqueue the pbuf.
00211  * @param apiflags API flags given to tcp_write.
00212  * @param first_seg true when this pbuf will be used in the first enqueued segment.
00213  * @param 
00214  */
00215 #if TCP_OVERSIZE
00216 static struct pbuf *
00217 tcp_pbuf_prealloc(pbuf_layer layer, u16_t length, u16_t max_length,
00218                   u16_t *oversize, struct tcp_pcb *pcb, u8_t apiflags,
00219                   u8_t first_seg)
00220 {
00221   struct pbuf *p;
00222   u16_t alloc = length;
00223 
00224   if (length < max_length) {
00225     /* Should we allocate an oversized pbuf, or just the minimum
00226      * length required? If tcp_write is going to be called again
00227      * before this segment is transmitted, we want the oversized
00228      * buffer. If the segment will be transmitted immediately, we can
00229      * save memory by allocating only length. We use a simple
00230      * heuristic based on the following information:
00231      *
00232      * Did the user set TCP_WRITE_FLAG_MORE?
00233      *
00234      * Will the Nagle algorithm defer transmission of this segment?
00235      */
00236     if ((apiflags & TCP_WRITE_FLAG_MORE) ||
00237         (!(pcb->flags & TF_NODELAY) &&
00238          (!first_seg ||
00239           pcb->unsent != NULL ||
00240           pcb->unacked != NULL))) {
00241       alloc = LWIP_MIN(max_length, LWIP_MEM_ALIGN_SIZE(length + TCP_OVERSIZE));
00242     }
00243   }
00244   p = pbuf_alloc(layer, alloc, PBUF_RAM);
00245   if (p == NULL) {
00246     return NULL;
00247   }
00248   LWIP_ASSERT("need unchained pbuf", p->next == NULL);
00249   *oversize = p->len - length;
00250   /* trim p->len to the currently used size */
00251   p->len = p->tot_len = length;
00252   return p;
00253 }
00254 #else /* TCP_OVERSIZE */
00255 #define tcp_pbuf_prealloc(layer, length, mx, os, pcb, api, fst) pbuf_alloc((layer), (length), PBUF_RAM)
00256 #endif /* TCP_OVERSIZE */
00257 
00258 #if TCP_CHECKSUM_ON_COPY
00259 /** Add a checksum of newly added data to the segment */
00260 static void
00261 tcp_seg_add_chksum(u16_t chksum, u16_t len, u16_t *seg_chksum,
00262                    u8_t *seg_chksum_swapped)
00263 {
00264   u32_t helper;
00265   /* add chksum to old chksum and fold to u16_t */
00266   helper = chksum + *seg_chksum;
00267   chksum = FOLD_U32T(helper);
00268   if ((len & 1) != 0) {
00269     *seg_chksum_swapped = 1 - *seg_chksum_swapped;
00270     chksum = SWAP_BYTES_IN_WORD(chksum);
00271   }
00272   *seg_chksum = chksum;
00273 }
00274 #endif /* TCP_CHECKSUM_ON_COPY */
00275 
00276 /**
00277  * Write data for sending (but does not send it immediately).
00278  *
00279  * It waits in the expectation of more data being sent soon (as
00280  * it can send them more efficiently by combining them together).
00281  * To prompt the system to send data now, call tcp_output() after
00282  * calling tcp_write().
00283  *
00284  * @param pcb Protocol control block for the TCP connection to enqueue data for.
00285  * @param arg Pointer to the data to be enqueued for sending.
00286  * @param len Data length in bytes
00287  * @param apiflags combination of following flags :
00288  * - TCP_WRITE_FLAG_COPY (0x01) data will be copied into memory belonging to the stack
00289  * - TCP_WRITE_FLAG_MORE (0x02) for TCP connection, PSH flag will be set on last segment sent,
00290  * @return ERR_OK if enqueued, another err_t on error
00291  */
00292 err_t
00293 tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags)
00294 {
00295   struct pbuf *concat_p = NULL;
00296   struct tcp_seg *last_unsent = NULL, *seg = NULL, *prev_seg = NULL, *queue = NULL;
00297   u16_t pos = 0; /* position in 'arg' data */
00298   u16_t queuelen;
00299   u8_t optlen = 0;
00300   u8_t optflags = 0;
00301 #if TCP_OVERSIZE
00302   u16_t oversize = 0;
00303   u16_t oversize_used = 0;
00304 #endif /* TCP_OVERSIZE */
00305 #if TCP_CHECKSUM_ON_COPY
00306   u16_t concat_chksum = 0;
00307   u8_t concat_chksum_swapped = 0;
00308   u16_t concat_chksummed = 0;
00309 #endif /* TCP_CHECKSUM_ON_COPY */
00310 
00311 #if LWIP_NETIF_TX_SINGLE_PBUF
00312   /* Always copy to try to create single pbufs for TX */
00313   apiflags |= TCP_WRITE_FLAG_COPY;
00314 #endif /* LWIP_NETIF_TX_SINGLE_PBUF */
00315 
00316   LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_write(pcb=%p, data=%p, len=%"U16_F", apiflags=%"U16_F")\n",
00317     (void *)pcb, arg, len, (u16_t)apiflags));
00318   /* connection is in invalid state for data transmission? */
00319   if ((pcb->state != ESTABLISHED) &&
00320       (pcb->state != CLOSE_WAIT) &&
00321       (pcb->state != SYN_SENT) &&
00322       (pcb->state != SYN_RCVD)) {
00323     LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_STATE | LWIP_DBG_LEVEL_SEVERE, ("tcp_write() called in invalid state\n"));
00324     return ERR_CONN;
00325   } else if (len == 0) {
00326     return ERR_OK;
00327   }
00328 
00329   LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_write(pcb=%p, arg=%p, len=%"U16_F", apiflags=%"U16_F")\n",
00330     (void *)pcb, arg, len, (u16_t)apiflags));
00331   LWIP_ERROR("tcp_write: arg == NULL (programmer violates API)", 
00332              arg != NULL, return ERR_ARG;);
00333 
00334   /* fail on too much data */
00335   if (len > pcb->snd_buf) {
00336     LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_write: too much data (len=%"U16_F" > snd_buf=%"U16_F")\n",
00337       len, pcb->snd_buf));
00338     pcb->flags |= TF_NAGLEMEMERR;
00339     return ERR_MEM;
00340   }
00341 
00342   LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_write: queuelen: %"U16_F"\n", (u16_t)pcb->snd_queuelen));
00343 
00344   /* If total number of pbufs on the unsent/unacked queues exceeds the
00345    * configured maximum, return an error */
00346   queuelen = pcb->snd_queuelen;
00347   /* check for configured max queuelen and possible overflow */
00348   if ((queuelen >= TCP_SND_QUEUELEN) || (queuelen > TCP_SNDQUEUELEN_OVERFLOW)) {
00349     LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_write: too long queue %"U16_F" (max %"U16_F")\n",
00350       queuelen, TCP_SND_QUEUELEN));
00351     TCP_STATS_INC(tcp.memerr);
00352     pcb->flags |= TF_NAGLEMEMERR;
00353     return ERR_MEM;
00354   }
00355   if (queuelen != 0) {
00356     LWIP_ASSERT("tcp_write: pbufs on queue => at least one queue non-empty",
00357       pcb->unacked != NULL || pcb->unsent != NULL);
00358   } else {
00359     LWIP_ASSERT("tcp_write: no pbufs on queue => both queues empty",
00360       pcb->unacked == NULL && pcb->unsent == NULL);
00361   }
00362 
00363 #if LWIP_TCP_TIMESTAMPS
00364   if ((pcb->flags & TF_TIMESTAMP)) {
00365     optflags = TF_SEG_OPTS_TS;
00366     optlen = LWIP_TCP_OPT_LENGTH(TF_SEG_OPTS_TS);
00367   }
00368 #endif /* LWIP_TCP_TIMESTAMPS */
00369 
00370 
00371   /*
00372    * TCP segmentation is done in three phases with increasing complexity:
00373    *
00374    * 1. Copy data directly into an oversized pbuf.
00375    * 2. Chain a new pbuf to the end of pcb->unsent.
00376    * 3. Create new segments.
00377    *
00378    * We may run out of memory at any point. In that case we must
00379    * return ERR_MEM and not change anything in pcb. Therefore, all
00380    * changes are recorded in local variables and committed at the end
00381    * of the function. Some pcb fields are maintained in local copies:
00382    *
00383    * queuelen = pcb->snd_queuelen
00384    * oversize = pcb->unsent_oversize
00385    *
00386    * These variables are set consistently by the phases:
00387    *
00388    * seg points to the last segment tampered with.
00389    *
00390    * pos records progress as data is segmented.
00391    */
00392 
00393   /* Find the tail of the unsent queue. */
00394   if (pcb->unsent != NULL) {
00395     u16_t space;
00396     u16_t unsent_optlen;
00397 
00398     /* @todo: this could be sped up by keeping last_unsent in the pcb */
00399     for (last_unsent = pcb->unsent; last_unsent->next != NULL;
00400          last_unsent = last_unsent->next);
00401 
00402     /* Usable space at the end of the last unsent segment */
00403     unsent_optlen = LWIP_TCP_OPT_LENGTH(last_unsent->flags);
00404     space = pcb->mss - (last_unsent->len + unsent_optlen);
00405 
00406     /*
00407      * Phase 1: Copy data directly into an oversized pbuf.
00408      *
00409      * The number of bytes copied is recorded in the oversize_used
00410      * variable. The actual copying is done at the bottom of the
00411      * function.
00412      */
00413 #if TCP_OVERSIZE
00414 #if TCP_OVERSIZE_DBGCHECK
00415     /* check that pcb->unsent_oversize matches last_unsent->unsent_oversize */
00416     LWIP_ASSERT("unsent_oversize mismatch (pcb vs. last_unsent)",
00417                 pcb->unsent_oversize == last_unsent->oversize_left);
00418 #endif /* TCP_OVERSIZE_DBGCHECK */
00419     oversize = pcb->unsent_oversize;
00420     if (oversize > 0) {
00421       LWIP_ASSERT("inconsistent oversize vs. space", oversize_used <= space);
00422       seg = last_unsent;
00423       oversize_used = oversize < len ? oversize : len;
00424       pos += oversize_used;
00425       oversize -= oversize_used;
00426       space -= oversize_used;
00427     }
00428     /* now we are either finished or oversize is zero */
00429     LWIP_ASSERT("inconsistend oversize vs. len", (oversize == 0) || (pos == len));
00430 #endif /* TCP_OVERSIZE */
00431 
00432     /*
00433      * Phase 2: Chain a new pbuf to the end of pcb->unsent.
00434      *
00435      * We don't extend segments containing SYN/FIN flags or options
00436      * (len==0). The new pbuf is kept in concat_p and pbuf_cat'ed at
00437      * the end.
00438      */
00439     if ((pos < len) && (space > 0) && (last_unsent->len > 0)) {
00440       u16_t seglen = space < len - pos ? space : len - pos;
00441       seg = last_unsent;
00442 
00443       /* Create a pbuf with a copy or reference to seglen bytes. We
00444        * can use PBUF_RAW here since the data appears in the middle of
00445        * a segment. A header will never be prepended. */
00446       if (apiflags & TCP_WRITE_FLAG_COPY) {
00447         /* Data is copied */
00448         if ((concat_p = tcp_pbuf_prealloc(PBUF_RAW, seglen, space, &oversize, pcb, apiflags, 1)) == NULL) {
00449           LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2,
00450                       ("tcp_write : could not allocate memory for pbuf copy size %"U16_F"\n",
00451                        seglen));
00452           goto memerr;
00453         }
00454 #if TCP_OVERSIZE_DBGCHECK
00455         last_unsent->oversize_left = oversize;
00456 #endif /* TCP_OVERSIZE_DBGCHECK */
00457         TCP_DATA_COPY2(concat_p->payload, (u8_t*)arg + pos, seglen, &concat_chksum, &concat_chksum_swapped);
00458 #if TCP_CHECKSUM_ON_COPY
00459         concat_chksummed += seglen;
00460 #endif /* TCP_CHECKSUM_ON_COPY */
00461       } else {
00462         /* Data is not copied */
00463         if ((concat_p = pbuf_alloc(PBUF_RAW, seglen, PBUF_ROM)) == NULL) {
00464           LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2,
00465                       ("tcp_write: could not allocate memory for zero-copy pbuf\n"));
00466           goto memerr;
00467         }
00468 #if TCP_CHECKSUM_ON_COPY
00469         /* calculate the checksum of nocopy-data */
00470         tcp_seg_add_chksum(~inet_chksum((u8_t*)arg + pos, seglen), seglen,
00471           &concat_chksum, &concat_chksum_swapped);
00472         concat_chksummed += seglen;
00473 #endif /* TCP_CHECKSUM_ON_COPY */
00474         /* reference the non-volatile payload data */
00475         concat_p->payload = (u8_t*)arg + pos;
00476       }
00477 
00478       pos += seglen;
00479       queuelen += pbuf_clen(concat_p);
00480     }
00481   } else {
00482 #if TCP_OVERSIZE
00483     LWIP_ASSERT("unsent_oversize mismatch (pcb->unsent is NULL)",
00484                 pcb->unsent_oversize == 0);
00485 #endif /* TCP_OVERSIZE */
00486   }
00487 
00488   /*
00489    * Phase 3: Create new segments.
00490    *
00491    * The new segments are chained together in the local 'queue'
00492    * variable, ready to be appended to pcb->unsent.
00493    */
00494   while (pos < len) {
00495     struct pbuf *p;
00496     u16_t left = len - pos;
00497     u16_t max_len = pcb->mss - optlen;
00498     u16_t seglen = left > max_len ? max_len : left;
00499 #if TCP_CHECKSUM_ON_COPY
00500     u16_t chksum = 0;
00501     u8_t chksum_swapped = 0;
00502 #endif /* TCP_CHECKSUM_ON_COPY */
00503 
00504     if (apiflags & TCP_WRITE_FLAG_COPY) {
00505       /* If copy is set, memory should be allocated and data copied
00506        * into pbuf */
00507       if ((p = tcp_pbuf_prealloc(PBUF_TRANSPORT, seglen + optlen, pcb->mss, &oversize, pcb, apiflags, queue == NULL)) == NULL) {
00508         LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_write : could not allocate memory for pbuf copy size %"U16_F"\n", seglen));
00509         goto memerr;
00510       }
00511       LWIP_ASSERT("tcp_write: check that first pbuf can hold the complete seglen",
00512                   (p->len >= seglen));
00513       TCP_DATA_COPY2((char *)p->payload + optlen, (u8_t*)arg + pos, seglen, &chksum, &chksum_swapped);
00514     } else {
00515       /* Copy is not set: First allocate a pbuf for holding the data.
00516        * Since the referenced data is available at least until it is
00517        * sent out on the link (as it has to be ACKed by the remote
00518        * party) we can safely use PBUF_ROM instead of PBUF_REF here.
00519        */
00520       struct pbuf *p2;
00521 #if TCP_OVERSIZE
00522       LWIP_ASSERT("oversize == 0", oversize == 0);
00523 #endif /* TCP_OVERSIZE */
00524       if ((p2 = pbuf_alloc(PBUF_TRANSPORT, seglen, PBUF_ROM)) == NULL) {
00525         LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_write: could not allocate memory for zero-copy pbuf\n"));
00526         goto memerr;
00527       }
00528 #if TCP_CHECKSUM_ON_COPY
00529       /* calculate the checksum of nocopy-data */
00530       chksum = ~inet_chksum((u8_t*)arg + pos, seglen);
00531 #endif /* TCP_CHECKSUM_ON_COPY */
00532       /* reference the non-volatile payload data */
00533       p2->payload = (u8_t*)arg + pos;
00534 
00535       /* Second, allocate a pbuf for the headers. */
00536       if ((p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) {
00537         /* If allocation fails, we have to deallocate the data pbuf as
00538          * well. */
00539         pbuf_free(p2);
00540         LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_write: could not allocate memory for header pbuf\n"));
00541         goto memerr;
00542       }
00543       /* Concatenate the headers and data pbufs together. */
00544       pbuf_cat(p/*header*/, p2/*data*/);
00545     }
00546 
00547     queuelen += pbuf_clen(p);
00548 
00549     /* Now that there are more segments queued, we check again if the
00550      * length of the queue exceeds the configured maximum or
00551      * overflows. */
00552     if ((queuelen > TCP_SND_QUEUELEN) || (queuelen > TCP_SNDQUEUELEN_OVERFLOW)) {
00553       LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_write: queue too long %"U16_F" (%"U16_F")\n", queuelen, TCP_SND_QUEUELEN));
00554       pbuf_free(p);
00555       goto memerr;
00556     }
00557 
00558     if ((seg = tcp_create_segment(pcb, p, 0, pcb->snd_lbb + pos, optflags)) == NULL) {
00559       goto memerr;
00560     }
00561 #if TCP_OVERSIZE_DBGCHECK
00562     seg->oversize_left = oversize;
00563 #endif /* TCP_OVERSIZE_DBGCHECK */
00564 #if TCP_CHECKSUM_ON_COPY
00565     seg->chksum = chksum;
00566     seg->chksum_swapped = chksum_swapped;
00567     seg->flags |= TF_SEG_DATA_CHECKSUMMED;
00568 #endif /* TCP_CHECKSUM_ON_COPY */
00569     /* Fix dataptr for the nocopy case */
00570     if ((apiflags & TCP_WRITE_FLAG_COPY) == 0) {
00571       seg->dataptr = (u8_t*)arg + pos;
00572     }
00573 
00574     /* first segment of to-be-queued data? */
00575     if (queue == NULL) {
00576       queue = seg;
00577     } else {
00578       /* Attach the segment to the end of the queued segments */
00579       LWIP_ASSERT("prev_seg != NULL", prev_seg != NULL);
00580       prev_seg->next = seg;
00581     }
00582     /* remember last segment of to-be-queued data for next iteration */
00583     prev_seg = seg;
00584 
00585     LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_TRACE, ("tcp_write: queueing %"U32_F":%"U32_F"\n",
00586       ntohl(seg->tcphdr->seqno),
00587       ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg)));
00588 
00589     pos += seglen;
00590   }
00591 
00592   /*
00593    * All three segmentation phases were successful. We can commit the
00594    * transaction.
00595    */
00596 
00597   /*
00598    * Phase 1: If data has been added to the preallocated tail of
00599    * last_unsent, we update the length fields of the pbuf chain.
00600    */
00601 #if TCP_OVERSIZE
00602   if (oversize_used > 0) {
00603     struct pbuf *p;
00604     /* Bump tot_len of whole chain, len of tail */
00605     for (p = last_unsent->p; p; p = p->next) {
00606       p->tot_len += oversize_used;
00607       if (p->next == NULL) {
00608         TCP_DATA_COPY((char *)p->payload + p->len, arg, oversize_used, last_unsent);
00609         p->len += oversize_used;
00610       }
00611     }
00612     last_unsent->len += oversize_used;
00613 #if TCP_OVERSIZE_DBGCHECK
00614     last_unsent->oversize_left -= oversize_used;
00615 #endif /* TCP_OVERSIZE_DBGCHECK */
00616   }
00617   pcb->unsent_oversize = oversize;
00618 #endif /* TCP_OVERSIZE */
00619 
00620   /*
00621    * Phase 2: concat_p can be concatenated onto last_unsent->p
00622    */
00623   if (concat_p != NULL) {
00624     LWIP_ASSERT("tcp_write: cannot concatenate when pcb->unsent is empty",
00625       (last_unsent != NULL));
00626     pbuf_cat(last_unsent->p, concat_p);
00627     last_unsent->len += concat_p->tot_len;
00628 #if TCP_CHECKSUM_ON_COPY
00629     if (concat_chksummed) {
00630       tcp_seg_add_chksum(concat_chksum, concat_chksummed, &last_unsent->chksum,
00631         &last_unsent->chksum_swapped);
00632       last_unsent->flags |= TF_SEG_DATA_CHECKSUMMED;
00633     }
00634 #endif /* TCP_CHECKSUM_ON_COPY */
00635   }
00636 
00637   /*
00638    * Phase 3: Append queue to pcb->unsent. Queue may be NULL, but that
00639    * is harmless
00640    */
00641   if (last_unsent == NULL) {
00642     pcb->unsent = queue;
00643   } else {
00644     last_unsent->next = queue;
00645   }
00646 
00647   /*
00648    * Finally update the pcb state.
00649    */
00650   pcb->snd_lbb += len;
00651   pcb->snd_buf -= len;
00652   pcb->snd_queuelen = queuelen;
00653 
00654   LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_write: %"S16_F" (after enqueued)\n",
00655     pcb->snd_queuelen));
00656   if (pcb->snd_queuelen != 0) {
00657     LWIP_ASSERT("tcp_write: valid queue length",
00658                 pcb->unacked != NULL || pcb->unsent != NULL);
00659   }
00660 
00661   /* Set the PSH flag in the last segment that we enqueued. */
00662   if (seg != NULL && seg->tcphdr != NULL && ((apiflags & TCP_WRITE_FLAG_MORE)==0)) {
00663     TCPH_SET_FLAG(seg->tcphdr, TCP_PSH);
00664   }
00665 
00666   return ERR_OK;
00667 memerr:
00668   pcb->flags |= TF_NAGLEMEMERR;
00669   TCP_STATS_INC(tcp.memerr);
00670 
00671   if (concat_p != NULL) {
00672     pbuf_free(concat_p);
00673   }
00674   if (queue != NULL) {
00675     tcp_segs_free(queue);
00676   }
00677   if (pcb->snd_queuelen != 0) {
00678     LWIP_ASSERT("tcp_write: valid queue length", pcb->unacked != NULL ||
00679       pcb->unsent != NULL);
00680   }
00681   LWIP_DEBUGF(TCP_QLEN_DEBUG | LWIP_DBG_STATE, ("tcp_write: %"S16_F" (with mem err)\n", pcb->snd_queuelen));
00682   return ERR_MEM;
00683 }
00684 
00685 /**
00686  * Enqueue TCP options for transmission.
00687  *
00688  * Called by tcp_connect(), tcp_listen_input(), and tcp_send_ctrl().
00689  *
00690  * @param pcb Protocol control block for the TCP connection.
00691  * @param flags TCP header flags to set in the outgoing segment.
00692  * @param optdata pointer to TCP options, or NULL.
00693  * @param optlen length of TCP options in bytes.
00694  */
00695 err_t
00696 tcp_enqueue_flags(struct tcp_pcb *pcb, u8_t flags)
00697 {
00698   struct pbuf *p;
00699   struct tcp_seg *seg;
00700   u8_t optflags = 0;
00701   u8_t optlen = 0;
00702 
00703   LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue_flags: queuelen: %"U16_F"\n", (u16_t)pcb->snd_queuelen));
00704 
00705   LWIP_ASSERT("tcp_enqueue_flags: need either TCP_SYN or TCP_FIN in flags (programmer violates API)",
00706               (flags & (TCP_SYN | TCP_FIN)) != 0);
00707 
00708   /* check for configured max queuelen and possible overflow */
00709   if ((pcb->snd_queuelen >= TCP_SND_QUEUELEN) || (pcb->snd_queuelen > TCP_SNDQUEUELEN_OVERFLOW)) {
00710     LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue_flags: too long queue %"U16_F" (max %"U16_F")\n",
00711                                        pcb->snd_queuelen, TCP_SND_QUEUELEN));
00712     TCP_STATS_INC(tcp.memerr);
00713     pcb->flags |= TF_NAGLEMEMERR;
00714     return ERR_MEM;
00715   }
00716 
00717   if (flags & TCP_SYN) {
00718     optflags = TF_SEG_OPTS_MSS;
00719   }
00720 #if LWIP_TCP_TIMESTAMPS
00721   if ((pcb->flags & TF_TIMESTAMP)) {
00722     optflags |= TF_SEG_OPTS_TS;
00723   }
00724 #endif /* LWIP_TCP_TIMESTAMPS */
00725   optlen = LWIP_TCP_OPT_LENGTH(optflags);
00726 
00727   /* tcp_enqueue_flags is always called with either SYN or FIN in flags.
00728    * We need one available snd_buf byte to do that.
00729    * This means we can't send FIN while snd_buf==0. A better fix would be to
00730    * not include SYN and FIN sequence numbers in the snd_buf count. */
00731   if (pcb->snd_buf == 0) {
00732     LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue_flags: no send buffer available\n"));
00733     TCP_STATS_INC(tcp.memerr);
00734     return ERR_MEM;
00735   }
00736 
00737   /* Allocate pbuf with room for TCP header + options */
00738   if ((p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) {
00739     pcb->flags |= TF_NAGLEMEMERR;
00740     TCP_STATS_INC(tcp.memerr);
00741     return ERR_MEM;
00742   }
00743   LWIP_ASSERT("tcp_enqueue_flags: check that first pbuf can hold optlen",
00744               (p->len >= optlen));
00745 
00746   /* Allocate memory for tcp_seg, and fill in fields. */
00747   if ((seg = tcp_create_segment(pcb, p, flags, pcb->snd_lbb, optflags)) == NULL) {
00748     pcb->flags |= TF_NAGLEMEMERR;
00749     TCP_STATS_INC(tcp.memerr);
00750     return ERR_MEM;
00751   }
00752   LWIP_ASSERT("tcp_enqueue_flags: invalid segment length", seg->len == 0);
00753 
00754   LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_TRACE,
00755               ("tcp_enqueue_flags: queueing %"U32_F":%"U32_F" (0x%"X16_F")\n",
00756                ntohl(seg->tcphdr->seqno),
00757                ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg),
00758                (u16_t)flags));
00759 
00760   /* Now append seg to pcb->unsent queue */
00761   if (pcb->unsent == NULL) {
00762     pcb->unsent = seg;
00763   } else {
00764     struct tcp_seg *useg;
00765     for (useg = pcb->unsent; useg->next != NULL; useg = useg->next);
00766     useg->next = seg;
00767   }
00768 #if TCP_OVERSIZE
00769   /* The new unsent tail has no space */
00770   pcb->unsent_oversize = 0;
00771 #endif /* TCP_OVERSIZE */
00772 
00773   /* SYN and FIN bump the sequence number */
00774   if ((flags & TCP_SYN) || (flags & TCP_FIN)) {
00775     pcb->snd_lbb++;
00776     /* optlen does not influence snd_buf */
00777     pcb->snd_buf--;
00778   }
00779   if (flags & TCP_FIN) {
00780     pcb->flags |= TF_FIN;
00781   }
00782 
00783   /* update number of segments on the queues */
00784   pcb->snd_queuelen += pbuf_clen(seg->p);
00785   LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue_flags: %"S16_F" (after enqueued)\n", pcb->snd_queuelen));
00786   if (pcb->snd_queuelen != 0) {
00787     LWIP_ASSERT("tcp_enqueue_flags: invalid queue length",
00788       pcb->unacked != NULL || pcb->unsent != NULL);
00789   }
00790 
00791   return ERR_OK;
00792 }
00793  
00794 
00795 #if LWIP_TCP_TIMESTAMPS
00796 /* Build a timestamp option (12 bytes long) at the specified options pointer)
00797  *
00798  * @param pcb tcp_pcb
00799  * @param opts option pointer where to store the timestamp option
00800  */
00801 static void
00802 tcp_build_timestamp_option(struct tcp_pcb *pcb, u32_t *opts)
00803 {
00804   /* Pad with two NOP options to make everything nicely aligned */
00805   opts[0] = htonl(0x0101080A);
00806   opts[1] = htonl(sys_now());
00807   opts[2] = htonl(pcb->ts_recent);
00808 }
00809 #endif
00810 
00811 /** Send an ACK without data.
00812  *
00813  * @param pcb Protocol control block for the TCP connection to send the ACK
00814  */
00815 err_t
00816 tcp_send_empty_ack(struct tcp_pcb *pcb)
00817 {
00818   struct pbuf *p;
00819   struct tcp_hdr *tcphdr;
00820   u8_t optlen = 0;
00821 
00822 #if LWIP_TCP_TIMESTAMPS
00823   if (pcb->flags & TF_TIMESTAMP) {
00824     optlen = LWIP_TCP_OPT_LENGTH(TF_SEG_OPTS_TS);
00825   }
00826 #endif
00827 
00828   p = tcp_output_alloc_header(pcb, optlen, 0, htonl(pcb->snd_nxt));
00829   if (p == NULL) {
00830     LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: (ACK) could not allocate pbuf\n"));
00831     return ERR_BUF;
00832   }
00833   tcphdr = (struct tcp_hdr *)p->payload;
00834   LWIP_DEBUGF(TCP_OUTPUT_DEBUG, 
00835               ("tcp_output: sending ACK for %"U32_F"\n", pcb->rcv_nxt));
00836   /* remove ACK flags from the PCB, as we send an empty ACK now */
00837   pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
00838 
00839   /* NB. MSS option is only sent on SYNs, so ignore it here */
00840 #if LWIP_TCP_TIMESTAMPS
00841   pcb->ts_lastacksent = pcb->rcv_nxt;
00842 
00843   if (pcb->flags & TF_TIMESTAMP) {
00844     tcp_build_timestamp_option(pcb, (u32_t *)(tcphdr + 1));
00845   }
00846 #endif 
00847 
00848 #if CHECKSUM_GEN_TCP
00849   tcphdr->chksum = inet_chksum_pseudo(p, &(pcb->local_ip), &(pcb->remote_ip),
00850         IP_PROTO_TCP, p->tot_len);
00851 #endif
00852 #if LWIP_NETIF_HWADDRHINT
00853   ip_output_hinted(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
00854       IP_PROTO_TCP, &(pcb->addr_hint));
00855 #else /* LWIP_NETIF_HWADDRHINT*/
00856   ip_output(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
00857       IP_PROTO_TCP);
00858 #endif /* LWIP_NETIF_HWADDRHINT*/
00859   pbuf_free(p);
00860 
00861   return ERR_OK;
00862 }
00863 
00864 /**
00865  * Find out what we can send and send it
00866  *
00867  * @param pcb Protocol control block for the TCP connection to send data
00868  * @return ERR_OK if data has been sent or nothing to send
00869  *         another err_t on error
00870  */
00871 err_t
00872 tcp_output(struct tcp_pcb *pcb)
00873 {
00874   struct tcp_seg *seg, *useg;
00875   u32_t wnd, snd_nxt;
00876 #if TCP_CWND_DEBUG
00877   s16_t i = 0;
00878 #endif /* TCP_CWND_DEBUG */
00879 
00880   /* First, check if we are invoked by the TCP input processing
00881      code. If so, we do not output anything. Instead, we rely on the
00882      input processing code to call us when input processing is done
00883      with. */
00884   if (tcp_input_pcb == pcb) {
00885     return ERR_OK;
00886   }
00887 
00888   wnd = LWIP_MIN(pcb->snd_wnd, pcb->cwnd);
00889 
00890   seg = pcb->unsent;
00891 
00892   /* If the TF_ACK_NOW flag is set and no data will be sent (either
00893    * because the ->unsent queue is empty or because the window does
00894    * not allow it), construct an empty ACK segment and send it.
00895    *
00896    * If data is to be sent, we will just piggyback the ACK (see below).
00897    */
00898   if (pcb->flags & TF_ACK_NOW &&
00899      (seg == NULL ||
00900       ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len > wnd)) {
00901      return tcp_send_empty_ack(pcb);
00902   }
00903 
00904   /* useg should point to last segment on unacked queue */
00905   useg = pcb->unacked;
00906   if (useg != NULL) {
00907     for (; useg->next != NULL; useg = useg->next);
00908   }
00909 
00910 #if TCP_OUTPUT_DEBUG
00911   if (seg == NULL) {
00912     LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: nothing to send (%p)\n",
00913                                    (void*)pcb->unsent));
00914   }
00915 #endif /* TCP_OUTPUT_DEBUG */
00916 #if TCP_CWND_DEBUG
00917   if (seg == NULL) {
00918     LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"U16_F
00919                                  ", cwnd %"U16_F", wnd %"U32_F
00920                                  ", seg == NULL, ack %"U32_F"\n",
00921                                  pcb->snd_wnd, pcb->cwnd, wnd, pcb->lastack));
00922   } else {
00923     LWIP_DEBUGF(TCP_CWND_DEBUG, 
00924                 ("tcp_output: snd_wnd %"U16_F", cwnd %"U16_F", wnd %"U32_F
00925                  ", effwnd %"U32_F", seq %"U32_F", ack %"U32_F"\n",
00926                  pcb->snd_wnd, pcb->cwnd, wnd,
00927                  ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len,
00928                  ntohl(seg->tcphdr->seqno), pcb->lastack));
00929   }
00930 #endif /* TCP_CWND_DEBUG */
00931   /* data available and window allows it to be sent? */
00932   while (seg != NULL &&
00933          ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) {
00934     LWIP_ASSERT("RST not expected here!", 
00935                 (TCPH_FLAGS(seg->tcphdr) & TCP_RST) == 0);
00936     /* Stop sending if the nagle algorithm would prevent it
00937      * Don't stop:
00938      * - if tcp_write had a memory error before (prevent delayed ACK timeout) or
00939      * - if FIN was already enqueued for this PCB (SYN is always alone in a segment -
00940      *   either seg->next != NULL or pcb->unacked == NULL;
00941      *   RST is no sent using tcp_write/tcp_output.
00942      */
00943     if((tcp_do_output_nagle(pcb) == 0) &&
00944       ((pcb->flags & (TF_NAGLEMEMERR | TF_FIN)) == 0)){
00945       break;
00946     }
00947 #if TCP_CWND_DEBUG
00948     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",
00949                             pcb->snd_wnd, pcb->cwnd, wnd,
00950                             ntohl(seg->tcphdr->seqno) + seg->len -
00951                             pcb->lastack,
00952                             ntohl(seg->tcphdr->seqno), pcb->lastack, i));
00953     ++i;
00954 #endif /* TCP_CWND_DEBUG */
00955 
00956     pcb->unsent = seg->next;
00957 
00958     if (pcb->state != SYN_SENT) {
00959       TCPH_SET_FLAG(seg->tcphdr, TCP_ACK);
00960       pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
00961     }
00962 
00963     tcp_output_segment(seg, pcb);
00964     snd_nxt = ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg);
00965     if (TCP_SEQ_LT(pcb->snd_nxt, snd_nxt)) {
00966       pcb->snd_nxt = snd_nxt;
00967     }
00968     /* put segment on unacknowledged list if length > 0 */
00969     if (TCP_TCPLEN(seg) > 0) {
00970       seg->next = NULL;
00971       /* unacked list is empty? */
00972       if (pcb->unacked == NULL) {
00973         pcb->unacked = seg;
00974         useg = seg;
00975       /* unacked list is not empty? */
00976       } else {
00977         /* In the case of fast retransmit, the packet should not go to the tail
00978          * of the unacked queue, but rather somewhere before it. We need to check for
00979          * this case. -STJ Jul 27, 2004 */
00980         if (TCP_SEQ_LT(ntohl(seg->tcphdr->seqno), ntohl(useg->tcphdr->seqno))) {
00981           /* add segment to before tail of unacked list, keeping the list sorted */
00982           struct tcp_seg **cur_seg = &(pcb->unacked);
00983           while (*cur_seg &&
00984             TCP_SEQ_LT(ntohl((*cur_seg)->tcphdr->seqno), ntohl(seg->tcphdr->seqno))) {
00985               cur_seg = &((*cur_seg)->next );
00986           }
00987           seg->next = (*cur_seg);
00988           (*cur_seg) = seg;
00989         } else {
00990           /* add segment to tail of unacked list */
00991           useg->next = seg;
00992           useg = useg->next;
00993         }
00994       }
00995     /* do not queue empty segments on the unacked list */
00996     } else {
00997       tcp_seg_free(seg);
00998     }
00999     seg = pcb->unsent;
01000   }
01001 #if TCP_OVERSIZE
01002   if (pcb->unsent == NULL) {
01003     /* last unsent has been removed, reset unsent_oversize */
01004     pcb->unsent_oversize = 0;
01005   }
01006 #endif /* TCP_OVERSIZE */
01007 
01008   if (seg != NULL && pcb->persist_backoff == 0 && 
01009       ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len > pcb->snd_wnd) {
01010     /* prepare for persist timer */
01011     pcb->persist_cnt = 0;
01012     pcb->persist_backoff = 1;
01013   }
01014 
01015   pcb->flags &= ~TF_NAGLEMEMERR;
01016   return ERR_OK;
01017 }
01018 
01019 /**
01020  * Called by tcp_output() to actually send a TCP segment over IP.
01021  *
01022  * @param seg the tcp_seg to send
01023  * @param pcb the tcp_pcb for the TCP connection used to send the segment
01024  */
01025 static void
01026 tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb)
01027 {
01028   u16_t len;
01029   struct netif *netif;
01030   u32_t *opts;
01031 
01032   /** @bug Exclude retransmitted segments from this count. */
01033   snmp_inc_tcpoutsegs();
01034 
01035   /* The TCP header has already been constructed, but the ackno and
01036    wnd fields remain. */
01037   seg->tcphdr->ackno = htonl(pcb->rcv_nxt);
01038 
01039   /* advertise our receive window size in this TCP segment */
01040   seg->tcphdr->wnd = htons(pcb->rcv_ann_wnd);
01041 
01042   pcb->rcv_ann_right_edge = pcb->rcv_nxt + pcb->rcv_ann_wnd;
01043 
01044   /* Add any requested options.  NB MSS option is only set on SYN
01045      packets, so ignore it here */
01046   LWIP_ASSERT("seg->tcphdr not aligned", ((mem_ptr_t)(seg->tcphdr + 1) % 4) == 0);
01047   opts = (u32_t *)(void *)(seg->tcphdr + 1);
01048   if (seg->flags & TF_SEG_OPTS_MSS) {
01049     TCP_BUILD_MSS_OPTION(*opts);
01050     opts += 1;
01051   }
01052 #if LWIP_TCP_TIMESTAMPS
01053   pcb->ts_lastacksent = pcb->rcv_nxt;
01054 
01055   if (seg->flags & TF_SEG_OPTS_TS) {
01056     tcp_build_timestamp_option(pcb, opts);
01057     opts += 3;
01058   }
01059 #endif
01060 
01061   /* If we don't have a local IP address, we get one by
01062      calling ip_route(). */
01063   if (ip_addr_isany(&(pcb->local_ip))) {
01064     netif = ip_route(&(pcb->remote_ip));
01065     if (netif == NULL) {
01066       return;
01067     }
01068     ip_addr_copy(pcb->local_ip, netif->ip_addr);
01069   }
01070 
01071   /* Set retransmission timer running if it is not currently enabled */
01072   if(pcb->rtime == -1) {
01073     pcb->rtime = 0;
01074   }
01075 
01076   if (pcb->rttest == 0) {
01077     pcb->rttest = tcp_ticks;
01078     pcb->rtseq = ntohl(seg->tcphdr->seqno);
01079 
01080     LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_output_segment: rtseq %"U32_F"\n", pcb->rtseq));
01081   }
01082   LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output_segment: %"U32_F":%"U32_F"\n",
01083           htonl(seg->tcphdr->seqno), htonl(seg->tcphdr->seqno) +
01084           seg->len));
01085 
01086   len = (u16_t)((u8_t *)seg->tcphdr - (u8_t *)seg->p->payload);
01087 
01088   seg->p->len -= len;
01089   seg->p->tot_len -= len;
01090 
01091   seg->p->payload = seg->tcphdr;
01092 
01093   seg->tcphdr->chksum = 0;
01094 #if CHECKSUM_GEN_TCP
01095 #if TCP_CHECKSUM_ON_COPY
01096   {
01097     u32_t acc;
01098 #if TCP_CHECKSUM_ON_COPY_SANITY_CHECK
01099     u16_t chksum_slow = inet_chksum_pseudo(seg->p, &(pcb->local_ip),
01100            &(pcb->remote_ip),
01101            IP_PROTO_TCP, seg->p->tot_len);
01102 #endif /* TCP_CHECKSUM_ON_COPY_SANITY_CHECK */
01103     if ((seg->flags & TF_SEG_DATA_CHECKSUMMED) == 0) {
01104       LWIP_ASSERT("data included but not checksummed",
01105         seg->p->tot_len == (TCPH_HDRLEN(seg->tcphdr) * 4));
01106     }
01107 
01108     /* rebuild TCP header checksum (TCP header changes for retransmissions!) */
01109     acc = inet_chksum_pseudo_partial(seg->p, &(pcb->local_ip),
01110              &(pcb->remote_ip),
01111              IP_PROTO_TCP, seg->p->tot_len, TCPH_HDRLEN(seg->tcphdr) * 4);
01112     /* add payload checksum */
01113     if (seg->chksum_swapped) {
01114       seg->chksum = SWAP_BYTES_IN_WORD(seg->chksum);
01115       seg->chksum_swapped = 0;
01116     }
01117     acc += (u16_t)~(seg->chksum);
01118     seg->tcphdr->chksum = FOLD_U32T(acc);
01119 #if TCP_CHECKSUM_ON_COPY_SANITY_CHECK
01120     if (chksum_slow != seg->tcphdr->chksum) {
01121       LWIP_DEBUGF(TCP_DEBUG | LWIP_DBG_LEVEL_WARNING,
01122                   ("tcp_output_segment: calculated checksum is %"X16_F" instead of %"X16_F"\n",
01123                   seg->tcphdr->chksum, chksum_slow));
01124       seg->tcphdr->chksum = chksum_slow;
01125     }
01126 #endif /* TCP_CHECKSUM_ON_COPY_SANITY_CHECK */
01127   }
01128 #else /* TCP_CHECKSUM_ON_COPY */
01129   seg->tcphdr->chksum = inet_chksum_pseudo(seg->p, &(pcb->local_ip),
01130          &(pcb->remote_ip),
01131          IP_PROTO_TCP, seg->p->tot_len);
01132 #endif /* TCP_CHECKSUM_ON_COPY */
01133 #endif /* CHECKSUM_GEN_TCP */
01134   TCP_STATS_INC(tcp.xmit);
01135 
01136 #if LWIP_NETIF_HWADDRHINT
01137   ip_output_hinted(seg->p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
01138       IP_PROTO_TCP, &(pcb->addr_hint));
01139 #else /* LWIP_NETIF_HWADDRHINT*/
01140   ip_output(seg->p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
01141       IP_PROTO_TCP);
01142 #endif /* LWIP_NETIF_HWADDRHINT*/
01143 }
01144 
01145 /**
01146  * Send a TCP RESET packet (empty segment with RST flag set) either to
01147  * abort a connection or to show that there is no matching local connection
01148  * for a received segment.
01149  *
01150  * Called by tcp_abort() (to abort a local connection), tcp_input() (if no
01151  * matching local pcb was found), tcp_listen_input() (if incoming segment
01152  * has ACK flag set) and tcp_process() (received segment in the wrong state)
01153  *
01154  * Since a RST segment is in most cases not sent for an active connection,
01155  * tcp_rst() has a number of arguments that are taken from a tcp_pcb for
01156  * most other segment output functions.
01157  *
01158  * @param seqno the sequence number to use for the outgoing segment
01159  * @param ackno the acknowledge number to use for the outgoing segment
01160  * @param local_ip the local IP address to send the segment from
01161  * @param remote_ip the remote IP address to send the segment to
01162  * @param local_port the local TCP port to send the segment from
01163  * @param remote_port the remote TCP port to send the segment to
01164  */
01165 void
01166 tcp_rst(u32_t seqno, u32_t ackno,
01167   ip_addr_t *local_ip, ip_addr_t *remote_ip,
01168   u16_t local_port, u16_t remote_port)
01169 {
01170   struct pbuf *p;
01171   struct tcp_hdr *tcphdr;
01172   p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM);
01173   if (p == NULL) {
01174       LWIP_DEBUGF(TCP_DEBUG, ("tcp_rst: could not allocate memory for pbuf\n"));
01175       return;
01176   }
01177   LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr",
01178               (p->len >= sizeof(struct tcp_hdr)));
01179 
01180   tcphdr = (struct tcp_hdr *)p->payload;
01181   tcphdr->src = htons(local_port);
01182   tcphdr->dest = htons(remote_port);
01183   tcphdr->seqno = htonl(seqno);
01184   tcphdr->ackno = htonl(ackno);
01185   TCPH_HDRLEN_FLAGS_SET(tcphdr, TCP_HLEN/4, TCP_RST | TCP_ACK);
01186   tcphdr->wnd = htons(TCP_WND);
01187   tcphdr->chksum = 0;
01188   tcphdr->urgp = 0;
01189 
01190 #if CHECKSUM_GEN_TCP
01191   tcphdr->chksum = inet_chksum_pseudo(p, local_ip, remote_ip,
01192               IP_PROTO_TCP, p->tot_len);
01193 #endif
01194   TCP_STATS_INC(tcp.xmit);
01195   snmp_inc_tcpoutrsts();
01196    /* Send output with hardcoded TTL since we have no access to the pcb */
01197   ip_output(p, local_ip, remote_ip, TCP_TTL, 0, IP_PROTO_TCP);
01198   pbuf_free(p);
01199   LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_rst: seqno %"U32_F" ackno %"U32_F".\n", seqno, ackno));
01200 }
01201 
01202 /**
01203  * Requeue all unacked segments for retransmission
01204  *
01205  * Called by tcp_slowtmr() for slow retransmission.
01206  *
01207  * @param pcb the tcp_pcb for which to re-enqueue all unacked segments
01208  */
01209 void
01210 tcp_rexmit_rto(struct tcp_pcb *pcb)
01211 {
01212   struct tcp_seg *seg;
01213 
01214   if (pcb->unacked == NULL) {
01215     return;
01216   }
01217 
01218   /* Move all unacked segments to the head of the unsent queue */
01219   for (seg = pcb->unacked; seg->next != NULL; seg = seg->next);
01220   /* concatenate unsent queue after unacked queue */
01221   seg->next = pcb->unsent;
01222   /* unsent queue is the concatenated queue (of unacked, unsent) */
01223   pcb->unsent = pcb->unacked;
01224   /* unacked queue is now empty */
01225   pcb->unacked = NULL;
01226 
01227   /* increment number of retransmissions */
01228   ++pcb->nrtx;
01229 
01230   /* Don't take any RTT measurements after retransmitting. */
01231   pcb->rttest = 0;
01232 
01233   /* Do the actual retransmission */
01234   tcp_output(pcb);
01235 }
01236 
01237 /**
01238  * Requeue the first unacked segment for retransmission
01239  *
01240  * Called by tcp_receive() for fast retramsmit.
01241  *
01242  * @param pcb the tcp_pcb for which to retransmit the first unacked segment
01243  */
01244 void
01245 tcp_rexmit(struct tcp_pcb *pcb)
01246 {
01247   struct tcp_seg *seg;
01248   struct tcp_seg **cur_seg;
01249 
01250   if (pcb->unacked == NULL) {
01251     return;
01252   }
01253 
01254   /* Move the first unacked segment to the unsent queue */
01255   /* Keep the unsent queue sorted. */
01256   seg = pcb->unacked;
01257   pcb->unacked = seg->next;
01258 
01259   cur_seg = &(pcb->unsent);
01260   while (*cur_seg &&
01261     TCP_SEQ_LT(ntohl((*cur_seg)->tcphdr->seqno), ntohl(seg->tcphdr->seqno))) {
01262       cur_seg = &((*cur_seg)->next );
01263   }
01264   seg->next = *cur_seg;
01265   *cur_seg = seg;
01266 
01267   ++pcb->nrtx;
01268 
01269   /* Don't take any rtt measurements after retransmitting. */
01270   pcb->rttest = 0;
01271 
01272   /* Do the actual retransmission. */
01273   snmp_inc_tcpretranssegs();
01274   /* No need to call tcp_output: we are always called from tcp_input()
01275      and thus tcp_output directly returns. */
01276 }
01277 
01278 
01279 /**
01280  * Handle retransmission after three dupacks received
01281  *
01282  * @param pcb the tcp_pcb for which to retransmit the first unacked segment
01283  */
01284 void 
01285 tcp_rexmit_fast(struct tcp_pcb *pcb)
01286 {
01287   if (pcb->unacked != NULL && !(pcb->flags & TF_INFR)) {
01288     /* This is fast retransmit. Retransmit the first unacked segment. */
01289     LWIP_DEBUGF(TCP_FR_DEBUG, 
01290                 ("tcp_receive: dupacks %"U16_F" (%"U32_F
01291                  "), fast retransmit %"U32_F"\n",
01292                  (u16_t)pcb->dupacks, pcb->lastack,
01293                  ntohl(pcb->unacked->tcphdr->seqno)));
01294     tcp_rexmit(pcb);
01295 
01296     /* Set ssthresh to half of the minimum of the current
01297      * cwnd and the advertised window */
01298     if (pcb->cwnd > pcb->snd_wnd) {
01299       pcb->ssthresh = pcb->snd_wnd / 2;
01300     } else {
01301       pcb->ssthresh = pcb->cwnd / 2;
01302     }
01303     
01304     /* The minimum value for ssthresh should be 2 MSS */
01305     if (pcb->ssthresh < 2*pcb->mss) {
01306       LWIP_DEBUGF(TCP_FR_DEBUG, 
01307                   ("tcp_receive: The minimum value for ssthresh %"U16_F
01308                    " should be min 2 mss %"U16_F"...\n",
01309                    pcb->ssthresh, 2*pcb->mss));
01310       pcb->ssthresh = 2*pcb->mss;
01311     }
01312     
01313     pcb->cwnd = pcb->ssthresh + 3 * pcb->mss;
01314     pcb->flags |= TF_INFR;
01315   } 
01316 }
01317 
01318 
01319 /**
01320  * Send keepalive packets to keep a connection active although
01321  * no data is sent over it.
01322  *
01323  * Called by tcp_slowtmr()
01324  *
01325  * @param pcb the tcp_pcb for which to send a keepalive packet
01326  */
01327 void
01328 tcp_keepalive(struct tcp_pcb *pcb)
01329 {
01330   struct pbuf *p;
01331   struct tcp_hdr *tcphdr;
01332 
01333   LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: sending KEEPALIVE probe to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
01334                           ip4_addr1_16(&pcb->remote_ip), ip4_addr2_16(&pcb->remote_ip),
01335                           ip4_addr3_16(&pcb->remote_ip), ip4_addr4_16(&pcb->remote_ip)));
01336 
01337   LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: tcp_ticks %"U32_F"   pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n", 
01338                           tcp_ticks, pcb->tmr, pcb->keep_cnt_sent));
01339    
01340   p = tcp_output_alloc_header(pcb, 0, 0, htonl(pcb->snd_nxt - 1));
01341   if(p == NULL) {
01342     LWIP_DEBUGF(TCP_DEBUG, 
01343                 ("tcp_keepalive: could not allocate memory for pbuf\n"));
01344     return;
01345   }
01346   tcphdr = (struct tcp_hdr *)p->payload;
01347 
01348 #if CHECKSUM_GEN_TCP
01349   tcphdr->chksum = inet_chksum_pseudo(p, &pcb->local_ip, &pcb->remote_ip,
01350                                       IP_PROTO_TCP, p->tot_len);
01351 #endif
01352   TCP_STATS_INC(tcp.xmit);
01353 
01354   /* Send output to IP */
01355 #if LWIP_NETIF_HWADDRHINT
01356   ip_output_hinted(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP,
01357     &(pcb->addr_hint));
01358 #else /* LWIP_NETIF_HWADDRHINT*/
01359   ip_output(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP);
01360 #endif /* LWIP_NETIF_HWADDRHINT*/
01361 
01362   pbuf_free(p);
01363 
01364   LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: seqno %"U32_F" ackno %"U32_F".\n",
01365                           pcb->snd_nxt - 1, pcb->rcv_nxt));
01366 }
01367 
01368 
01369 /**
01370  * Send persist timer zero-window probes to keep a connection active
01371  * when a window update is lost.
01372  *
01373  * Called by tcp_slowtmr()
01374  *
01375  * @param pcb the tcp_pcb for which to send a zero-window probe packet
01376  */
01377 void
01378 tcp_zero_window_probe(struct tcp_pcb *pcb)
01379 {
01380   struct pbuf *p;
01381   struct tcp_hdr *tcphdr;
01382   struct tcp_seg *seg;
01383   u16_t len;
01384   u8_t is_fin;
01385 
01386   LWIP_DEBUGF(TCP_DEBUG, 
01387               ("tcp_zero_window_probe: sending ZERO WINDOW probe to %"
01388                U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
01389                ip4_addr1_16(&pcb->remote_ip), ip4_addr2_16(&pcb->remote_ip),
01390                ip4_addr3_16(&pcb->remote_ip), ip4_addr4_16(&pcb->remote_ip)));
01391 
01392   LWIP_DEBUGF(TCP_DEBUG, 
01393               ("tcp_zero_window_probe: tcp_ticks %"U32_F
01394                "   pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n", 
01395                tcp_ticks, pcb->tmr, pcb->keep_cnt_sent));
01396 
01397   seg = pcb->unacked;
01398 
01399   if(seg == NULL) {
01400     seg = pcb->unsent;
01401   }
01402   if(seg == NULL) {
01403     return;
01404   }
01405 
01406   is_fin = ((TCPH_FLAGS(seg->tcphdr) & TCP_FIN) != 0) && (seg->len == 0);
01407   /* we want to send one seqno: either FIN or data (no options) */
01408   len = is_fin ? 0 : 1;
01409 
01410   p = tcp_output_alloc_header(pcb, 0, len, seg->tcphdr->seqno);
01411   if(p == NULL) {
01412     LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: no memory for pbuf\n"));
01413     return;
01414   }
01415   tcphdr = (struct tcp_hdr *)p->payload;
01416 
01417   if (is_fin) {
01418     /* FIN segment, no data */
01419     TCPH_FLAGS_SET(tcphdr, TCP_ACK | TCP_FIN);
01420   } else {
01421     /* Data segment, copy in one byte from the head of the unacked queue */
01422     *((char *)p->payload + TCP_HLEN) = *(char *)seg->dataptr;
01423   }
01424 
01425 #if CHECKSUM_GEN_TCP
01426   tcphdr->chksum = inet_chksum_pseudo(p, &pcb->local_ip, &pcb->remote_ip,
01427                                       IP_PROTO_TCP, p->tot_len);
01428 #endif
01429   TCP_STATS_INC(tcp.xmit);
01430 
01431   /* Send output to IP */
01432 #if LWIP_NETIF_HWADDRHINT
01433   ip_output_hinted(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP,
01434     &(pcb->addr_hint));
01435 #else /* LWIP_NETIF_HWADDRHINT*/
01436   ip_output(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP);
01437 #endif /* LWIP_NETIF_HWADDRHINT*/
01438 
01439   pbuf_free(p);
01440 
01441   LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: seqno %"U32_F
01442                           " ackno %"U32_F".\n",
01443                           pcb->snd_nxt - 1, pcb->rcv_nxt));
01444 }
01445 #endif /* LWIP_TCP */