Back to home page

Quest Cross Reference

 
 

    


Warning, cross-references for /kernel/lwip/core/tcp_out.c need to be fixed.

0001 /**
0002  * @file
0003  * Transmission Control Protocol, outgoing traffic
0004  *
0005  * The output functions of TCP.
0006  *
0007  */
0008 
0009 /*
0010  * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
0011  * All rights reserved.
0012  *
0013  * Redistribution and use in source and binary forms, with or without modification,
0014  * are permitted provided that the following conditions are met:
0015  *
0016  * 1. Redistributions of source code must retain the above copyright notice,
0017  *    this list of conditions and the following disclaimer.
0018  * 2. Redistributions in binary form must reproduce the above copyright notice,
0019  *    this list of conditions and the following disclaimer in the documentation
0020  *    and/or other materials provided with the distribution.
0021  * 3. The name of the author may not be used to endorse or promote products
0022  *    derived from this software without specific prior written permission.
0023  *
0024  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
0025  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
0026  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
0027  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
0028  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
0029  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0030  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0031  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
0032  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
0033  * OF SUCH DAMAGE.
0034  *
0035  * This file is part of the lwIP TCP/IP stack.
0036  *
0037  * Author: Adam Dunkels <adam@sics.se>
0038  *
0039  */
0040 
0041 #include "lwip/opt.h"
0042 
0043 #if LWIP_TCP /* don't build if not configured for use in lwipopts.h */
0044 
0045 #include "lwip/tcp.h"
0046 #include "lwip/def.h"
0047 #include "lwip/mem.h"
0048 #include "lwip/memp.h"
0049 #include "lwip/sys.h"
0050 #include "lwip/ip_addr.h"
0051 #include "lwip/netif.h"
0052 #include "lwip/inet.h"
0053 #include "lwip/inet_chksum.h"
0054 #include "lwip/stats.h"
0055 #include "lwip/snmp.h"
0056 
0057 #include <string.h>
0058 
0059 /* Forward declarations.*/
0060 static void tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb);
0061 
0062 static struct tcp_hdr *
0063 tcp_output_set_header(struct tcp_pcb *pcb, struct pbuf *p, int optlen,
0064                       u32_t seqno_be /* already in network byte order */)
0065 {
0066   struct tcp_hdr *tcphdr = p->payload;
0067   tcphdr->src = htons(pcb->local_port);
0068   tcphdr->dest = htons(pcb->remote_port);
0069   tcphdr->seqno = seqno_be;
0070   tcphdr->ackno = htonl(pcb->rcv_nxt);
0071   TCPH_FLAGS_SET(tcphdr, TCP_ACK);
0072   tcphdr->wnd = htons(pcb->rcv_ann_wnd);
0073   tcphdr->urgp = 0;
0074   TCPH_HDRLEN_SET(tcphdr, (5 + optlen / 4));
0075   tcphdr->chksum = 0;
0076 
0077   /* If we're sending a packet, update the announced right window edge */
0078   pcb->rcv_ann_right_edge = pcb->rcv_nxt + pcb->rcv_ann_wnd;
0079 
0080   return tcphdr;
0081 }
0082 
0083 /**
0084  * Called by tcp_close() to send a segment including flags but not data.
0085  *
0086  * @param pcb the tcp_pcb over which to send a segment
0087  * @param flags the flags to set in the segment header
0088  * @return ERR_OK if sent, another err_t otherwise
0089  */
0090 err_t
0091 tcp_send_ctrl(struct tcp_pcb *pcb, u8_t flags)
0092 {
0093   /* no data, no length, flags, copy=1, no optdata */
0094   return tcp_enqueue(pcb, NULL, 0, flags, TCP_WRITE_FLAG_COPY, 0);
0095 }
0096 
0097 /**
0098  * Write data for sending (but does not send it immediately).
0099  *
0100  * It waits in the expectation of more data being sent soon (as
0101  * it can send them more efficiently by combining them together).
0102  * To prompt the system to send data now, call tcp_output() after
0103  * calling tcp_write().
0104  * 
0105  * @param pcb Protocol control block of the TCP connection to enqueue data for.
0106  * @param data pointer to the data to send
0107  * @param len length (in bytes) of the data to send
0108  * @param apiflags combination of following flags :
0109  * - TCP_WRITE_FLAG_COPY (0x01) data will be copied into memory belonging to the stack
0110  * - TCP_WRITE_FLAG_MORE (0x02) for TCP connection, PSH flag will be set on last segment sent,
0111  * @return ERR_OK if enqueued, another err_t on error
0112  * 
0113  * @see tcp_write()
0114  */
0115 err_t
0116 tcp_write(struct tcp_pcb *pcb, const void *data, u16_t len, u8_t apiflags)
0117 {
0118   LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_write(pcb=%p, data=%p, len=%"U16_F", apiflags=%"U16_F")\n", (void *)pcb,
0119     data, len, (u16_t)apiflags));
0120   /* connection is in valid state for data transmission? */
0121   if (pcb->state == ESTABLISHED ||
0122      pcb->state == CLOSE_WAIT ||
0123      pcb->state == SYN_SENT ||
0124      pcb->state == SYN_RCVD) {
0125     if (len > 0) {
0126 #if LWIP_TCP_TIMESTAMPS
0127       return tcp_enqueue(pcb, (void *)data, len, 0, apiflags, 
0128                          pcb->flags & TF_TIMESTAMP ? TF_SEG_OPTS_TS : 0);
0129 #else
0130       return tcp_enqueue(pcb, (void *)data, len, 0, apiflags, 0);
0131 #endif
0132     }
0133     return ERR_OK;
0134   } else {
0135     LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_STATE | LWIP_DBG_LEVEL_SEVERE, ("tcp_write() called in invalid state\n"));
0136     return ERR_CONN;
0137   }
0138 }
0139 
0140 /**
0141  * Enqueue data and/or TCP options for transmission
0142  *
0143  * Called by tcp_connect(), tcp_listen_input(), tcp_send_ctrl() and tcp_write().
0144  *
0145  * @param pcb Protocol control block for the TCP connection to enqueue data for.
0146  * @param arg Pointer to the data to be enqueued for sending.
0147  * @param len Data length in bytes
0148  * @param flags tcp header flags to set in the outgoing segment
0149  * @param apiflags combination of following flags :
0150  * - TCP_WRITE_FLAG_COPY (0x01) data will be copied into memory belonging to the stack
0151  * - TCP_WRITE_FLAG_MORE (0x02) for TCP connection, PSH flag will be set on last segment sent,
0152  * @param optflags options to include in segment later on (see definition of struct tcp_seg)
0153  */
0154 err_t
0155 tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
0156             u8_t flags, u8_t apiflags, u8_t optflags)
0157 {
0158   struct pbuf *p;
0159   struct tcp_seg *seg, *useg, *queue;
0160   u32_t seqno;
0161   u16_t left, seglen;
0162   void *ptr;
0163   u16_t queuelen;
0164   u8_t optlen;
0165 
0166   LWIP_DEBUGF(TCP_OUTPUT_DEBUG, 
0167               ("tcp_enqueue(pcb=%p, arg=%p, len=%"U16_F", flags=%"X16_F", apiflags=%"U16_F")\n",
0168                (void *)pcb, arg, len, (u16_t)flags, (u16_t)apiflags));
0169   LWIP_ERROR("tcp_enqueue: packet needs payload, options, or SYN/FIN (programmer violates API)",
0170              ((len != 0) || (optflags != 0) || ((flags & (TCP_SYN | TCP_FIN)) != 0)),
0171              return ERR_ARG;);
0172   LWIP_ERROR("tcp_enqueue: len != 0 || arg == NULL (programmer violates API)", 
0173              ((len != 0) || (arg == NULL)), return ERR_ARG;);
0174 
0175   /* fail on too much data */
0176   if (len > pcb->snd_buf) {
0177     LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_WARNING,
0178       ("tcp_enqueue: too much data (len=%"U16_F" > snd_buf=%"U16_F")\n", len, pcb->snd_buf));
0179     pcb->flags |= TF_NAGLEMEMERR;
0180     return ERR_MEM;
0181   }
0182   left = len;
0183   ptr = arg;
0184 
0185   optlen = LWIP_TCP_OPT_LENGTH(optflags);
0186 
0187   /* seqno will be the sequence number of the first segment enqueued
0188    * by the call to this function. */
0189   seqno = pcb->snd_lbb;
0190 
0191   LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue: queuelen: %"U16_F"\n", (u16_t)pcb->snd_queuelen));
0192 
0193   /* If total number of pbufs on the unsent/unacked queues exceeds the
0194    * configured maximum, return an error */
0195   queuelen = pcb->snd_queuelen;
0196   /* check for configured max queuelen and possible overflow */
0197   if ((queuelen >= TCP_SND_QUEUELEN) || (queuelen > TCP_SNDQUEUELEN_OVERFLOW)) {
0198     LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_WARNING,
0199       ("tcp_enqueue: too long queue %"U16_F" (max %"U16_F")\n", queuelen, TCP_SND_QUEUELEN));
0200     TCP_STATS_INC(tcp.memerr);
0201     pcb->flags |= TF_NAGLEMEMERR;
0202     return ERR_MEM;
0203   }
0204   if (queuelen != 0) {
0205     LWIP_ASSERT("tcp_enqueue: pbufs on queue => at least one queue non-empty",
0206       pcb->unacked != NULL || pcb->unsent != NULL);
0207   } else {
0208     LWIP_ASSERT("tcp_enqueue: no pbufs on queue => both queues empty",
0209       pcb->unacked == NULL && pcb->unsent == NULL);
0210   }
0211 
0212   /* First, break up the data into segments and tuck them together in
0213    * the local "queue" variable. */
0214   useg = queue = seg = NULL;
0215   seglen = 0;
0216   while (queue == NULL || left > 0) {
0217     /* The segment length (including options) should be at most the MSS */
0218     seglen = left > (pcb->mss - optlen) ? (pcb->mss - optlen) : left;
0219 
0220     /* Allocate memory for tcp_seg, and fill in fields. */
0221     seg = memp_malloc(MEMP_TCP_SEG);
0222     if (seg == NULL) {
0223       LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, 
0224                   ("tcp_enqueue: could not allocate memory for tcp_seg\n"));
0225       goto memerr;
0226     }
0227     seg->next = NULL;
0228     seg->p = NULL;
0229 
0230     /* first segment of to-be-queued data? */
0231     if (queue == NULL) {
0232       queue = seg;
0233     }
0234     /* subsequent segments of to-be-queued data */
0235     else {
0236       /* Attach the segment to the end of the queued segments */
0237       LWIP_ASSERT("useg != NULL", useg != NULL);
0238       useg->next = seg;
0239     }
0240     /* remember last segment of to-be-queued data for next iteration */
0241     useg = seg;
0242 
0243     /* If copy is set, memory should be allocated
0244      * and data copied into pbuf, otherwise data comes from
0245      * ROM or other static memory, and need not be copied.  */
0246     if (apiflags & TCP_WRITE_FLAG_COPY) {
0247       if ((seg->p = pbuf_alloc(PBUF_TRANSPORT, seglen + optlen, PBUF_RAM)) == NULL) {
0248         LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, 
0249                     ("tcp_enqueue : could not allocate memory for pbuf copy size %"U16_F"\n", seglen));
0250         goto memerr;
0251       }
0252       LWIP_ASSERT("check that first pbuf can hold the complete seglen",
0253                   (seg->p->len >= seglen + optlen));
0254       queuelen += pbuf_clen(seg->p);
0255       if (arg != NULL) {
0256         MEMCPY((char *)seg->p->payload + optlen, ptr, seglen);
0257       }
0258       seg->dataptr = seg->p->payload;
0259     }
0260     /* do not copy data */
0261     else {
0262       /* First, allocate a pbuf for the headers. */
0263       if ((seg->p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) {
0264         LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, 
0265                     ("tcp_enqueue: could not allocate memory for header pbuf\n"));
0266         goto memerr;
0267       }
0268       queuelen += pbuf_clen(seg->p);
0269 
0270       /* Second, allocate a pbuf for holding the data.
0271        * since the referenced data is available at least until it is sent out on the
0272        * link (as it has to be ACKed by the remote party) we can safely use PBUF_ROM
0273        * instead of PBUF_REF here.
0274        */
0275       if (left > 0) {
0276         if ((p = pbuf_alloc(PBUF_RAW, seglen, PBUF_ROM)) == NULL) {
0277           /* If allocation fails, we have to deallocate the header pbuf as well. */
0278           pbuf_free(seg->p);
0279           seg->p = NULL;
0280           LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, 
0281                       ("tcp_enqueue: could not allocate memory for zero-copy pbuf\n"));
0282           goto memerr;
0283         }
0284         ++queuelen;
0285         /* reference the non-volatile payload data */
0286         p->payload = ptr;
0287         seg->dataptr = ptr;
0288 
0289         /* Concatenate the headers and data pbufs together. */
0290         pbuf_cat(seg->p/*header*/, p/*data*/);
0291         p = NULL;
0292       }
0293     }
0294 
0295     /* Now that there are more segments queued, we check again if the
0296     length of the queue exceeds the configured maximum or overflows. */
0297     if ((queuelen > TCP_SND_QUEUELEN) || (queuelen > TCP_SNDQUEUELEN_OVERFLOW)) {
0298       LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
0299         ("tcp_enqueue: queue too long %"U16_F" (%"U16_F")\n", queuelen, TCP_SND_QUEUELEN));
0300       goto memerr;
0301     }
0302 
0303     seg->len = seglen;
0304 
0305     /* build TCP header */
0306     if (pbuf_header(seg->p, TCP_HLEN)) {
0307       LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_enqueue: no room for TCP header in pbuf.\n"));
0308       TCP_STATS_INC(tcp.err);
0309       goto memerr;
0310     }
0311     seg->tcphdr = seg->p->payload;
0312     seg->tcphdr->src = htons(pcb->local_port);
0313     seg->tcphdr->dest = htons(pcb->remote_port);
0314     seg->tcphdr->seqno = htonl(seqno);
0315     seg->tcphdr->urgp = 0;
0316     TCPH_FLAGS_SET(seg->tcphdr, flags);
0317     /* don't fill in tcphdr->ackno and tcphdr->wnd until later */
0318 
0319     seg->flags = optflags;
0320 
0321     /* Set the length of the header */
0322     TCPH_HDRLEN_SET(seg->tcphdr, (5 + optlen / 4));
0323     LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_TRACE, ("tcp_enqueue: queueing %"U32_F":%"U32_F" (0x%"X16_F")\n",
0324       ntohl(seg->tcphdr->seqno),
0325       ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg),
0326       (u16_t)flags));
0327 
0328     left -= seglen;
0329     seqno += seglen;
0330     ptr = (void *)((u8_t *)ptr + seglen);
0331   }
0332 
0333   /* Now that the data to be enqueued has been broken up into TCP
0334   segments in the queue variable, we add them to the end of the
0335   pcb->unsent queue. */
0336   if (pcb->unsent == NULL) {
0337     useg = NULL;
0338   }
0339   else {
0340     for (useg = pcb->unsent; useg->next != NULL; useg = useg->next);
0341   }
0342   /* { useg is last segment on the unsent queue, NULL if list is empty } */
0343 
0344   /* If there is room in the last pbuf on the unsent queue,
0345   chain the first pbuf on the queue together with that. */
0346   if (useg != NULL &&
0347     TCP_TCPLEN(useg) != 0 &&
0348     !(TCPH_FLAGS(useg->tcphdr) & (TCP_SYN | TCP_FIN)) &&
0349     (!(flags & (TCP_SYN | TCP_FIN)) || (flags == TCP_FIN)) &&
0350     /* fit within max seg size */
0351     (useg->len + queue->len <= pcb->mss) &&
0352     /* only concatenate segments with the same options */
0353     (useg->flags == queue->flags) &&
0354     /* segments are consecutive */
0355     (ntohl(useg->tcphdr->seqno) + useg->len == ntohl(queue->tcphdr->seqno)) ) {
0356     /* Remove TCP header from first segment of our to-be-queued list */
0357     if(pbuf_header(queue->p, -(TCP_HLEN + optlen))) {
0358       /* Can we cope with this failing?  Just assert for now */
0359       LWIP_ASSERT("pbuf_header failed\n", 0);
0360       TCP_STATS_INC(tcp.err);
0361       goto memerr;
0362     }
0363     if (queue->p->len == 0) {
0364       /* free the first (header-only) pbuf if it is now empty (contained only headers) */
0365       struct pbuf *old_q = queue->p;
0366       queue->p = queue->p->next;
0367       old_q->next = NULL;
0368       queuelen--;
0369       pbuf_free(old_q);
0370     }
0371     if (flags & TCP_FIN) {
0372       /* the new segment contains only FIN, no data -> put the FIN into the last segment */
0373       LWIP_ASSERT("FIN enqueued together with data", queue->p == NULL && queue->len == 0);
0374       TCPH_SET_FLAG(useg->tcphdr, TCP_FIN);
0375     } else {
0376       LWIP_ASSERT("zero-length pbuf", (queue->p != NULL) && (queue->p->len > 0));
0377       pbuf_cat(useg->p, queue->p);
0378       useg->len += queue->len;
0379       useg->next = queue->next;
0380     }
0381 
0382     LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("tcp_enqueue: chaining segments, new len %"U16_F"\n", useg->len));
0383     if (seg == queue) {
0384       seg = useg;
0385       seglen = useg->len;
0386     }
0387     memp_free(MEMP_TCP_SEG, queue);
0388   }
0389   else {
0390     /* empty list */
0391     if (useg == NULL) {
0392       /* initialize list with this segment */
0393       pcb->unsent = queue;
0394     }
0395     /* enqueue segment */
0396     else {
0397       useg->next = queue;
0398     }
0399   }
0400   if ((flags & TCP_SYN) || (flags & TCP_FIN)) {
0401     ++len;
0402   }
0403   if (flags & TCP_FIN) {
0404     pcb->flags |= TF_FIN;
0405   }
0406   pcb->snd_lbb += len;
0407 
0408   pcb->snd_buf -= len;
0409 
0410   /* update number of segments on the queues */
0411   pcb->snd_queuelen = queuelen;
0412   LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue: %"S16_F" (after enqueued)\n", pcb->snd_queuelen));
0413   if (pcb->snd_queuelen != 0) {
0414     LWIP_ASSERT("tcp_enqueue: valid queue length",
0415       pcb->unacked != NULL || pcb->unsent != NULL);
0416   }
0417 
0418   /* Set the PSH flag in the last segment that we enqueued, but only
0419   if the segment has data (indicated by seglen > 0). */
0420   if (seg != NULL && seglen > 0 && seg->tcphdr != NULL && ((apiflags & TCP_WRITE_FLAG_MORE)==0)) {
0421     TCPH_SET_FLAG(seg->tcphdr, TCP_PSH);
0422   }
0423 
0424   return ERR_OK;
0425 memerr:
0426   pcb->flags |= TF_NAGLEMEMERR;
0427   TCP_STATS_INC(tcp.memerr);
0428 
0429   if (queue != NULL) {
0430     tcp_segs_free(queue);
0431   }
0432   if (pcb->snd_queuelen != 0) {
0433     LWIP_ASSERT("tcp_enqueue: valid queue length", pcb->unacked != NULL ||
0434       pcb->unsent != NULL);
0435   }
0436   LWIP_DEBUGF(TCP_QLEN_DEBUG | LWIP_DBG_STATE, ("tcp_enqueue: %"S16_F" (with mem err)\n", pcb->snd_queuelen));
0437   return ERR_MEM;
0438 }
0439 
0440 
0441 #if LWIP_TCP_TIMESTAMPS
0442 /* Build a timestamp option (12 bytes long) at the specified options pointer)
0443  *
0444  * @param pcb tcp_pcb
0445  * @param opts option pointer where to store the timestamp option
0446  */
0447 static void
0448 tcp_build_timestamp_option(struct tcp_pcb *pcb, u32_t *opts)
0449 {
0450   /* Pad with two NOP options to make everything nicely aligned */
0451   opts[0] = htonl(0x0101080A);
0452   opts[1] = htonl(sys_now());
0453   opts[2] = htonl(pcb->ts_recent);
0454 }
0455 #endif
0456 
0457 /** Send an ACK without data.
0458  *
0459  * @param pcb Protocol control block for the TCP connection to send the ACK
0460  */
0461 err_t
0462 tcp_send_empty_ack(struct tcp_pcb *pcb)
0463 {
0464   struct pbuf *p;
0465   struct tcp_hdr *tcphdr;
0466   u8_t optlen = 0;
0467 
0468 #if LWIP_TCP_TIMESTAMPS
0469   if (pcb->flags & TF_TIMESTAMP) {
0470     optlen = LWIP_TCP_OPT_LENGTH(TF_SEG_OPTS_TS);
0471   }
0472 #endif
0473   p = pbuf_alloc(PBUF_IP, TCP_HLEN + optlen, PBUF_RAM);
0474   if (p == NULL) {
0475     LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: (ACK) could not allocate pbuf\n"));
0476     return ERR_BUF;
0477   }
0478   LWIP_DEBUGF(TCP_OUTPUT_DEBUG, 
0479               ("tcp_output: sending ACK for %"U32_F"\n", pcb->rcv_nxt));
0480   /* remove ACK flags from the PCB, as we send an empty ACK now */
0481   pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
0482 
0483   tcphdr = tcp_output_set_header(pcb, p, optlen, htonl(pcb->snd_nxt));
0484 
0485   /* NB. MSS option is only sent on SYNs, so ignore it here */
0486 #if LWIP_TCP_TIMESTAMPS
0487   pcb->ts_lastacksent = pcb->rcv_nxt;
0488 
0489   if (pcb->flags & TF_TIMESTAMP) {
0490     tcp_build_timestamp_option(pcb, (u32_t *)(tcphdr + 1));
0491   }
0492 #endif 
0493 
0494 #if CHECKSUM_GEN_TCP
0495   tcphdr->chksum = inet_chksum_pseudo(p, &(pcb->local_ip), &(pcb->remote_ip),
0496         IP_PROTO_TCP, p->tot_len);
0497 #endif
0498 #if LWIP_NETIF_HWADDRHINT
0499   ip_output_hinted(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
0500       IP_PROTO_TCP, &(pcb->addr_hint));
0501 #else /* LWIP_NETIF_HWADDRHINT*/
0502   ip_output(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
0503       IP_PROTO_TCP);
0504 #endif /* LWIP_NETIF_HWADDRHINT*/
0505   pbuf_free(p);
0506 
0507   return ERR_OK;
0508 }
0509 
0510 /**
0511  * Find out what we can send and send it
0512  *
0513  * @param pcb Protocol control block for the TCP connection to send data
0514  * @return ERR_OK if data has been sent or nothing to send
0515  *         another err_t on error
0516  */
0517 err_t
0518 tcp_output(struct tcp_pcb *pcb)
0519 {
0520   struct tcp_seg *seg, *useg;
0521   u32_t wnd, snd_nxt;
0522 #if TCP_CWND_DEBUG
0523   s16_t i = 0;
0524 #endif /* TCP_CWND_DEBUG */
0525 
0526   /* First, check if we are invoked by the TCP input processing
0527      code. If so, we do not output anything. Instead, we rely on the
0528      input processing code to call us when input processing is done
0529      with. */
0530   if (tcp_input_pcb == pcb) {
0531     return ERR_OK;
0532   }
0533 
0534   wnd = LWIP_MIN(pcb->snd_wnd, pcb->cwnd);
0535 
0536   seg = pcb->unsent;
0537 
0538   /* If the TF_ACK_NOW flag is set and no data will be sent (either
0539    * because the ->unsent queue is empty or because the window does
0540    * not allow it), construct an empty ACK segment and send it.
0541    *
0542    * If data is to be sent, we will just piggyback the ACK (see below).
0543    */
0544   if (pcb->flags & TF_ACK_NOW &&
0545      (seg == NULL ||
0546       ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len > wnd)) {
0547      return tcp_send_empty_ack(pcb);
0548   }
0549 
0550   /* useg should point to last segment on unacked queue */
0551   useg = pcb->unacked;
0552   if (useg != NULL) {
0553     for (; useg->next != NULL; useg = useg->next);
0554   }
0555 
0556 #if TCP_OUTPUT_DEBUG
0557   if (seg == NULL) {
0558     LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: nothing to send (%p)\n",
0559                                    (void*)pcb->unsent));
0560   }
0561 #endif /* TCP_OUTPUT_DEBUG */
0562 #if TCP_CWND_DEBUG
0563   if (seg == NULL) {
0564     LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"U16_F
0565                                  ", cwnd %"U16_F", wnd %"U32_F
0566                                  ", seg == NULL, ack %"U32_F"\n",
0567                                  pcb->snd_wnd, pcb->cwnd, wnd, pcb->lastack));
0568   } else {
0569     LWIP_DEBUGF(TCP_CWND_DEBUG, 
0570                 ("tcp_output: snd_wnd %"U16_F", cwnd %"U16_F", wnd %"U32_F
0571                  ", effwnd %"U32_F", seq %"U32_F", ack %"U32_F"\n",
0572                  pcb->snd_wnd, pcb->cwnd, wnd,
0573                  ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len,
0574                  ntohl(seg->tcphdr->seqno), pcb->lastack));
0575   }
0576 #endif /* TCP_CWND_DEBUG */
0577   /* data available and window allows it to be sent? */
0578   while (seg != NULL &&
0579          ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) {
0580     LWIP_ASSERT("RST not expected here!", 
0581                 (TCPH_FLAGS(seg->tcphdr) & TCP_RST) == 0);
0582     /* Stop sending if the nagle algorithm would prevent it
0583      * Don't stop:
0584      * - if tcp_enqueue had a memory error before (prevent delayed ACK timeout) or
0585      * - if FIN was already enqueued for this PCB (SYN is always alone in a segment -
0586      *   either seg->next != NULL or pcb->unacked == NULL;
0587      *   RST is no sent using tcp_enqueue/tcp_output.
0588      */
0589     if((tcp_do_output_nagle(pcb) == 0) &&
0590       ((pcb->flags & (TF_NAGLEMEMERR | TF_FIN)) == 0)){
0591       break;
0592     }
0593 #if TCP_CWND_DEBUG
0594     LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"U16_F", cwnd %"U16_F", wnd %"U32_F", effwnd %"U32_F", seq %"U32_F", ack %"U32_F", i %"S16_F"\n",
0595                             pcb->snd_wnd, pcb->cwnd, wnd,
0596                             ntohl(seg->tcphdr->seqno) + seg->len -
0597                             pcb->lastack,
0598                             ntohl(seg->tcphdr->seqno), pcb->lastack, i));
0599     ++i;
0600 #endif /* TCP_CWND_DEBUG */
0601 
0602     pcb->unsent = seg->next;
0603 
0604     if (pcb->state != SYN_SENT) {
0605       TCPH_SET_FLAG(seg->tcphdr, TCP_ACK);
0606       pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
0607     }
0608 
0609     tcp_output_segment(seg, pcb);
0610     snd_nxt = ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg);
0611     if (TCP_SEQ_LT(pcb->snd_nxt, snd_nxt)) {
0612       pcb->snd_nxt = snd_nxt;
0613     }
0614     /* put segment on unacknowledged list if length > 0 */
0615     if (TCP_TCPLEN(seg) > 0) {
0616       seg->next = NULL;
0617       /* unacked list is empty? */
0618       if (pcb->unacked == NULL) {
0619         pcb->unacked = seg;
0620         useg = seg;
0621       /* unacked list is not empty? */
0622       } else {
0623         /* In the case of fast retransmit, the packet should not go to the tail
0624          * of the unacked queue, but rather somewhere before it. We need to check for
0625          * this case. -STJ Jul 27, 2004 */
0626         if (TCP_SEQ_LT(ntohl(seg->tcphdr->seqno), ntohl(useg->tcphdr->seqno))){
0627           /* add segment to before tail of unacked list, keeping the list sorted */
0628           struct tcp_seg **cur_seg = &(pcb->unacked);
0629           while (*cur_seg &&
0630             TCP_SEQ_LT(ntohl((*cur_seg)->tcphdr->seqno), ntohl(seg->tcphdr->seqno))) {
0631               cur_seg = &((*cur_seg)->next );
0632           }
0633           seg->next = (*cur_seg);
0634           (*cur_seg) = seg;
0635         } else {
0636           /* add segment to tail of unacked list */
0637           useg->next = seg;
0638           useg = useg->next;
0639         }
0640       }
0641     /* do not queue empty segments on the unacked list */
0642     } else {
0643       tcp_seg_free(seg);
0644     }
0645     seg = pcb->unsent;
0646   }
0647 
0648   if (seg != NULL && pcb->persist_backoff == 0 && 
0649       ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len > pcb->snd_wnd) {
0650     /* prepare for persist timer */
0651     pcb->persist_cnt = 0;
0652     pcb->persist_backoff = 1;
0653   }
0654 
0655   pcb->flags &= ~TF_NAGLEMEMERR;
0656   return ERR_OK;
0657 }
0658 
0659 /**
0660  * Called by tcp_output() to actually send a TCP segment over IP.
0661  *
0662  * @param seg the tcp_seg to send
0663  * @param pcb the tcp_pcb for the TCP connection used to send the segment
0664  */
0665 static void
0666 tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb)
0667 {
0668   u16_t len;
0669   struct netif *netif;
0670   u32_t *opts;
0671 
0672   /** @bug Exclude retransmitted segments from this count. */
0673   snmp_inc_tcpoutsegs();
0674 
0675   /* The TCP header has already been constructed, but the ackno and
0676    wnd fields remain. */
0677   seg->tcphdr->ackno = htonl(pcb->rcv_nxt);
0678 
0679   /* advertise our receive window size in this TCP segment */
0680   seg->tcphdr->wnd = htons(pcb->rcv_ann_wnd);
0681 
0682   pcb->rcv_ann_right_edge = pcb->rcv_nxt + pcb->rcv_ann_wnd;
0683 
0684   /* Add any requested options.  NB MSS option is only set on SYN
0685      packets, so ignore it here */
0686   opts = (u32_t *)(seg->tcphdr + 1);
0687   if (seg->flags & TF_SEG_OPTS_MSS) {
0688     TCP_BUILD_MSS_OPTION(*opts);
0689     opts += 1;
0690   }
0691 #if LWIP_TCP_TIMESTAMPS
0692   pcb->ts_lastacksent = pcb->rcv_nxt;
0693 
0694   if (seg->flags & TF_SEG_OPTS_TS) {
0695     tcp_build_timestamp_option(pcb, opts);
0696     opts += 3;
0697   }
0698 #endif
0699 
0700   /* If we don't have a local IP address, we get one by
0701      calling ip_route(). */
0702   if (ip_addr_isany(&(pcb->local_ip))) {
0703     netif = ip_route(&(pcb->remote_ip));
0704     if (netif == NULL) {
0705       return;
0706     }
0707     ip_addr_set(&(pcb->local_ip), &(netif->ip_addr));
0708   }
0709 
0710   /* Set retransmission timer running if it is not currently enabled */
0711   if(pcb->rtime == -1)
0712     pcb->rtime = 0;
0713 
0714   if (pcb->rttest == 0) {
0715     pcb->rttest = tcp_ticks;
0716     pcb->rtseq = ntohl(seg->tcphdr->seqno);
0717 
0718     LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_output_segment: rtseq %"U32_F"\n", pcb->rtseq));
0719   }
0720   LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output_segment: %"U32_F":%"U32_F"\n",
0721           htonl(seg->tcphdr->seqno), htonl(seg->tcphdr->seqno) +
0722           seg->len));
0723 
0724   len = (u16_t)((u8_t *)seg->tcphdr - (u8_t *)seg->p->payload);
0725 
0726   seg->p->len -= len;
0727   seg->p->tot_len -= len;
0728 
0729   seg->p->payload = seg->tcphdr;
0730 
0731   seg->tcphdr->chksum = 0;
0732 #if CHECKSUM_GEN_TCP
0733   seg->tcphdr->chksum = inet_chksum_pseudo(seg->p,
0734              &(pcb->local_ip),
0735              &(pcb->remote_ip),
0736              IP_PROTO_TCP, seg->p->tot_len);
0737 #endif
0738   TCP_STATS_INC(tcp.xmit);
0739 
0740 #if LWIP_NETIF_HWADDRHINT
0741   ip_output_hinted(seg->p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
0742       IP_PROTO_TCP, &(pcb->addr_hint));
0743 #else /* LWIP_NETIF_HWADDRHINT*/
0744   ip_output(seg->p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
0745       IP_PROTO_TCP);
0746 #endif /* LWIP_NETIF_HWADDRHINT*/
0747 }
0748 
0749 /**
0750  * Send a TCP RESET packet (empty segment with RST flag set) either to
0751  * abort a connection or to show that there is no matching local connection
0752  * for a received segment.
0753  *
0754  * Called by tcp_abort() (to abort a local connection), tcp_input() (if no
0755  * matching local pcb was found), tcp_listen_input() (if incoming segment
0756  * has ACK flag set) and tcp_process() (received segment in the wrong state)
0757  *
0758  * Since a RST segment is in most cases not sent for an active connection,
0759  * tcp_rst() has a number of arguments that are taken from a tcp_pcb for
0760  * most other segment output functions.
0761  *
0762  * @param seqno the sequence number to use for the outgoing segment
0763  * @param ackno the acknowledge number to use for the outgoing segment
0764  * @param local_ip the local IP address to send the segment from
0765  * @param remote_ip the remote IP address to send the segment to
0766  * @param local_port the local TCP port to send the segment from
0767  * @param remote_port the remote TCP port to send the segment to
0768  */
0769 void
0770 tcp_rst(u32_t seqno, u32_t ackno,
0771   struct ip_addr *local_ip, struct ip_addr *remote_ip,
0772   u16_t local_port, u16_t remote_port)
0773 {
0774   struct pbuf *p;
0775   struct tcp_hdr *tcphdr;
0776   p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM);
0777   if (p == NULL) {
0778       LWIP_DEBUGF(TCP_DEBUG, ("tcp_rst: could not allocate memory for pbuf\n"));
0779       return;
0780   }
0781   LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr",
0782               (p->len >= sizeof(struct tcp_hdr)));
0783 
0784   tcphdr = p->payload;
0785   tcphdr->src = htons(local_port);
0786   tcphdr->dest = htons(remote_port);
0787   tcphdr->seqno = htonl(seqno);
0788   tcphdr->ackno = htonl(ackno);
0789   TCPH_FLAGS_SET(tcphdr, TCP_RST | TCP_ACK);
0790   tcphdr->wnd = htons(TCP_WND);
0791   tcphdr->urgp = 0;
0792   TCPH_HDRLEN_SET(tcphdr, 5);
0793 
0794   tcphdr->chksum = 0;
0795 #if CHECKSUM_GEN_TCP
0796   tcphdr->chksum = inet_chksum_pseudo(p, local_ip, remote_ip,
0797               IP_PROTO_TCP, p->tot_len);
0798 #endif
0799   TCP_STATS_INC(tcp.xmit);
0800   snmp_inc_tcpoutrsts();
0801    /* Send output with hardcoded TTL since we have no access to the pcb */
0802   ip_output(p, local_ip, remote_ip, TCP_TTL, 0, IP_PROTO_TCP);
0803   pbuf_free(p);
0804   LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_rst: seqno %"U32_F" ackno %"U32_F".\n", seqno, ackno));
0805 }
0806 
0807 /**
0808  * Requeue all unacked segments for retransmission
0809  *
0810  * Called by tcp_slowtmr() for slow retransmission.
0811  *
0812  * @param pcb the tcp_pcb for which to re-enqueue all unacked segments
0813  */
0814 void
0815 tcp_rexmit_rto(struct tcp_pcb *pcb)
0816 {
0817   struct tcp_seg *seg;
0818 
0819   if (pcb->unacked == NULL) {
0820     return;
0821   }
0822 
0823   /* Move all unacked segments to the head of the unsent queue */
0824   for (seg = pcb->unacked; seg->next != NULL; seg = seg->next);
0825   /* concatenate unsent queue after unacked queue */
0826   seg->next = pcb->unsent;
0827   /* unsent queue is the concatenated queue (of unacked, unsent) */
0828   pcb->unsent = pcb->unacked;
0829   /* unacked queue is now empty */
0830   pcb->unacked = NULL;
0831 
0832   /* increment number of retransmissions */
0833   ++pcb->nrtx;
0834 
0835   /* Don't take any RTT measurements after retransmitting. */
0836   pcb->rttest = 0;
0837 
0838   /* Do the actual retransmission */
0839   tcp_output(pcb);
0840 }
0841 
0842 /**
0843  * Requeue the first unacked segment for retransmission
0844  *
0845  * Called by tcp_receive() for fast retramsmit.
0846  *
0847  * @param pcb the tcp_pcb for which to retransmit the first unacked segment
0848  */
0849 void
0850 tcp_rexmit(struct tcp_pcb *pcb)
0851 {
0852   struct tcp_seg *seg;
0853   struct tcp_seg **cur_seg;
0854 
0855   if (pcb->unacked == NULL) {
0856     return;
0857   }
0858 
0859   /* Move the first unacked segment to the unsent queue */
0860   /* Keep the unsent queue sorted. */
0861   seg = pcb->unacked;
0862   pcb->unacked = seg->next;
0863 
0864   cur_seg = &(pcb->unsent);
0865   while (*cur_seg &&
0866     TCP_SEQ_LT(ntohl((*cur_seg)->tcphdr->seqno), ntohl(seg->tcphdr->seqno))) {
0867       cur_seg = &((*cur_seg)->next );
0868   }
0869   seg->next = *cur_seg;
0870   *cur_seg = seg;
0871 
0872   ++pcb->nrtx;
0873 
0874   /* Don't take any rtt measurements after retransmitting. */
0875   pcb->rttest = 0;
0876 
0877   /* Do the actual retransmission. */
0878   snmp_inc_tcpretranssegs();
0879   /* No need to call tcp_output: we are always called from tcp_input()
0880      and thus tcp_output directly returns. */
0881 }
0882 
0883 
0884 /**
0885  * Handle retransmission after three dupacks received
0886  *
0887  * @param pcb the tcp_pcb for which to retransmit the first unacked segment
0888  */
0889 void 
0890 tcp_rexmit_fast(struct tcp_pcb *pcb)
0891 {
0892   if (pcb->unacked != NULL && !(pcb->flags & TF_INFR)) {
0893     /* This is fast retransmit. Retransmit the first unacked segment. */
0894     LWIP_DEBUGF(TCP_FR_DEBUG, 
0895                 ("tcp_receive: dupacks %"U16_F" (%"U32_F
0896                  "), fast retransmit %"U32_F"\n",
0897                  (u16_t)pcb->dupacks, pcb->lastack,
0898                  ntohl(pcb->unacked->tcphdr->seqno)));
0899     tcp_rexmit(pcb);
0900 
0901     /* Set ssthresh to half of the minimum of the current
0902      * cwnd and the advertised window */
0903     if (pcb->cwnd > pcb->snd_wnd)
0904       pcb->ssthresh = pcb->snd_wnd / 2;
0905     else
0906       pcb->ssthresh = pcb->cwnd / 2;
0907     
0908     /* The minimum value for ssthresh should be 2 MSS */
0909     if (pcb->ssthresh < 2*pcb->mss) {
0910       LWIP_DEBUGF(TCP_FR_DEBUG, 
0911                   ("tcp_receive: The minimum value for ssthresh %"U16_F
0912                    " should be min 2 mss %"U16_F"...\n",
0913                    pcb->ssthresh, 2*pcb->mss));
0914       pcb->ssthresh = 2*pcb->mss;
0915     }
0916     
0917     pcb->cwnd = pcb->ssthresh + 3 * pcb->mss;
0918     pcb->flags |= TF_INFR;
0919   } 
0920 }
0921 
0922 
0923 /**
0924  * Send keepalive packets to keep a connection active although
0925  * no data is sent over it.
0926  *
0927  * Called by tcp_slowtmr()
0928  *
0929  * @param pcb the tcp_pcb for which to send a keepalive packet
0930  */
0931 void
0932 tcp_keepalive(struct tcp_pcb *pcb)
0933 {
0934   struct pbuf *p;
0935   struct tcp_hdr *tcphdr;
0936 
0937   LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: sending KEEPALIVE probe to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
0938                           ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip),
0939                           ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip)));
0940 
0941   LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: tcp_ticks %"U32_F"   pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n", 
0942                           tcp_ticks, pcb->tmr, pcb->keep_cnt_sent));
0943    
0944   p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM);
0945    
0946   if(p == NULL) {
0947     LWIP_DEBUGF(TCP_DEBUG, 
0948                 ("tcp_keepalive: could not allocate memory for pbuf\n"));
0949     return;
0950   }
0951   LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr",
0952               (p->len >= sizeof(struct tcp_hdr)));
0953 
0954   tcphdr = tcp_output_set_header(pcb, p, 0, htonl(pcb->snd_nxt - 1));
0955 
0956 #if CHECKSUM_GEN_TCP
0957   tcphdr->chksum = inet_chksum_pseudo(p, &pcb->local_ip, &pcb->remote_ip,
0958                                       IP_PROTO_TCP, p->tot_len);
0959 #endif
0960   TCP_STATS_INC(tcp.xmit);
0961 
0962   /* Send output to IP */
0963 #if LWIP_NETIF_HWADDRHINT
0964   ip_output_hinted(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP,
0965     &(pcb->addr_hint));
0966 #else /* LWIP_NETIF_HWADDRHINT*/
0967   ip_output(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP);
0968 #endif /* LWIP_NETIF_HWADDRHINT*/
0969 
0970   pbuf_free(p);
0971 
0972   LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: seqno %"U32_F" ackno %"U32_F".\n",
0973                           pcb->snd_nxt - 1, pcb->rcv_nxt));
0974 }
0975 
0976 
0977 /**
0978  * Send persist timer zero-window probes to keep a connection active
0979  * when a window update is lost.
0980  *
0981  * Called by tcp_slowtmr()
0982  *
0983  * @param pcb the tcp_pcb for which to send a zero-window probe packet
0984  */
0985 void
0986 tcp_zero_window_probe(struct tcp_pcb *pcb)
0987 {
0988   struct pbuf *p;
0989   struct tcp_hdr *tcphdr;
0990   struct tcp_seg *seg;
0991   u16_t len;
0992   u8_t is_fin;
0993 
0994   LWIP_DEBUGF(TCP_DEBUG, 
0995               ("tcp_zero_window_probe: sending ZERO WINDOW probe to %"
0996                U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
0997                ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip),
0998                ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip)));
0999 
1000   LWIP_DEBUGF(TCP_DEBUG, 
1001               ("tcp_zero_window_probe: tcp_ticks %"U32_F
1002                "   pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n", 
1003                tcp_ticks, pcb->tmr, pcb->keep_cnt_sent));
1004 
1005   seg = pcb->unacked;
1006 
1007   if(seg == NULL)
1008     seg = pcb->unsent;
1009 
1010   if(seg == NULL)
1011     return;
1012 
1013   is_fin = ((TCPH_FLAGS(seg->tcphdr) & TCP_FIN) != 0) && (seg->len == 0);
1014   len = is_fin ? TCP_HLEN : TCP_HLEN + 1;
1015 
1016   p = pbuf_alloc(PBUF_IP, len, PBUF_RAM);
1017   if(p == NULL) {
1018     LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: no memory for pbuf\n"));
1019     return;
1020   }
1021   LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr",
1022               (p->len >= sizeof(struct tcp_hdr)));
1023 
1024   tcphdr = tcp_output_set_header(pcb, p, 0, seg->tcphdr->seqno);
1025 
1026   if (is_fin) {
1027     /* FIN segment, no data */
1028     TCPH_FLAGS_SET(tcphdr, TCP_ACK | TCP_FIN);
1029   } else {
1030     /* Data segment, copy in one byte from the head of the unacked queue */
1031     *((char *)p->payload + sizeof(struct tcp_hdr)) = *(char *)seg->dataptr;
1032   }
1033 
1034 #if CHECKSUM_GEN_TCP
1035   tcphdr->chksum = inet_chksum_pseudo(p, &pcb->local_ip, &pcb->remote_ip,
1036                                       IP_PROTO_TCP, p->tot_len);
1037 #endif
1038   TCP_STATS_INC(tcp.xmit);
1039 
1040   /* Send output to IP */
1041 #if LWIP_NETIF_HWADDRHINT
1042   ip_output_hinted(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP,
1043     &(pcb->addr_hint));
1044 #else /* LWIP_NETIF_HWADDRHINT*/
1045   ip_output(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP);
1046 #endif /* LWIP_NETIF_HWADDRHINT*/
1047 
1048   pbuf_free(p);
1049 
1050   LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: seqno %"U32_F
1051                           " ackno %"U32_F".\n",
1052                           pcb->snd_nxt - 1, pcb->rcv_nxt));
1053 }
1054 #endif /* LWIP_TCP */