ZG2100 Network interface source

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