Daiki Kato / mbed-os-lychee

Dependents:   mbed-os-example-blinky-gr-lychee GR-Boads_Camera_sample GR-Boards_Audio_Recoder GR-Boads_Camera_DisplayApp ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers lwip_tcp_out.c Source File

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