Ethernet for Nucleo and Disco board STM32F746 works with gcc and arm. IAC is untested

Dependents:   STM32F746_iothub_client_sample_mqtt DISCO-F746NG_Ethernet Nucleo_F746ZG_Ethernet thethingsiO-DISCO_F746NG-mqtt ... more

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