ソースの整理中ですが、利用はできます。 大きなファイルはできないかもしれません。

Dependencies:   EthernetInterface HttpServer TextLCD expatlib mbed-rpc mbed-rtos mbed Socket lwip-eth lwip-sys lwip

Fork of giken9_HTMLServer_Sample by Yasushi TAUCHI

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