1/**
2 * @file
3 * Transmission Control Protocol, outgoing traffic
4 *
5 * The output functions of TCP.
6 *
7 */
8
9/*
10 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
11 * All rights reserved.
12 *
13 * Redistribution and use in source and binary forms, with or without modification,
14 * are permitted provided that the following conditions are met:
15 *
16 * 1. Redistributions of source code must retain the above copyright notice,
17 *    this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright notice,
19 *    this list of conditions and the following disclaimer in the documentation
20 *    and/or other materials provided with the distribution.
21 * 3. The name of the author may not be used to endorse or promote products
22 *    derived from this software without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
25 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
26 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
27 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
29 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
32 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
33 * OF SUCH DAMAGE.
34 *
35 * This file is part of the lwIP TCP/IP stack.
36 *
37 * Author: Adam Dunkels <adam@sics.se>
38 *
39 */
40
41#include "lwip/opt.h"
42
43#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */
44
45#include "lwip/priv/tcp_priv.h"
46#include "lwip/def.h"
47#include "lwip/mem.h"
48#include "lwip/memp.h"
49#include "lwip/ip_addr.h"
50#include "lwip/netif.h"
51#include "lwip/inet_chksum.h"
52#include "lwip/stats.h"
53#include "lwip/ip6.h"
54#include "lwip/ip6_addr.h"
55#if LWIP_TCP_TIMESTAMPS
56#include "lwip/sys.h"
57#endif
58
59#include <string.h>
60
61/* Define some copy-macros for checksum-on-copy so that the code looks
62   nicer by preventing too many ifdef's. */
63#if TCP_CHECKSUM_ON_COPY
64#define TCP_DATA_COPY(dst, src, len, seg) do { \
65  tcp_seg_add_chksum(LWIP_CHKSUM_COPY(dst, src, len), \
66                     len, &seg->chksum, &seg->chksum_swapped); \
67  seg->flags |= TF_SEG_DATA_CHECKSUMMED; } while(0)
68#define TCP_DATA_COPY2(dst, src, len, chksum, chksum_swapped)  \
69  tcp_seg_add_chksum(LWIP_CHKSUM_COPY(dst, src, len), len, chksum, chksum_swapped);
70#else /* TCP_CHECKSUM_ON_COPY*/
71#define TCP_DATA_COPY(dst, src, len, seg)                     MEMCPY(dst, src, len)
72#define TCP_DATA_COPY2(dst, src, len, chksum, chksum_swapped) MEMCPY(dst, src, len)
73#endif /* TCP_CHECKSUM_ON_COPY*/
74
75/** Define this to 1 for an extra check that the output checksum is valid
76 * (usefule when the checksum is generated by the application, not the stack) */
77#ifndef TCP_CHECKSUM_ON_COPY_SANITY_CHECK
78#define TCP_CHECKSUM_ON_COPY_SANITY_CHECK   0
79#endif
80/* Allow to override the failure of sanity check from warning to e.g. hard failure */
81#if TCP_CHECKSUM_ON_COPY_SANITY_CHECK
82#ifndef TCP_CHECKSUM_ON_COPY_SANITY_CHECK_FAIL
83#define TCP_CHECKSUM_ON_COPY_SANITY_CHECK_FAIL(msg) LWIP_DEBUGF(TCP_DEBUG | LWIP_DBG_LEVEL_WARNING, msg)
84#endif
85#endif
86
87#if TCP_OVERSIZE
88/** The size of segment pbufs created when TCP_OVERSIZE is enabled */
89#ifndef TCP_OVERSIZE_CALC_LENGTH
90#define TCP_OVERSIZE_CALC_LENGTH(length) ((length) + TCP_OVERSIZE)
91#endif
92#endif
93
94/* Forward declarations.*/
95static err_t tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif);
96
97/** Allocate a pbuf and create a tcphdr at p->payload, used for output
98 * functions other than the default tcp_output -> tcp_output_segment
99 * (e.g. tcp_send_empty_ack, etc.)
100 *
101 * @param pcb tcp pcb for which to send a packet (used to initialize tcp_hdr)
102 * @param optlen length of header-options
103 * @param datalen length of tcp data to reserve in pbuf
104 * @param seqno_be seqno in network byte order (big-endian)
105 * @return pbuf with p->payload being the tcp_hdr
106 */
107static struct pbuf *
108tcp_output_alloc_header(struct tcp_pcb *pcb, u16_t optlen, u16_t datalen,
109                      u32_t seqno_be /* already in network byte order */)
110{
111  struct tcp_hdr *tcphdr;
112  struct pbuf *p = pbuf_alloc(PBUF_IP, TCP_HLEN + optlen + datalen, PBUF_RAM);
113  if (p != NULL) {
114    LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr",
115                 (p->len >= TCP_HLEN + optlen));
116    tcphdr = (struct tcp_hdr *)p->payload;
117    tcphdr->src = lwip_htons(pcb->local_port);
118    tcphdr->dest = lwip_htons(pcb->remote_port);
119    tcphdr->seqno = seqno_be;
120    tcphdr->ackno = lwip_htonl(pcb->rcv_nxt);
121    TCPH_HDRLEN_FLAGS_SET(tcphdr, (5 + optlen / 4), TCP_ACK);
122    tcphdr->wnd = lwip_htons(TCPWND_MIN16(RCV_WND_SCALE(pcb, pcb->rcv_ann_wnd)));
123    tcphdr->chksum = 0;
124    tcphdr->urgp = 0;
125
126    /* If we're sending a packet, update the announced right window edge */
127    pcb->rcv_ann_right_edge = pcb->rcv_nxt + pcb->rcv_ann_wnd;
128  }
129  return p;
130}
131
132/**
133 * Called by tcp_close() to send a segment including FIN flag but not data.
134 *
135 * @param pcb the tcp_pcb over which to send a segment
136 * @return ERR_OK if sent, another err_t otherwise
137 */
138err_t
139tcp_send_fin(struct tcp_pcb *pcb)
140{
141  /* first, try to add the fin to the last unsent segment */
142  if (pcb->unsent != NULL) {
143    struct tcp_seg *last_unsent;
144    for (last_unsent = pcb->unsent; last_unsent->next != NULL;
145         last_unsent = last_unsent->next);
146
147    if ((TCPH_FLAGS(last_unsent->tcphdr) & (TCP_SYN | TCP_FIN | TCP_RST)) == 0) {
148      /* no SYN/FIN/RST flag in the header, we can add the FIN flag */
149      TCPH_SET_FLAG(last_unsent->tcphdr, TCP_FIN);
150      pcb->flags |= TF_FIN;
151      return ERR_OK;
152    }
153  }
154  /* no data, no length, flags, copy=1, no optdata */
155  return tcp_enqueue_flags(pcb, TCP_FIN);
156}
157
158/**
159 * Create a TCP segment with prefilled header.
160 *
161 * Called by tcp_write and tcp_enqueue_flags.
162 *
163 * @param pcb Protocol control block for the TCP connection.
164 * @param p pbuf that is used to hold the TCP header.
165 * @param flags TCP flags for header.
166 * @param seqno TCP sequence number of this packet
167 * @param optflags options to include in TCP header
168 * @return a new tcp_seg pointing to p, or NULL.
169 * The TCP header is filled in except ackno and wnd.
170 * p is freed on failure.
171 */
172static struct tcp_seg *
173tcp_create_segment(struct tcp_pcb *pcb, struct pbuf *p, u8_t flags, u32_t seqno, u8_t optflags)
174{
175  struct tcp_seg *seg;
176  u8_t optlen = LWIP_TCP_OPT_LENGTH(optflags);
177
178  if ((seg = (struct tcp_seg *)memp_malloc(MEMP_TCP_SEG)) == NULL) {
179    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_create_segment: no memory.\n"));
180    pbuf_free(p);
181    return NULL;
182  }
183  seg->flags = optflags;
184  seg->next = NULL;
185  seg->p = p;
186  LWIP_ASSERT("p->tot_len >= optlen", p->tot_len >= optlen);
187  seg->len = p->tot_len - optlen;
188#if TCP_OVERSIZE_DBGCHECK
189  seg->oversize_left = 0;
190#endif /* TCP_OVERSIZE_DBGCHECK */
191#if TCP_CHECKSUM_ON_COPY
192  seg->chksum = 0;
193  seg->chksum_swapped = 0;
194  /* check optflags */
195  LWIP_ASSERT("invalid optflags passed: TF_SEG_DATA_CHECKSUMMED",
196              (optflags & TF_SEG_DATA_CHECKSUMMED) == 0);
197#endif /* TCP_CHECKSUM_ON_COPY */
198
199  /* build TCP header */
200  if (pbuf_header(p, TCP_HLEN)) {
201    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_create_segment: no room for TCP header in pbuf.\n"));
202    TCP_STATS_INC(tcp.err);
203    tcp_seg_free(seg);
204    return NULL;
205  }
206  seg->tcphdr = (struct tcp_hdr *)seg->p->payload;
207  seg->tcphdr->src = lwip_htons(pcb->local_port);
208  seg->tcphdr->dest = lwip_htons(pcb->remote_port);
209  seg->tcphdr->seqno = lwip_htonl(seqno);
210  /* ackno is set in tcp_output */
211  TCPH_HDRLEN_FLAGS_SET(seg->tcphdr, (5 + optlen / 4), flags);
212  /* wnd and chksum are set in tcp_output */
213  seg->tcphdr->urgp = 0;
214  return seg;
215}
216
217/**
218 * Allocate a PBUF_RAM pbuf, perhaps with extra space at the end.
219 *
220 * This function is like pbuf_alloc(layer, length, PBUF_RAM) except
221 * there may be extra bytes available at the end.
222 *
223 * @param layer flag to define header size.
224 * @param length size of the pbuf's payload.
225 * @param max_length maximum usable size of payload+oversize.
226 * @param oversize pointer to a u16_t that will receive the number of usable tail bytes.
227 * @param pcb The TCP connection that will enqueue the pbuf.
228 * @param apiflags API flags given to tcp_write.
229 * @param first_seg true when this pbuf will be used in the first enqueued segment.
230 */
231#if TCP_OVERSIZE
232static struct pbuf *
233tcp_pbuf_prealloc(pbuf_layer layer, u16_t length, u16_t max_length,
234                  u16_t *oversize, struct tcp_pcb *pcb, u8_t apiflags,
235                  u8_t first_seg)
236{
237  struct pbuf *p;
238  u16_t alloc = length;
239
240#if LWIP_NETIF_TX_SINGLE_PBUF
241  LWIP_UNUSED_ARG(max_length);
242  LWIP_UNUSED_ARG(pcb);
243  LWIP_UNUSED_ARG(apiflags);
244  LWIP_UNUSED_ARG(first_seg);
245  alloc = max_length;
246#else /* LWIP_NETIF_TX_SINGLE_PBUF */
247  if (length < max_length) {
248    /* Should we allocate an oversized pbuf, or just the minimum
249     * length required? If tcp_write is going to be called again
250     * before this segment is transmitted, we want the oversized
251     * buffer. If the segment will be transmitted immediately, we can
252     * save memory by allocating only length. We use a simple
253     * heuristic based on the following information:
254     *
255     * Did the user set TCP_WRITE_FLAG_MORE?
256     *
257     * Will the Nagle algorithm defer transmission of this segment?
258     */
259    if ((apiflags & TCP_WRITE_FLAG_MORE) ||
260        (!(pcb->flags & TF_NODELAY) &&
261         (!first_seg ||
262          pcb->unsent != NULL ||
263          pcb->unacked != NULL))) {
264      alloc = LWIP_MIN(max_length, LWIP_MEM_ALIGN_SIZE(TCP_OVERSIZE_CALC_LENGTH(length)));
265    }
266  }
267#endif /* LWIP_NETIF_TX_SINGLE_PBUF */
268  p = pbuf_alloc(layer, alloc, PBUF_RAM);
269  if (p == NULL) {
270    return NULL;
271  }
272  LWIP_ASSERT("need unchained pbuf", p->next == NULL);
273  *oversize = p->len - length;
274  /* trim p->len to the currently used size */
275  p->len = p->tot_len = length;
276  return p;
277}
278#else /* TCP_OVERSIZE */
279#define tcp_pbuf_prealloc(layer, length, mx, os, pcb, api, fst) pbuf_alloc((layer), (length), PBUF_RAM)
280#endif /* TCP_OVERSIZE */
281
282#if TCP_CHECKSUM_ON_COPY
283/** Add a checksum of newly added data to the segment */
284static void
285tcp_seg_add_chksum(u16_t chksum, u16_t len, u16_t *seg_chksum,
286                   u8_t *seg_chksum_swapped)
287{
288  u32_t helper;
289  /* add chksum to old chksum and fold to u16_t */
290  helper = chksum + *seg_chksum;
291  chksum = FOLD_U32T(helper);
292  if ((len & 1) != 0) {
293    *seg_chksum_swapped = 1 - *seg_chksum_swapped;
294    chksum = SWAP_BYTES_IN_WORD(chksum);
295  }
296  *seg_chksum = chksum;
297}
298#endif /* TCP_CHECKSUM_ON_COPY */
299
300/** Checks if tcp_write is allowed or not (checks state, snd_buf and snd_queuelen).
301 *
302 * @param pcb the tcp pcb to check for
303 * @param len length of data to send (checked agains snd_buf)
304 * @return ERR_OK if tcp_write is allowed to proceed, another err_t otherwise
305 */
306static err_t
307tcp_write_checks(struct tcp_pcb *pcb, u16_t len)
308{
309  /* connection is in invalid state for data transmission? */
310  if ((pcb->state != ESTABLISHED) &&
311      (pcb->state != CLOSE_WAIT) &&
312      (pcb->state != SYN_SENT) &&
313      (pcb->state != SYN_RCVD)) {
314    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_STATE | LWIP_DBG_LEVEL_SEVERE, ("tcp_write() called in invalid state\n"));
315    return ERR_CONN;
316  } else if (len == 0) {
317    return ERR_OK;
318  }
319
320  /* fail on too much data */
321  if (len > pcb->snd_buf) {
322    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("tcp_write: too much data (len=%"U16_F" > snd_buf=%"TCPWNDSIZE_F")\n",
323      len, pcb->snd_buf));
324    pcb->flags |= TF_NAGLEMEMERR;
325    return ERR_MEM;
326  }
327
328  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_write: queuelen: %"TCPWNDSIZE_F"\n", (tcpwnd_size_t)pcb->snd_queuelen));
329
330  /* If total number of pbufs on the unsent/unacked queues exceeds the
331   * configured maximum, return an error */
332  /* check for configured max queuelen and possible overflow */
333  if ((pcb->snd_queuelen >= TCP_SND_QUEUELEN) || (pcb->snd_queuelen > TCP_SNDQUEUELEN_OVERFLOW)) {
334    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("tcp_write: too long queue %"U16_F" (max %"U16_F")\n",
335      pcb->snd_queuelen, (u16_t)TCP_SND_QUEUELEN));
336    TCP_STATS_INC(tcp.memerr);
337    pcb->flags |= TF_NAGLEMEMERR;
338    return ERR_MEM;
339  }
340  if (pcb->snd_queuelen != 0) {
341    LWIP_ASSERT("tcp_write: pbufs on queue => at least one queue non-empty",
342      pcb->unacked != NULL || pcb->unsent != NULL);
343  } else {
344    LWIP_ASSERT("tcp_write: no pbufs on queue => both queues empty",
345      pcb->unacked == NULL && pcb->unsent == NULL);
346  }
347  return ERR_OK;
348}
349
350/**
351 * @ingroup tcp_raw
352 * Write data for sending (but does not send it immediately).
353 *
354 * It waits in the expectation of more data being sent soon (as
355 * it can send them more efficiently by combining them together).
356 * To prompt the system to send data now, call tcp_output() after
357 * calling tcp_write().
358 *
359 * @param pcb Protocol control block for the TCP connection to enqueue data for.
360 * @param arg Pointer to the data to be enqueued for sending.
361 * @param len Data length in bytes
362 * @param apiflags combination of following flags :
363 * - TCP_WRITE_FLAG_COPY (0x01) data will be copied into memory belonging to the stack
364 * - TCP_WRITE_FLAG_MORE (0x02) for TCP connection, PSH flag will not be set on last segment sent,
365 * @return ERR_OK if enqueued, another err_t on error
366 */
367err_t
368tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags)
369{
370  struct pbuf *concat_p = NULL;
371  struct tcp_seg *last_unsent = NULL, *seg = NULL, *prev_seg = NULL, *queue = NULL;
372  u16_t pos = 0; /* position in 'arg' data */
373  u16_t queuelen;
374  u8_t optlen = 0;
375  u8_t optflags = 0;
376#if TCP_OVERSIZE
377  u16_t oversize = 0;
378  u16_t oversize_used = 0;
379#if TCP_OVERSIZE_DBGCHECK
380  u16_t oversize_add = 0;
381#endif /* TCP_OVERSIZE_DBGCHECK*/
382#endif /* TCP_OVERSIZE */
383  u16_t extendlen = 0;
384#if TCP_CHECKSUM_ON_COPY
385  u16_t concat_chksum = 0;
386  u8_t concat_chksum_swapped = 0;
387  u16_t concat_chksummed = 0;
388#endif /* TCP_CHECKSUM_ON_COPY */
389  err_t err;
390  /* don't allocate segments bigger than half the maximum window we ever received */
391  u16_t mss_local = LWIP_MIN(pcb->mss, TCPWND_MIN16(pcb->snd_wnd_max/2));
392  mss_local = mss_local ? mss_local : pcb->mss;
393
394#if LWIP_NETIF_TX_SINGLE_PBUF
395  /* Always copy to try to create single pbufs for TX */
396  apiflags |= TCP_WRITE_FLAG_COPY;
397#endif /* LWIP_NETIF_TX_SINGLE_PBUF */
398
399  LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_write(pcb=%p, data=%p, len=%"U16_F", apiflags=%"U16_F")\n",
400    (void *)pcb, arg, len, (u16_t)apiflags));
401  LWIP_ERROR("tcp_write: arg == NULL (programmer violates API)",
402             arg != NULL, return ERR_ARG;);
403
404  err = tcp_write_checks(pcb, len);
405  if (err != ERR_OK) {
406    return err;
407  }
408  queuelen = pcb->snd_queuelen;
409
410#if LWIP_TCP_TIMESTAMPS
411  if ((pcb->flags & TF_TIMESTAMP)) {
412    /* Make sure the timestamp option is only included in data segments if we
413       agreed about it with the remote host. */
414    optflags = TF_SEG_OPTS_TS;
415    optlen = LWIP_TCP_OPT_LENGTH(TF_SEG_OPTS_TS);
416    /* ensure that segments can hold at least one data byte... */
417    mss_local = LWIP_MAX(mss_local, LWIP_TCP_OPT_LEN_TS + 1);
418  }
419#endif /* LWIP_TCP_TIMESTAMPS */
420
421
422  /*
423   * TCP segmentation is done in three phases with increasing complexity:
424   *
425   * 1. Copy data directly into an oversized pbuf.
426   * 2. Chain a new pbuf to the end of pcb->unsent.
427   * 3. Create new segments.
428   *
429   * We may run out of memory at any point. In that case we must
430   * return ERR_MEM and not change anything in pcb. Therefore, all
431   * changes are recorded in local variables and committed at the end
432   * of the function. Some pcb fields are maintained in local copies:
433   *
434   * queuelen = pcb->snd_queuelen
435   * oversize = pcb->unsent_oversize
436   *
437   * These variables are set consistently by the phases:
438   *
439   * seg points to the last segment tampered with.
440   *
441   * pos records progress as data is segmented.
442   */
443
444  /* Find the tail of the unsent queue. */
445  if (pcb->unsent != NULL) {
446    u16_t space;
447    u16_t unsent_optlen;
448
449    /* @todo: this could be sped up by keeping last_unsent in the pcb */
450    for (last_unsent = pcb->unsent; last_unsent->next != NULL;
451         last_unsent = last_unsent->next);
452
453    /* Usable space at the end of the last unsent segment */
454    unsent_optlen = LWIP_TCP_OPT_LENGTH(last_unsent->flags);
455    LWIP_ASSERT("mss_local is too small", mss_local >= last_unsent->len + unsent_optlen);
456    space = mss_local - (last_unsent->len + unsent_optlen);
457
458    /*
459     * Phase 1: Copy data directly into an oversized pbuf.
460     *
461     * The number of bytes copied is recorded in the oversize_used
462     * variable. The actual copying is done at the bottom of the
463     * function.
464     */
465#if TCP_OVERSIZE
466#if TCP_OVERSIZE_DBGCHECK
467    /* check that pcb->unsent_oversize matches last_unsent->oversize_left */
468    LWIP_ASSERT("unsent_oversize mismatch (pcb vs. last_unsent)",
469                pcb->unsent_oversize == last_unsent->oversize_left);
470#endif /* TCP_OVERSIZE_DBGCHECK */
471    oversize = pcb->unsent_oversize;
472    if (oversize > 0) {
473      LWIP_ASSERT("inconsistent oversize vs. space", oversize <= space);
474      seg = last_unsent;
475      oversize_used = LWIP_MIN(space, LWIP_MIN(oversize, len));
476      pos += oversize_used;
477      oversize -= oversize_used;
478      space -= oversize_used;
479    }
480    /* now we are either finished or oversize is zero */
481    LWIP_ASSERT("inconsistent oversize vs. len", (oversize == 0) || (pos == len));
482#endif /* TCP_OVERSIZE */
483
484    /*
485     * Phase 2: Chain a new pbuf to the end of pcb->unsent.
486     *
487     * As an exception when NOT copying the data, if the given data buffer
488     * directly follows the last unsent data buffer in memory, extend the last
489     * ROM pbuf reference to the buffer, thus saving a ROM pbuf allocation.
490     *
491     * We don't extend segments containing SYN/FIN flags or options
492     * (len==0). The new pbuf is kept in concat_p and pbuf_cat'ed at
493     * the end.
494     */
495    if ((pos < len) && (space > 0) && (last_unsent->len > 0)) {
496      u16_t seglen = LWIP_MIN(space, len - pos);
497      seg = last_unsent;
498
499      /* Create a pbuf with a copy or reference to seglen bytes. We
500       * can use PBUF_RAW here since the data appears in the middle of
501       * a segment. A header will never be prepended. */
502      if (apiflags & TCP_WRITE_FLAG_COPY) {
503        /* Data is copied */
504        if ((concat_p = tcp_pbuf_prealloc(PBUF_RAW, seglen, space, &oversize, pcb, apiflags, 1)) == NULL) {
505          LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
506                      ("tcp_write : could not allocate memory for pbuf copy size %"U16_F"\n",
507                       seglen));
508          goto memerr;
509        }
510#if TCP_OVERSIZE_DBGCHECK
511        oversize_add = oversize;
512#endif /* TCP_OVERSIZE_DBGCHECK */
513        TCP_DATA_COPY2(concat_p->payload, (const u8_t*)arg + pos, seglen, &concat_chksum, &concat_chksum_swapped);
514#if TCP_CHECKSUM_ON_COPY
515        concat_chksummed += seglen;
516#endif /* TCP_CHECKSUM_ON_COPY */
517        queuelen += pbuf_clen(concat_p);
518      } else {
519        /* Data is not copied */
520        /* If the last unsent pbuf is of type PBUF_ROM, try to extend it. */
521        struct pbuf *p;
522        for (p = last_unsent->p; p->next != NULL; p = p->next);
523        if (p->type == PBUF_ROM && (const u8_t *)p->payload + p->len == (const u8_t *)arg) {
524          LWIP_ASSERT("tcp_write: ROM pbufs cannot be oversized", pos == 0);
525          extendlen = seglen;
526        } else {
527          if ((concat_p = pbuf_alloc(PBUF_RAW, seglen, PBUF_ROM)) == NULL) {
528            LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
529                        ("tcp_write: could not allocate memory for zero-copy pbuf\n"));
530            goto memerr;
531          }
532          /* reference the non-volatile payload data */
533          ((struct pbuf_rom*)concat_p)->payload = (const u8_t*)arg + pos;
534          queuelen += pbuf_clen(concat_p);
535        }
536#if TCP_CHECKSUM_ON_COPY
537        /* calculate the checksum of nocopy-data */
538        tcp_seg_add_chksum(~inet_chksum((const u8_t*)arg + pos, seglen), seglen,
539          &concat_chksum, &concat_chksum_swapped);
540        concat_chksummed += seglen;
541#endif /* TCP_CHECKSUM_ON_COPY */
542      }
543
544      pos += seglen;
545    }
546  } else {
547#if TCP_OVERSIZE
548    LWIP_ASSERT("unsent_oversize mismatch (pcb->unsent is NULL)",
549                pcb->unsent_oversize == 0);
550#endif /* TCP_OVERSIZE */
551  }
552
553  /*
554   * Phase 3: Create new segments.
555   *
556   * The new segments are chained together in the local 'queue'
557   * variable, ready to be appended to pcb->unsent.
558   */
559  while (pos < len) {
560    struct pbuf *p;
561    u16_t left = len - pos;
562    u16_t max_len = mss_local - optlen;
563    u16_t seglen = LWIP_MIN(left, max_len);
564#if TCP_CHECKSUM_ON_COPY
565    u16_t chksum = 0;
566    u8_t chksum_swapped = 0;
567#endif /* TCP_CHECKSUM_ON_COPY */
568
569    if (apiflags & TCP_WRITE_FLAG_COPY) {
570      /* If copy is set, memory should be allocated and data copied
571       * into pbuf */
572      if ((p = tcp_pbuf_prealloc(PBUF_TRANSPORT, seglen + optlen, mss_local, &oversize, pcb, apiflags, queue == NULL)) == NULL) {
573        LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_write : could not allocate memory for pbuf copy size %"U16_F"\n", seglen));
574        goto memerr;
575      }
576      LWIP_ASSERT("tcp_write: check that first pbuf can hold the complete seglen",
577                  (p->len >= seglen));
578      TCP_DATA_COPY2((char *)p->payload + optlen, (const u8_t*)arg + pos, seglen, &chksum, &chksum_swapped);
579    } else {
580      /* Copy is not set: First allocate a pbuf for holding the data.
581       * Since the referenced data is available at least until it is
582       * sent out on the link (as it has to be ACKed by the remote
583       * party) we can safely use PBUF_ROM instead of PBUF_REF here.
584       */
585      struct pbuf *p2;
586#if TCP_OVERSIZE
587      LWIP_ASSERT("oversize == 0", oversize == 0);
588#endif /* TCP_OVERSIZE */
589      if ((p2 = pbuf_alloc(PBUF_TRANSPORT, seglen, PBUF_ROM)) == NULL) {
590        LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_write: could not allocate memory for zero-copy pbuf\n"));
591        goto memerr;
592      }
593#if TCP_CHECKSUM_ON_COPY
594      /* calculate the checksum of nocopy-data */
595      chksum = ~inet_chksum((const u8_t*)arg + pos, seglen);
596      if (seglen & 1) {
597        chksum_swapped = 1;
598        chksum = SWAP_BYTES_IN_WORD(chksum);
599      }
600#endif /* TCP_CHECKSUM_ON_COPY */
601      /* reference the non-volatile payload data */
602      ((struct pbuf_rom*)p2)->payload = (const u8_t*)arg + pos;
603
604      /* Second, allocate a pbuf for the headers. */
605      if ((p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) {
606        /* If allocation fails, we have to deallocate the data pbuf as
607         * well. */
608        pbuf_free(p2);
609        LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_write: could not allocate memory for header pbuf\n"));
610        goto memerr;
611      }
612      /* Concatenate the headers and data pbufs together. */
613      pbuf_cat(p/*header*/, p2/*data*/);
614    }
615
616    queuelen += pbuf_clen(p);
617
618    /* Now that there are more segments queued, we check again if the
619     * length of the queue exceeds the configured maximum or
620     * overflows. */
621    if ((queuelen > TCP_SND_QUEUELEN) || (queuelen > TCP_SNDQUEUELEN_OVERFLOW)) {
622      LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_write: queue too long %"U16_F" (%d)\n",
623        queuelen, (int)TCP_SND_QUEUELEN));
624      pbuf_free(p);
625      goto memerr;
626    }
627
628    if ((seg = tcp_create_segment(pcb, p, 0, pcb->snd_lbb + pos, optflags)) == NULL) {
629      goto memerr;
630    }
631#if TCP_OVERSIZE_DBGCHECK
632    seg->oversize_left = oversize;
633#endif /* TCP_OVERSIZE_DBGCHECK */
634#if TCP_CHECKSUM_ON_COPY
635    seg->chksum = chksum;
636    seg->chksum_swapped = chksum_swapped;
637    seg->flags |= TF_SEG_DATA_CHECKSUMMED;
638#endif /* TCP_CHECKSUM_ON_COPY */
639
640    /* first segment of to-be-queued data? */
641    if (queue == NULL) {
642      queue = seg;
643    } else {
644      /* Attach the segment to the end of the queued segments */
645      LWIP_ASSERT("prev_seg != NULL", prev_seg != NULL);
646      prev_seg->next = seg;
647    }
648    /* remember last segment of to-be-queued data for next iteration */
649    prev_seg = seg;
650
651    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_TRACE, ("tcp_write: queueing %"U32_F":%"U32_F"\n",
652      lwip_ntohl(seg->tcphdr->seqno),
653      lwip_ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg)));
654
655    pos += seglen;
656  }
657
658  /*
659   * All three segmentation phases were successful. We can commit the
660   * transaction.
661   */
662#if TCP_OVERSIZE_DBGCHECK
663  if ((last_unsent != NULL) && (oversize_add != 0)) {
664    last_unsent->oversize_left += oversize_add;
665  }
666#endif /* TCP_OVERSIZE_DBGCHECK */
667
668  /*
669   * Phase 1: If data has been added to the preallocated tail of
670   * last_unsent, we update the length fields of the pbuf chain.
671   */
672#if TCP_OVERSIZE
673  if (oversize_used > 0) {
674    struct pbuf *p;
675    /* Bump tot_len of whole chain, len of tail */
676    for (p = last_unsent->p; p; p = p->next) {
677      p->tot_len += oversize_used;
678      if (p->next == NULL) {
679        TCP_DATA_COPY((char *)p->payload + p->len, arg, oversize_used, last_unsent);
680        p->len += oversize_used;
681      }
682    }
683    last_unsent->len += oversize_used;
684#if TCP_OVERSIZE_DBGCHECK
685    LWIP_ASSERT("last_unsent->oversize_left >= oversize_used",
686                last_unsent->oversize_left >= oversize_used);
687    last_unsent->oversize_left -= oversize_used;
688#endif /* TCP_OVERSIZE_DBGCHECK */
689  }
690  pcb->unsent_oversize = oversize;
691#endif /* TCP_OVERSIZE */
692
693  /*
694   * Phase 2: concat_p can be concatenated onto last_unsent->p, unless we
695   * determined that the last ROM pbuf can be extended to include the new data.
696   */
697  if (concat_p != NULL) {
698    LWIP_ASSERT("tcp_write: cannot concatenate when pcb->unsent is empty",
699      (last_unsent != NULL));
700    pbuf_cat(last_unsent->p, concat_p);
701    last_unsent->len += concat_p->tot_len;
702  } else if (extendlen > 0) {
703    struct pbuf *p;
704    LWIP_ASSERT("tcp_write: extension of reference requires reference",
705      last_unsent != NULL && last_unsent->p != NULL);
706    for (p = last_unsent->p; p->next != NULL; p = p->next) {
707      p->tot_len += extendlen;
708    }
709    p->tot_len += extendlen;
710    p->len += extendlen;
711    last_unsent->len += extendlen;
712  }
713
714#if TCP_CHECKSUM_ON_COPY
715  if (concat_chksummed) {
716    LWIP_ASSERT("tcp_write: concat checksum needs concatenated data",
717        concat_p != NULL || extendlen > 0);
718    /*if concat checksumm swapped - swap it back */
719    if (concat_chksum_swapped) {
720      concat_chksum = SWAP_BYTES_IN_WORD(concat_chksum);
721    }
722    tcp_seg_add_chksum(concat_chksum, concat_chksummed, &last_unsent->chksum,
723      &last_unsent->chksum_swapped);
724    last_unsent->flags |= TF_SEG_DATA_CHECKSUMMED;
725  }
726#endif /* TCP_CHECKSUM_ON_COPY */
727
728  /*
729   * Phase 3: Append queue to pcb->unsent. Queue may be NULL, but that
730   * is harmless
731   */
732  if (last_unsent == NULL) {
733    pcb->unsent = queue;
734  } else {
735    last_unsent->next = queue;
736  }
737
738  /*
739   * Finally update the pcb state.
740   */
741  pcb->snd_lbb += len;
742  pcb->snd_buf -= len;
743  pcb->snd_queuelen = queuelen;
744
745  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_write: %"S16_F" (after enqueued)\n",
746    pcb->snd_queuelen));
747  if (pcb->snd_queuelen != 0) {
748    LWIP_ASSERT("tcp_write: valid queue length",
749                pcb->unacked != NULL || pcb->unsent != NULL);
750  }
751
752  /* Set the PSH flag in the last segment that we enqueued. */
753  if (seg != NULL && seg->tcphdr != NULL && ((apiflags & TCP_WRITE_FLAG_MORE)==0)) {
754    TCPH_SET_FLAG(seg->tcphdr, TCP_PSH);
755  }
756
757  return ERR_OK;
758memerr:
759  pcb->flags |= TF_NAGLEMEMERR;
760  TCP_STATS_INC(tcp.memerr);
761
762  if (concat_p != NULL) {
763    pbuf_free(concat_p);
764  }
765  if (queue != NULL) {
766    tcp_segs_free(queue);
767  }
768  if (pcb->snd_queuelen != 0) {
769    LWIP_ASSERT("tcp_write: valid queue length", pcb->unacked != NULL ||
770      pcb->unsent != NULL);
771  }
772  LWIP_DEBUGF(TCP_QLEN_DEBUG | LWIP_DBG_STATE, ("tcp_write: %"S16_F" (with mem err)\n", pcb->snd_queuelen));
773  return ERR_MEM;
774}
775
776/**
777 * Enqueue TCP options for transmission.
778 *
779 * Called by tcp_connect(), tcp_listen_input(), and tcp_send_ctrl().
780 *
781 * @param pcb Protocol control block for the TCP connection.
782 * @param flags TCP header flags to set in the outgoing segment.
783 */
784err_t
785tcp_enqueue_flags(struct tcp_pcb *pcb, u8_t flags)
786{
787  struct pbuf *p;
788  struct tcp_seg *seg;
789  u8_t optflags = 0;
790  u8_t optlen = 0;
791
792  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue_flags: queuelen: %"U16_F"\n", (u16_t)pcb->snd_queuelen));
793
794  LWIP_ASSERT("tcp_enqueue_flags: need either TCP_SYN or TCP_FIN in flags (programmer violates API)",
795              (flags & (TCP_SYN | TCP_FIN)) != 0);
796
797  /* check for configured max queuelen and possible overflow (FIN flag should always come through!) */
798  if (((pcb->snd_queuelen >= TCP_SND_QUEUELEN) || (pcb->snd_queuelen > TCP_SNDQUEUELEN_OVERFLOW)) &&
799      ((flags & TCP_FIN) == 0)) {
800    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("tcp_enqueue_flags: too long queue %"U16_F" (max %"U16_F")\n",
801                                       pcb->snd_queuelen, (u16_t)TCP_SND_QUEUELEN));
802    TCP_STATS_INC(tcp.memerr);
803    pcb->flags |= TF_NAGLEMEMERR;
804    return ERR_MEM;
805  }
806
807  if (flags & TCP_SYN) {
808    optflags = TF_SEG_OPTS_MSS;
809#if LWIP_WND_SCALE
810    if ((pcb->state != SYN_RCVD) || (pcb->flags & TF_WND_SCALE)) {
811      /* In a <SYN,ACK> (sent in state SYN_RCVD), the window scale option may only
812         be sent if we received a window scale option from the remote host. */
813      optflags |= TF_SEG_OPTS_WND_SCALE;
814    }
815#endif /* LWIP_WND_SCALE */
816  }
817#if LWIP_TCP_TIMESTAMPS
818  if ((pcb->flags & TF_TIMESTAMP)) {
819    /* Make sure the timestamp option is only included in data segments if we
820       agreed about it with the remote host. */
821    optflags |= TF_SEG_OPTS_TS;
822  }
823#endif /* LWIP_TCP_TIMESTAMPS */
824  optlen = LWIP_TCP_OPT_LENGTH(optflags);
825
826  /* Allocate pbuf with room for TCP header + options */
827  if ((p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) {
828    pcb->flags |= TF_NAGLEMEMERR;
829    TCP_STATS_INC(tcp.memerr);
830    return ERR_MEM;
831  }
832  LWIP_ASSERT("tcp_enqueue_flags: check that first pbuf can hold optlen",
833              (p->len >= optlen));
834
835  /* Allocate memory for tcp_seg, and fill in fields. */
836  if ((seg = tcp_create_segment(pcb, p, flags, pcb->snd_lbb, optflags)) == NULL) {
837    pcb->flags |= TF_NAGLEMEMERR;
838    TCP_STATS_INC(tcp.memerr);
839    return ERR_MEM;
840  }
841  LWIP_ASSERT("seg->tcphdr not aligned", ((mem_ptr_t)seg->tcphdr % LWIP_MIN(MEM_ALIGNMENT, 4)) == 0);
842  LWIP_ASSERT("tcp_enqueue_flags: invalid segment length", seg->len == 0);
843
844  LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_TRACE,
845              ("tcp_enqueue_flags: queueing %"U32_F":%"U32_F" (0x%"X16_F")\n",
846               lwip_ntohl(seg->tcphdr->seqno),
847               lwip_ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg),
848               (u16_t)flags));
849
850  /* Now append seg to pcb->unsent queue */
851  if (pcb->unsent == NULL) {
852    pcb->unsent = seg;
853  } else {
854    struct tcp_seg *useg;
855    for (useg = pcb->unsent; useg->next != NULL; useg = useg->next);
856    useg->next = seg;
857  }
858#if TCP_OVERSIZE
859  /* The new unsent tail has no space */
860  pcb->unsent_oversize = 0;
861#endif /* TCP_OVERSIZE */
862
863  /* SYN and FIN bump the sequence number */
864  if ((flags & TCP_SYN) || (flags & TCP_FIN)) {
865    pcb->snd_lbb++;
866    /* optlen does not influence snd_buf */
867  }
868  if (flags & TCP_FIN) {
869    pcb->flags |= TF_FIN;
870  }
871
872  /* update number of segments on the queues */
873  pcb->snd_queuelen += pbuf_clen(seg->p);
874  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue_flags: %"S16_F" (after enqueued)\n", pcb->snd_queuelen));
875  if (pcb->snd_queuelen != 0) {
876    LWIP_ASSERT("tcp_enqueue_flags: invalid queue length",
877      pcb->unacked != NULL || pcb->unsent != NULL);
878  }
879
880  return ERR_OK;
881}
882
883#if LWIP_TCP_TIMESTAMPS
884/* Build a timestamp option (12 bytes long) at the specified options pointer)
885 *
886 * @param pcb tcp_pcb
887 * @param opts option pointer where to store the timestamp option
888 */
889static void
890tcp_build_timestamp_option(struct tcp_pcb *pcb, u32_t *opts)
891{
892  /* Pad with two NOP options to make everything nicely aligned */
893  opts[0] = PP_HTONL(0x0101080A);
894  opts[1] = lwip_htonl(sys_now());
895  opts[2] = lwip_htonl(pcb->ts_recent);
896}
897#endif
898
899#if LWIP_WND_SCALE
900/** Build a window scale option (3 bytes long) at the specified options pointer)
901 *
902 * @param opts option pointer where to store the window scale option
903 */
904static void
905tcp_build_wnd_scale_option(u32_t *opts)
906{
907  /* Pad with one NOP option to make everything nicely aligned */
908  opts[0] = PP_HTONL(0x01030300 | TCP_RCV_SCALE);
909}
910#endif
911
912/**
913 * Send an ACK without data.
914 *
915 * @param pcb Protocol control block for the TCP connection to send the ACK
916 */
917err_t
918tcp_send_empty_ack(struct tcp_pcb *pcb)
919{
920  err_t err;
921  struct pbuf *p;
922  u8_t optlen = 0;
923  struct netif *netif;
924#if LWIP_TCP_TIMESTAMPS || CHECKSUM_GEN_TCP
925  struct tcp_hdr *tcphdr;
926#endif /* LWIP_TCP_TIMESTAMPS || CHECKSUM_GEN_TCP */
927
928#if LWIP_TCP_TIMESTAMPS
929  if (pcb->flags & TF_TIMESTAMP) {
930    optlen = LWIP_TCP_OPT_LENGTH(TF_SEG_OPTS_TS);
931  }
932#endif
933
934  p = tcp_output_alloc_header(pcb, optlen, 0, lwip_htonl(pcb->snd_nxt));
935  if (p == NULL) {
936    /* let tcp_fasttmr retry sending this ACK */
937    pcb->flags |= (TF_ACK_DELAY | TF_ACK_NOW);
938    LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: (ACK) could not allocate pbuf\n"));
939    return ERR_BUF;
940  }
941#if LWIP_TCP_TIMESTAMPS || CHECKSUM_GEN_TCP
942  tcphdr = (struct tcp_hdr *)p->payload;
943#endif /* LWIP_TCP_TIMESTAMPS || CHECKSUM_GEN_TCP */
944  LWIP_DEBUGF(TCP_OUTPUT_DEBUG,
945              ("tcp_output: sending ACK for %"U32_F"\n", pcb->rcv_nxt));
946
947  /* NB. MSS and window scale options are only sent on SYNs, so ignore them here */
948#if LWIP_TCP_TIMESTAMPS
949  pcb->ts_lastacksent = pcb->rcv_nxt;
950
951  if (pcb->flags & TF_TIMESTAMP) {
952    tcp_build_timestamp_option(pcb, (u32_t *)(tcphdr + 1));
953  }
954#endif
955
956  netif = ip_route(&pcb->local_ip, &pcb->remote_ip);
957  if (netif == NULL) {
958    err = ERR_RTE;
959  } else {
960#if CHECKSUM_GEN_TCP
961    IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_TCP) {
962      tcphdr->chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len,
963        &pcb->local_ip, &pcb->remote_ip);
964    }
965#endif
966    NETIF_SET_HWADDRHINT(netif, &(pcb->addr_hint));
967    err = ip_output_if(p, &pcb->local_ip, &pcb->remote_ip,
968      pcb->ttl, pcb->tos, IP_PROTO_TCP, netif);
969    NETIF_SET_HWADDRHINT(netif, NULL);
970  }
971  pbuf_free(p);
972
973  if (err != ERR_OK) {
974    /* let tcp_fasttmr retry sending this ACK */
975    pcb->flags |= (TF_ACK_DELAY | TF_ACK_NOW);
976  } else {
977    /* remove ACK flags from the PCB, as we sent an empty ACK now */
978    pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
979  }
980
981  return err;
982}
983
984/**
985 * @ingroup tcp_raw
986 * Find out what we can send and send it
987 *
988 * @param pcb Protocol control block for the TCP connection to send data
989 * @return ERR_OK if data has been sent or nothing to send
990 *         another err_t on error
991 */
992err_t
993tcp_output(struct tcp_pcb *pcb)
994{
995  struct tcp_seg *seg, *useg;
996  u32_t wnd, snd_nxt;
997  err_t err;
998  struct netif *netif;
999#if TCP_CWND_DEBUG
1000  s16_t i = 0;
1001#endif /* TCP_CWND_DEBUG */
1002
1003  /* pcb->state LISTEN not allowed here */
1004  LWIP_ASSERT("don't call tcp_output for listen-pcbs",
1005    pcb->state != LISTEN);
1006
1007  /* First, check if we are invoked by the TCP input processing
1008     code. If so, we do not output anything. Instead, we rely on the
1009     input processing code to call us when input processing is done
1010     with. */
1011  if (tcp_input_pcb == pcb) {
1012    return ERR_OK;
1013  }
1014
1015  wnd = LWIP_MIN(pcb->snd_wnd, pcb->cwnd);
1016
1017  seg = pcb->unsent;
1018
1019  /* If the TF_ACK_NOW flag is set and no data will be sent (either
1020   * because the ->unsent queue is empty or because the window does
1021   * not allow it), construct an empty ACK segment and send it.
1022   *
1023   * If data is to be sent, we will just piggyback the ACK (see below).
1024   */
1025  if (pcb->flags & TF_ACK_NOW &&
1026     (seg == NULL ||
1027      lwip_ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len > wnd)) {
1028     return tcp_send_empty_ack(pcb);
1029  }
1030
1031  /* useg should point to last segment on unacked queue */
1032  useg = pcb->unacked;
1033  if (useg != NULL) {
1034    for (; useg->next != NULL; useg = useg->next);
1035  }
1036
1037  netif = ip_route(&pcb->local_ip, &pcb->remote_ip);
1038  if (netif == NULL) {
1039    return ERR_RTE;
1040  }
1041
1042  /* If we don't have a local IP address, we get one from netif */
1043  if (ip_addr_isany(&pcb->local_ip)) {
1044    const ip_addr_t *local_ip = ip_netif_get_local_ip(netif, &pcb->remote_ip);
1045    if (local_ip == NULL) {
1046      return ERR_RTE;
1047    }
1048    ip_addr_copy(pcb->local_ip, *local_ip);
1049  }
1050
1051#if TCP_OUTPUT_DEBUG
1052  if (seg == NULL) {
1053    LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: nothing to send (%p)\n",
1054                                   (void*)pcb->unsent));
1055  }
1056#endif /* TCP_OUTPUT_DEBUG */
1057#if TCP_CWND_DEBUG
1058  if (seg == NULL) {
1059    LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"TCPWNDSIZE_F
1060                                 ", cwnd %"TCPWNDSIZE_F", wnd %"U32_F
1061                                 ", seg == NULL, ack %"U32_F"\n",
1062                                 pcb->snd_wnd, pcb->cwnd, wnd, pcb->lastack));
1063  } else {
1064    LWIP_DEBUGF(TCP_CWND_DEBUG,
1065                ("tcp_output: snd_wnd %"TCPWNDSIZE_F", cwnd %"TCPWNDSIZE_F", wnd %"U32_F
1066                 ", effwnd %"U32_F", seq %"U32_F", ack %"U32_F"\n",
1067                 pcb->snd_wnd, pcb->cwnd, wnd,
1068                 lwip_ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len,
1069                 lwip_ntohl(seg->tcphdr->seqno), pcb->lastack));
1070  }
1071#endif /* TCP_CWND_DEBUG */
1072  /* Check if we need to start the persistent timer when the next unsent segment
1073   * does not fit within the remaining send window and RTO timer is not running (we
1074   * have no in-flight data). A traditional approach would fill the remaining window
1075   * with part of the unsent segment (which will engage zero-window probing upon
1076   * reception of the zero window update from the receiver). This ensures the
1077   * subsequent window update is reliably received. With the goal of being lightweight,
1078   * we avoid splitting the unsent segment and treat the window as already zero.
1079   */
1080  if (seg != NULL &&
1081      lwip_ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len > wnd &&
1082      wnd > 0 && wnd == pcb->snd_wnd && pcb->unacked == NULL) {
1083    /* Start the persist timer */
1084    if (pcb->persist_backoff == 0) {
1085      pcb->persist_cnt = 0;
1086      pcb->persist_backoff = 1;
1087    }
1088    goto output_done;
1089  }
1090  /* data available and window allows it to be sent? */
1091  while (seg != NULL &&
1092         lwip_ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) {
1093    LWIP_ASSERT("RST not expected here!",
1094                (TCPH_FLAGS(seg->tcphdr) & TCP_RST) == 0);
1095    /* Stop sending if the nagle algorithm would prevent it
1096     * Don't stop:
1097     * - if tcp_write had a memory error before (prevent delayed ACK timeout) or
1098     * - if FIN was already enqueued for this PCB (SYN is always alone in a segment -
1099     *   either seg->next != NULL or pcb->unacked == NULL;
1100     *   RST is no sent using tcp_write/tcp_output.
1101     */
1102    if ((tcp_do_output_nagle(pcb) == 0) &&
1103      ((pcb->flags & (TF_NAGLEMEMERR | TF_FIN)) == 0)) {
1104      break;
1105    }
1106#if TCP_CWND_DEBUG
1107    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",
1108                            pcb->snd_wnd, pcb->cwnd, wnd,
1109                            lwip_ntohl(seg->tcphdr->seqno) + seg->len -
1110                            pcb->lastack,
1111                            lwip_ntohl(seg->tcphdr->seqno), pcb->lastack, i));
1112    ++i;
1113#endif /* TCP_CWND_DEBUG */
1114
1115    if (pcb->state != SYN_SENT) {
1116      TCPH_SET_FLAG(seg->tcphdr, TCP_ACK);
1117    }
1118
1119#if TCP_OVERSIZE_DBGCHECK
1120    seg->oversize_left = 0;
1121#endif /* TCP_OVERSIZE_DBGCHECK */
1122    err = tcp_output_segment(seg, pcb, netif);
1123    if (err != ERR_OK) {
1124      /* segment could not be sent, for whatever reason */
1125      pcb->flags |= TF_NAGLEMEMERR;
1126      return err;
1127    }
1128    pcb->unsent = seg->next;
1129    if (pcb->state != SYN_SENT) {
1130      pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
1131    }
1132    snd_nxt = lwip_ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg);
1133    if (TCP_SEQ_LT(pcb->snd_nxt, snd_nxt)) {
1134      pcb->snd_nxt = snd_nxt;
1135    }
1136    /* put segment on unacknowledged list if length > 0 */
1137    if (TCP_TCPLEN(seg) > 0) {
1138      seg->next = NULL;
1139      /* unacked list is empty? */
1140      if (pcb->unacked == NULL) {
1141        pcb->unacked = seg;
1142        useg = seg;
1143      /* unacked list is not empty? */
1144      } else {
1145        /* In the case of fast retransmit, the packet should not go to the tail
1146         * of the unacked queue, but rather somewhere before it. We need to check for
1147         * this case. -STJ Jul 27, 2004 */
1148        if (TCP_SEQ_LT(lwip_ntohl(seg->tcphdr->seqno), lwip_ntohl(useg->tcphdr->seqno))) {
1149          /* add segment to before tail of unacked list, keeping the list sorted */
1150          struct tcp_seg **cur_seg = &(pcb->unacked);
1151          while (*cur_seg &&
1152            TCP_SEQ_LT(lwip_ntohl((*cur_seg)->tcphdr->seqno), lwip_ntohl(seg->tcphdr->seqno))) {
1153              cur_seg = &((*cur_seg)->next );
1154          }
1155          seg->next = (*cur_seg);
1156          (*cur_seg) = seg;
1157        } else {
1158          /* add segment to tail of unacked list */
1159          useg->next = seg;
1160          useg = useg->next;
1161        }
1162      }
1163    /* do not queue empty segments on the unacked list */
1164    } else {
1165      tcp_seg_free(seg);
1166    }
1167    seg = pcb->unsent;
1168  }
1169output_done:
1170#if TCP_OVERSIZE
1171  if (pcb->unsent == NULL) {
1172    /* last unsent has been removed, reset unsent_oversize */
1173    pcb->unsent_oversize = 0;
1174  }
1175#endif /* TCP_OVERSIZE */
1176
1177  pcb->flags &= ~TF_NAGLEMEMERR;
1178  return ERR_OK;
1179}
1180
1181/**
1182 * Called by tcp_output() to actually send a TCP segment over IP.
1183 *
1184 * @param seg the tcp_seg to send
1185 * @param pcb the tcp_pcb for the TCP connection used to send the segment
1186 * @param netif the netif used to send the segment
1187 */
1188static err_t
1189tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif)
1190{
1191  err_t err;
1192  u16_t len;
1193  u32_t *opts;
1194
1195  if (seg->p->ref != 1) {
1196    /* This can happen if the pbuf of this segment is still referenced by the
1197       netif driver due to deferred transmission. Since this function modifies
1198       p->len, we must not continue in this case. */
1199    return ERR_OK;
1200  }
1201
1202  /* The TCP header has already been constructed, but the ackno and
1203   wnd fields remain. */
1204  seg->tcphdr->ackno = lwip_htonl(pcb->rcv_nxt);
1205
1206  /* advertise our receive window size in this TCP segment */
1207#if LWIP_WND_SCALE
1208  if (seg->flags & TF_SEG_OPTS_WND_SCALE) {
1209    /* The Window field in a SYN segment itself (the only type where we send
1210       the window scale option) is never scaled. */
1211    seg->tcphdr->wnd = lwip_htons(TCPWND_MIN16(pcb->rcv_ann_wnd));
1212  } else
1213#endif /* LWIP_WND_SCALE */
1214  {
1215    seg->tcphdr->wnd = lwip_htons(TCPWND_MIN16(RCV_WND_SCALE(pcb, pcb->rcv_ann_wnd)));
1216  }
1217
1218  pcb->rcv_ann_right_edge = pcb->rcv_nxt + pcb->rcv_ann_wnd;
1219
1220  /* Add any requested options.  NB MSS option is only set on SYN
1221     packets, so ignore it here */
1222  /* cast through void* to get rid of alignment warnings */
1223  opts = (u32_t *)(void *)(seg->tcphdr + 1);
1224  if (seg->flags & TF_SEG_OPTS_MSS) {
1225    u16_t mss;
1226#if TCP_CALCULATE_EFF_SEND_MSS
1227    mss = tcp_eff_send_mss(TCP_MSS, &pcb->local_ip, &pcb->remote_ip);
1228#else /* TCP_CALCULATE_EFF_SEND_MSS */
1229    mss = TCP_MSS;
1230#endif /* TCP_CALCULATE_EFF_SEND_MSS */
1231    *opts = TCP_BUILD_MSS_OPTION(mss);
1232    opts += 1;
1233  }
1234#if LWIP_TCP_TIMESTAMPS
1235  pcb->ts_lastacksent = pcb->rcv_nxt;
1236
1237  if (seg->flags & TF_SEG_OPTS_TS) {
1238    tcp_build_timestamp_option(pcb, opts);
1239    opts += 3;
1240  }
1241#endif
1242#if LWIP_WND_SCALE
1243  if (seg->flags & TF_SEG_OPTS_WND_SCALE) {
1244    tcp_build_wnd_scale_option(opts);
1245    opts += 1;
1246  }
1247#endif
1248
1249  /* Set retransmission timer running if it is not currently enabled
1250     This must be set before checking the route. */
1251  if (pcb->rtime < 0) {
1252    pcb->rtime = 0;
1253  }
1254
1255  if (pcb->rttest == 0) {
1256    pcb->rttest = tcp_ticks;
1257    pcb->rtseq = lwip_ntohl(seg->tcphdr->seqno);
1258
1259    LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_output_segment: rtseq %"U32_F"\n", pcb->rtseq));
1260  }
1261  LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output_segment: %"U32_F":%"U32_F"\n",
1262          lwip_htonl(seg->tcphdr->seqno), lwip_htonl(seg->tcphdr->seqno) +
1263          seg->len));
1264
1265  len = (u16_t)((u8_t *)seg->tcphdr - (u8_t *)seg->p->payload);
1266  if (len == 0) {
1267    /** Exclude retransmitted segments from this count. */
1268    MIB2_STATS_INC(mib2.tcpoutsegs);
1269  }
1270
1271  seg->p->len -= len;
1272  seg->p->tot_len -= len;
1273
1274  seg->p->payload = seg->tcphdr;
1275
1276  seg->tcphdr->chksum = 0;
1277#if CHECKSUM_GEN_TCP
1278  IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_TCP) {
1279#if TCP_CHECKSUM_ON_COPY
1280    u32_t acc;
1281#if TCP_CHECKSUM_ON_COPY_SANITY_CHECK
1282    u16_t chksum_slow = ip_chksum_pseudo(seg->p, IP_PROTO_TCP,
1283      seg->p->tot_len, &pcb->local_ip, &pcb->remote_ip);
1284#endif /* TCP_CHECKSUM_ON_COPY_SANITY_CHECK */
1285    if ((seg->flags & TF_SEG_DATA_CHECKSUMMED) == 0) {
1286      LWIP_ASSERT("data included but not checksummed",
1287        seg->p->tot_len == (TCPH_HDRLEN(seg->tcphdr) * 4));
1288    }
1289
1290    /* rebuild TCP header checksum (TCP header changes for retransmissions!) */
1291    acc = ip_chksum_pseudo_partial(seg->p, IP_PROTO_TCP,
1292      seg->p->tot_len, TCPH_HDRLEN(seg->tcphdr) * 4, &pcb->local_ip, &pcb->remote_ip);
1293    /* add payload checksum */
1294    if (seg->chksum_swapped) {
1295      seg->chksum = SWAP_BYTES_IN_WORD(seg->chksum);
1296      seg->chksum_swapped = 0;
1297    }
1298    acc += (u16_t)~(seg->chksum);
1299    seg->tcphdr->chksum = FOLD_U32T(acc);
1300#if TCP_CHECKSUM_ON_COPY_SANITY_CHECK
1301    if (chksum_slow != seg->tcphdr->chksum) {
1302      TCP_CHECKSUM_ON_COPY_SANITY_CHECK_FAIL(
1303                  ("tcp_output_segment: calculated checksum is %"X16_F" instead of %"X16_F"\n",
1304                  seg->tcphdr->chksum, chksum_slow));
1305      seg->tcphdr->chksum = chksum_slow;
1306    }
1307#endif /* TCP_CHECKSUM_ON_COPY_SANITY_CHECK */
1308#else /* TCP_CHECKSUM_ON_COPY */
1309    seg->tcphdr->chksum = ip_chksum_pseudo(seg->p, IP_PROTO_TCP,
1310      seg->p->tot_len, &pcb->local_ip, &pcb->remote_ip);
1311#endif /* TCP_CHECKSUM_ON_COPY */
1312  }
1313#endif /* CHECKSUM_GEN_TCP */
1314  TCP_STATS_INC(tcp.xmit);
1315
1316  NETIF_SET_HWADDRHINT(netif, &(pcb->addr_hint));
1317  err = ip_output_if(seg->p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl,
1318    pcb->tos, IP_PROTO_TCP, netif);
1319  NETIF_SET_HWADDRHINT(netif, NULL);
1320  return err;
1321}
1322
1323/**
1324 * Send a TCP RESET packet (empty segment with RST flag set) either to
1325 * abort a connection or to show that there is no matching local connection
1326 * for a received segment.
1327 *
1328 * Called by tcp_abort() (to abort a local connection), tcp_input() (if no
1329 * matching local pcb was found), tcp_listen_input() (if incoming segment
1330 * has ACK flag set) and tcp_process() (received segment in the wrong state)
1331 *
1332 * Since a RST segment is in most cases not sent for an active connection,
1333 * tcp_rst() has a number of arguments that are taken from a tcp_pcb for
1334 * most other segment output functions.
1335 *
1336 * @param seqno the sequence number to use for the outgoing segment
1337 * @param ackno the acknowledge number to use for the outgoing segment
1338 * @param local_ip the local IP address to send the segment from
1339 * @param remote_ip the remote IP address to send the segment to
1340 * @param local_port the local TCP port to send the segment from
1341 * @param remote_port the remote TCP port to send the segment to
1342 */
1343void
1344tcp_rst(u32_t seqno, u32_t ackno,
1345  const ip_addr_t *local_ip, const ip_addr_t *remote_ip,
1346  u16_t local_port, u16_t remote_port)
1347{
1348  struct pbuf *p;
1349  struct tcp_hdr *tcphdr;
1350  struct netif *netif;
1351  p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM);
1352  if (p == NULL) {
1353    LWIP_DEBUGF(TCP_DEBUG, ("tcp_rst: could not allocate memory for pbuf\n"));
1354    return;
1355  }
1356  LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr",
1357              (p->len >= sizeof(struct tcp_hdr)));
1358
1359  tcphdr = (struct tcp_hdr *)p->payload;
1360  tcphdr->src = lwip_htons(local_port);
1361  tcphdr->dest = lwip_htons(remote_port);
1362  tcphdr->seqno = lwip_htonl(seqno);
1363  tcphdr->ackno = lwip_htonl(ackno);
1364  TCPH_HDRLEN_FLAGS_SET(tcphdr, TCP_HLEN/4, TCP_RST | TCP_ACK);
1365#if LWIP_WND_SCALE
1366  tcphdr->wnd = PP_HTONS(((TCP_WND >> TCP_RCV_SCALE) & 0xFFFF));
1367#else
1368  tcphdr->wnd = PP_HTONS(TCP_WND);
1369#endif
1370  tcphdr->chksum = 0;
1371  tcphdr->urgp = 0;
1372
1373  TCP_STATS_INC(tcp.xmit);
1374  MIB2_STATS_INC(mib2.tcpoutrsts);
1375
1376  netif = ip_route(local_ip, remote_ip);
1377  if (netif != NULL) {
1378#if CHECKSUM_GEN_TCP
1379    IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_TCP) {
1380      tcphdr->chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len,
1381                                        local_ip, remote_ip);
1382    }
1383#endif
1384    /* Send output with hardcoded TTL/HL since we have no access to the pcb */
1385    ip_output_if(p, local_ip, remote_ip, TCP_TTL, 0, IP_PROTO_TCP, netif);
1386  }
1387  pbuf_free(p);
1388  LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_rst: seqno %"U32_F" ackno %"U32_F".\n", seqno, ackno));
1389}
1390
1391/**
1392 * Requeue all unacked segments for retransmission
1393 *
1394 * Called by tcp_slowtmr() for slow retransmission.
1395 *
1396 * @param pcb the tcp_pcb for which to re-enqueue all unacked segments
1397 */
1398void
1399tcp_rexmit_rto(struct tcp_pcb *pcb)
1400{
1401  struct tcp_seg *seg;
1402
1403  if (pcb->unacked == NULL) {
1404    return;
1405  }
1406
1407  /* Move all unacked segments to the head of the unsent queue */
1408  for (seg = pcb->unacked; seg->next != NULL; seg = seg->next);
1409  /* concatenate unsent queue after unacked queue */
1410  seg->next = pcb->unsent;
1411#if TCP_OVERSIZE_DBGCHECK
1412  /* if last unsent changed, we need to update unsent_oversize */
1413  if (pcb->unsent == NULL) {
1414    pcb->unsent_oversize = seg->oversize_left;
1415  }
1416#endif /* TCP_OVERSIZE_DBGCHECK */
1417  /* unsent queue is the concatenated queue (of unacked, unsent) */
1418  pcb->unsent = pcb->unacked;
1419  /* unacked queue is now empty */
1420  pcb->unacked = NULL;
1421
1422  /* increment number of retransmissions */
1423  if (pcb->nrtx < 0xFF) {
1424    ++pcb->nrtx;
1425  }
1426
1427  /* Don't take any RTT measurements after retransmitting. */
1428  pcb->rttest = 0;
1429
1430  /* Do the actual retransmission */
1431  tcp_output(pcb);
1432}
1433
1434/**
1435 * Requeue the first unacked segment for retransmission
1436 *
1437 * Called by tcp_receive() for fast retransmit.
1438 *
1439 * @param pcb the tcp_pcb for which to retransmit the first unacked segment
1440 */
1441void
1442tcp_rexmit(struct tcp_pcb *pcb)
1443{
1444  struct tcp_seg *seg;
1445  struct tcp_seg **cur_seg;
1446
1447  if (pcb->unacked == NULL) {
1448    return;
1449  }
1450
1451  /* Move the first unacked segment to the unsent queue */
1452  /* Keep the unsent queue sorted. */
1453  seg = pcb->unacked;
1454  pcb->unacked = seg->next;
1455
1456  cur_seg = &(pcb->unsent);
1457  while (*cur_seg &&
1458    TCP_SEQ_LT(lwip_ntohl((*cur_seg)->tcphdr->seqno), lwip_ntohl(seg->tcphdr->seqno))) {
1459      cur_seg = &((*cur_seg)->next );
1460  }
1461  seg->next = *cur_seg;
1462  *cur_seg = seg;
1463#if TCP_OVERSIZE
1464  if (seg->next == NULL) {
1465    /* the retransmitted segment is last in unsent, so reset unsent_oversize */
1466    pcb->unsent_oversize = 0;
1467  }
1468#endif /* TCP_OVERSIZE */
1469
1470  if (pcb->nrtx < 0xFF) {
1471    ++pcb->nrtx;
1472  }
1473
1474  /* Don't take any rtt measurements after retransmitting. */
1475  pcb->rttest = 0;
1476
1477  /* Do the actual retransmission. */
1478  MIB2_STATS_INC(mib2.tcpretranssegs);
1479  /* No need to call tcp_output: we are always called from tcp_input()
1480     and thus tcp_output directly returns. */
1481}
1482
1483
1484/**
1485 * Handle retransmission after three dupacks received
1486 *
1487 * @param pcb the tcp_pcb for which to retransmit the first unacked segment
1488 */
1489void
1490tcp_rexmit_fast(struct tcp_pcb *pcb)
1491{
1492  if (pcb->unacked != NULL && !(pcb->flags & TF_INFR)) {
1493    /* This is fast retransmit. Retransmit the first unacked segment. */
1494    LWIP_DEBUGF(TCP_FR_DEBUG,
1495                ("tcp_receive: dupacks %"U16_F" (%"U32_F
1496                 "), fast retransmit %"U32_F"\n",
1497                 (u16_t)pcb->dupacks, pcb->lastack,
1498                 lwip_ntohl(pcb->unacked->tcphdr->seqno)));
1499    tcp_rexmit(pcb);
1500
1501    /* Set ssthresh to half of the minimum of the current
1502     * cwnd and the advertised window */
1503    pcb->ssthresh = LWIP_MIN(pcb->cwnd, pcb->snd_wnd) / 2;
1504
1505    /* The minimum value for ssthresh should be 2 MSS */
1506    if (pcb->ssthresh < (2U * pcb->mss)) {
1507      LWIP_DEBUGF(TCP_FR_DEBUG,
1508                  ("tcp_receive: The minimum value for ssthresh %"TCPWNDSIZE_F
1509                   " should be min 2 mss %"U16_F"...\n",
1510                   pcb->ssthresh, (u16_t)(2*pcb->mss)));
1511      pcb->ssthresh = 2*pcb->mss;
1512    }
1513
1514    pcb->cwnd = pcb->ssthresh + 3 * pcb->mss;
1515    pcb->flags |= TF_INFR;
1516
1517    /* Reset the retransmission timer to prevent immediate rto retransmissions */
1518    pcb->rtime = 0;
1519  }
1520}
1521
1522
1523/**
1524 * Send keepalive packets to keep a connection active although
1525 * no data is sent over it.
1526 *
1527 * Called by tcp_slowtmr()
1528 *
1529 * @param pcb the tcp_pcb for which to send a keepalive packet
1530 */
1531err_t
1532tcp_keepalive(struct tcp_pcb *pcb)
1533{
1534  err_t err;
1535  struct pbuf *p;
1536  struct netif *netif;
1537
1538  LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: sending KEEPALIVE probe to "));
1539  ip_addr_debug_print(TCP_DEBUG, &pcb->remote_ip);
1540  LWIP_DEBUGF(TCP_DEBUG, ("\n"));
1541
1542  LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: tcp_ticks %"U32_F"   pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n",
1543                          tcp_ticks, pcb->tmr, (u16_t)pcb->keep_cnt_sent));
1544
1545  p = tcp_output_alloc_header(pcb, 0, 0, lwip_htonl(pcb->snd_nxt - 1));
1546  if (p == NULL) {
1547    LWIP_DEBUGF(TCP_DEBUG,
1548                ("tcp_keepalive: could not allocate memory for pbuf\n"));
1549    return ERR_MEM;
1550  }
1551  netif = ip_route(&pcb->local_ip, &pcb->remote_ip);
1552  if (netif == NULL) {
1553    err = ERR_RTE;
1554  } else {
1555#if CHECKSUM_GEN_TCP
1556    IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_TCP) {
1557      struct tcp_hdr *tcphdr = (struct tcp_hdr *)p->payload;
1558      tcphdr->chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len,
1559        &pcb->local_ip, &pcb->remote_ip);
1560    }
1561#endif /* CHECKSUM_GEN_TCP */
1562    TCP_STATS_INC(tcp.xmit);
1563
1564    /* Send output to IP */
1565    NETIF_SET_HWADDRHINT(netif, &(pcb->addr_hint));
1566    err = ip_output_if(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP, netif);
1567    NETIF_SET_HWADDRHINT(netif, NULL);
1568  }
1569  pbuf_free(p);
1570
1571  LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: seqno %"U32_F" ackno %"U32_F" err %d.\n",
1572                          pcb->snd_nxt - 1, pcb->rcv_nxt, (int)err));
1573  return err;
1574}
1575
1576
1577/**
1578 * Send persist timer zero-window probes to keep a connection active
1579 * when a window update is lost.
1580 *
1581 * Called by tcp_slowtmr()
1582 *
1583 * @param pcb the tcp_pcb for which to send a zero-window probe packet
1584 */
1585err_t
1586tcp_zero_window_probe(struct tcp_pcb *pcb)
1587{
1588  err_t err;
1589  struct pbuf *p;
1590  struct tcp_hdr *tcphdr;
1591  struct tcp_seg *seg;
1592  u16_t len;
1593  u8_t is_fin;
1594  u32_t snd_nxt;
1595  struct netif *netif;
1596
1597  LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: sending ZERO WINDOW probe to "));
1598  ip_addr_debug_print(TCP_DEBUG, &pcb->remote_ip);
1599  LWIP_DEBUGF(TCP_DEBUG, ("\n"));
1600
1601  LWIP_DEBUGF(TCP_DEBUG,
1602              ("tcp_zero_window_probe: tcp_ticks %"U32_F
1603               "   pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n",
1604               tcp_ticks, pcb->tmr, (u16_t)pcb->keep_cnt_sent));
1605
1606  seg = pcb->unacked;
1607
1608  if (seg == NULL) {
1609    seg = pcb->unsent;
1610  }
1611  if (seg == NULL) {
1612    /* nothing to send, zero window probe not needed */
1613    return ERR_OK;
1614  }
1615
1616  is_fin = ((TCPH_FLAGS(seg->tcphdr) & TCP_FIN) != 0) && (seg->len == 0);
1617  /* we want to send one seqno: either FIN or data (no options) */
1618  len = is_fin ? 0 : 1;
1619
1620  p = tcp_output_alloc_header(pcb, 0, len, seg->tcphdr->seqno);
1621  if (p == NULL) {
1622    LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: no memory for pbuf\n"));
1623    return ERR_MEM;
1624  }
1625  tcphdr = (struct tcp_hdr *)p->payload;
1626
1627  if (is_fin) {
1628    /* FIN segment, no data */
1629    TCPH_FLAGS_SET(tcphdr, TCP_ACK | TCP_FIN);
1630  } else {
1631    /* Data segment, copy in one byte from the head of the unacked queue */
1632    char *d = ((char *)p->payload + TCP_HLEN);
1633    /* Depending on whether the segment has already been sent (unacked) or not
1634       (unsent), seg->p->payload points to the IP header or TCP header.
1635       Ensure we copy the first TCP data byte: */
1636    pbuf_copy_partial(seg->p, d, 1, seg->p->tot_len - seg->len);
1637  }
1638
1639  /* The byte may be acknowledged without the window being opened. */
1640  snd_nxt = lwip_ntohl(seg->tcphdr->seqno) + 1;
1641  if (TCP_SEQ_LT(pcb->snd_nxt, snd_nxt)) {
1642    pcb->snd_nxt = snd_nxt;
1643  }
1644
1645  netif = ip_route(&pcb->local_ip, &pcb->remote_ip);
1646  if (netif == NULL) {
1647    err = ERR_RTE;
1648  } else {
1649#if CHECKSUM_GEN_TCP
1650    IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_TCP) {
1651      tcphdr->chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len,
1652        &pcb->local_ip, &pcb->remote_ip);
1653    }
1654#endif
1655    TCP_STATS_INC(tcp.xmit);
1656
1657    /* Send output to IP */
1658    NETIF_SET_HWADDRHINT(netif, &(pcb->addr_hint));
1659    err = ip_output_if(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl,
1660      0, IP_PROTO_TCP, netif);
1661    NETIF_SET_HWADDRHINT(netif, NULL);
1662  }
1663
1664  pbuf_free(p);
1665
1666  LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: seqno %"U32_F
1667                          " ackno %"U32_F" err %d.\n",
1668                          pcb->snd_nxt - 1, pcb->rcv_nxt, (int)err));
1669  return err;
1670}
1671#endif /* LWIP_TCP */
1672