A version of LWIP, provided for backwards compatibility.

Dependents:   AA_DemoBoard DemoBoard HelloServerDemo DemoBoard_RangeIndicator ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers tcp_out.c Source File

tcp_out.c

Go to the documentation of this file.
00001 /**
00002  * @file
00003  * Transmission Control Protocol, outgoing traffic
00004  *
00005  * The output functions of TCP.
00006  *
00007  */
00008 
00009 /*
00010  * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
00011  * All rights reserved.
00012  *
00013  * Redistribution and use in source and binary forms, with or without modification,
00014  * are permitted provided that the following conditions are met:
00015  *
00016  * 1. Redistributions of source code must retain the above copyright notice,
00017  *    this list of conditions and the following disclaimer.
00018  * 2. Redistributions in binary form must reproduce the above copyright notice,
00019  *    this list of conditions and the following disclaimer in the documentation
00020  *    and/or other materials provided with the distribution.
00021  * 3. The name of the author may not be used to endorse or promote products
00022  *    derived from this software without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
00025  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00026  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
00027  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00028  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
00029  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00030  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00031  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
00032  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
00033  * OF SUCH DAMAGE.
00034  *
00035  * This file is part of the lwIP TCP/IP stack.
00036  *
00037  * Author: Adam Dunkels <adam@sics.se>
00038  *
00039  */
00040 
00041 #include "lwip/opt.h"
00042 
00043 #if LWIP_TCP /* don't build if not configured for use in lwipopts.h */
00044 
00045 #include "lwip/tcp.h"
00046 #include "lwip/def.h"
00047 #include "lwip/mem.h"
00048 #include "lwip/memp.h"
00049 #include "lwip/sys.h"
00050 #include "lwip/ip_addr.h"
00051 #include "lwip/netif.h"
00052 #include "lwip/inet.h"
00053 #include "lwip/inet_chksum.h"
00054 #include "lwip/stats.h"
00055 #include "lwip/snmp.h"
00056 
00057 #include <string.h>
00058 
00059 /* Forward declarations.*/
00060 static void tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb);
00061 
00062 /**
00063  * Called by tcp_close() to send a segment including flags but not data.
00064  *
00065  * @param pcb the tcp_pcb over which to send a segment
00066  * @param flags the flags to set in the segment header
00067  * @return ERR_OK if sent, another err_t otherwise
00068  */
00069 err_t
00070 tcp_send_ctrl(struct tcp_pcb *pcb, u8_t flags)
00071 {
00072   /* no data, no length, flags, copy=1, no optdata, no optdatalen */
00073   return tcp_enqueue(pcb, NULL, 0, flags, TCP_WRITE_FLAG_COPY, NULL, 0);
00074 }
00075 
00076 /**
00077  * Write data for sending (but does not send it immediately).
00078  *
00079  * It waits in the expectation of more data being sent soon (as
00080  * it can send them more efficiently by combining them together).
00081  * To prompt the system to send data now, call tcp_output() after
00082  * calling tcp_write().
00083  * 
00084  * @param pcb Protocol control block of the TCP connection to enqueue data for.
00085  * @param data pointer to the data to send
00086  * @param len length (in bytes) of the data to send
00087  * @param apiflags combination of following flags :
00088  * - TCP_WRITE_FLAG_COPY (0x01) data will be copied into memory belonging to the stack
00089  * - TCP_WRITE_FLAG_MORE (0x02) for TCP connection, PSH flag will be set on last segment sent,
00090  * @return ERR_OK if enqueued, another err_t on error
00091  * 
00092  * @see tcp_write()
00093  */
00094 err_t
00095 tcp_write(struct tcp_pcb *pcb, const void *data, u16_t len, u8_t apiflags)
00096 {
00097   LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_write(pcb=%p, data=%p, len=%"U16_F", apiflags=%"U16_F")\n", (void *)pcb,
00098     data, len, (u16_t)apiflags));
00099   /* connection is in valid state for data transmission? */
00100   if (pcb->state == ESTABLISHED ||
00101      pcb->state == CLOSE_WAIT ||
00102      pcb->state == SYN_SENT ||
00103      pcb->state == SYN_RCVD) {
00104     if (len > 0) {
00105       return tcp_enqueue(pcb, (void *)data, len, 0, apiflags, NULL, 0);
00106     }
00107     return ERR_OK;
00108   } else {
00109     LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_STATE | 3, ("tcp_write() called in invalid state\n"));
00110     return ERR_CONN;
00111   }
00112 }
00113 
00114 /**
00115  * Enqueue either data or TCP options (but not both) for tranmission
00116  *
00117  * Called by tcp_connect(), tcp_listen_input(), tcp_send_ctrl() and tcp_write().
00118  *
00119  * @param pcb Protocol control block for the TCP connection to enqueue data for.
00120  * @param arg Pointer to the data to be enqueued for sending.
00121  * @param len Data length in bytes
00122  * @param flags tcp header flags to set in the outgoing segment
00123  * @param apiflags combination of following flags :
00124  * - TCP_WRITE_FLAG_COPY (0x01) data will be copied into memory belonging to the stack
00125  * - TCP_WRITE_FLAG_MORE (0x02) for TCP connection, PSH flag will be set on last segment sent,
00126  * @param optdata
00127  * @param optlen
00128  */
00129 err_t
00130 tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
00131   u8_t flags, u8_t apiflags,
00132   u8_t *optdata, u8_t optlen)
00133 {
00134   struct pbuf *p;
00135   struct tcp_seg *seg, *useg, *queue;
00136   u32_t seqno;
00137   u16_t left, seglen;
00138   void *ptr;
00139   u16_t queuelen;
00140 
00141   LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_enqueue(pcb=%p, arg=%p, len=%"U16_F", flags=%"X16_F", apiflags=%"U16_F")\n",
00142     (void *)pcb, arg, len, (u16_t)flags, (u16_t)apiflags));
00143   LWIP_ERROR("tcp_enqueue: len == 0 || optlen == 0 (programmer violates API)",
00144       ((len == 0) || (optlen == 0)), return ERR_ARG;);
00145   LWIP_ERROR("tcp_enqueue: arg == NULL || optdata == NULL (programmer violates API)",
00146       ((arg == NULL) || (optdata == NULL)), return ERR_ARG;);
00147   /* fail on too much data */
00148   if (len > pcb->snd_buf) {
00149     LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue: too much data (len=%"U16_F" > snd_buf=%"U16_F")\n", len, pcb->snd_buf));
00150     pcb->flags |= TF_NAGLEMEMERR;
00151     return ERR_MEM;
00152   }
00153   left = len;
00154   ptr = arg;
00155 
00156   /* seqno will be the sequence number of the first segment enqueued
00157    * by the call to this function. */
00158   seqno = pcb->snd_lbb;
00159 
00160   LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue: queuelen: %"U16_F"\n", (u16_t)pcb->snd_queuelen));
00161 
00162   /* If total number of pbufs on the unsent/unacked queues exceeds the
00163    * configured maximum, return an error */
00164   queuelen = pcb->snd_queuelen;
00165   /* check for configured max queuelen and possible overflow */
00166   if ((queuelen >= TCP_SND_QUEUELEN) || (queuelen > TCP_SNDQUEUELEN_OVERFLOW)) {
00167     LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue: too long queue %"U16_F" (max %"U16_F")\n", queuelen, TCP_SND_QUEUELEN));
00168     TCP_STATS_INC(tcp.memerr);
00169     pcb->flags |= TF_NAGLEMEMERR;
00170     return ERR_MEM;
00171   }
00172   if (queuelen != 0) {
00173     LWIP_ASSERT("tcp_enqueue: pbufs on queue => at least one queue non-empty",
00174       pcb->unacked != NULL || pcb->unsent != NULL);
00175   } else {
00176     LWIP_ASSERT("tcp_enqueue: no pbufs on queue => both queues empty",
00177       pcb->unacked == NULL && pcb->unsent == NULL);
00178   }
00179 
00180   /* First, break up the data into segments and tuck them together in
00181    * the local "queue" variable. */
00182   useg = queue = seg = NULL;
00183   seglen = 0;
00184   while (queue == NULL || left > 0) {
00185 
00186     /* The segment length should be the MSS if the data to be enqueued
00187      * is larger than the MSS. */
00188     seglen = left > pcb->mss? pcb->mss: left;
00189 
00190     /* Allocate memory for tcp_seg, and fill in fields. */
00191     seg = static_cast<struct tcp_seg *>(memp_malloc(MEMP_TCP_SEG));
00192     if (seg == NULL) {
00193       LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: could not allocate memory for tcp_seg\n"));
00194       goto memerr;
00195     }
00196     seg->next = NULL;
00197     seg->p = NULL;
00198 
00199     /* first segment of to-be-queued data? */
00200     if (queue == NULL) {
00201       queue = seg;
00202     }
00203     /* subsequent segments of to-be-queued data */
00204     else {
00205       /* Attach the segment to the end of the queued segments */
00206       LWIP_ASSERT("useg != NULL", useg != NULL);
00207       useg->next = seg;
00208     }
00209     /* remember last segment of to-be-queued data for next iteration */
00210     useg = seg;
00211 
00212     /* If copy is set, memory should be allocated
00213      * and data copied into pbuf, otherwise data comes from
00214      * ROM or other static memory, and need not be copied. If
00215      * optdata is != NULL, we have options instead of data. */
00216      
00217     /* options? */
00218     if (optdata != NULL) {
00219       if ((seg->p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) {
00220         goto memerr;
00221       }
00222       LWIP_ASSERT("check that first pbuf can hold optlen",
00223                   (seg->p->len >= optlen));
00224       queuelen += pbuf_clen(seg->p);
00225       seg->dataptr = seg->p->payload;
00226     }
00227     /* copy from volatile memory? */
00228     else if (apiflags & TCP_WRITE_FLAG_COPY) {
00229       if ((seg->p = pbuf_alloc(PBUF_TRANSPORT, seglen, PBUF_RAM)) == NULL) {
00230         LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue : could not allocate memory for pbuf copy size %"U16_F"\n", seglen));
00231         goto memerr;
00232       }
00233       LWIP_ASSERT("check that first pbuf can hold the complete seglen",
00234                   (seg->p->len >= seglen));
00235       queuelen += pbuf_clen(seg->p);
00236       if (arg != NULL) {
00237         MEMCPY(seg->p->payload, ptr, seglen);
00238       }
00239       seg->dataptr = seg->p->payload;
00240     }
00241     /* do not copy data */
00242     else {
00243       /* First, allocate a pbuf for holding the data.
00244        * since the referenced data is available at least until it is sent out on the
00245        * link (as it has to be ACKed by the remote party) we can safely use PBUF_ROM
00246        * instead of PBUF_REF here.
00247        */
00248       if ((p = pbuf_alloc(PBUF_TRANSPORT, seglen, PBUF_ROM)) == NULL) {
00249         LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: could not allocate memory for zero-copy pbuf\n"));
00250         goto memerr;
00251       }
00252       ++queuelen;
00253       /* reference the non-volatile payload data */
00254       p->payload = ptr;
00255       seg->dataptr = ptr;
00256 
00257       /* Second, allocate a pbuf for the headers. */
00258       if ((seg->p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_RAM)) == NULL) {
00259         /* If allocation fails, we have to deallocate the data pbuf as
00260          * well. */
00261         pbuf_free(p);
00262         LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: could not allocate memory for header pbuf\n"));
00263         goto memerr;
00264       }
00265       queuelen += pbuf_clen(seg->p);
00266 
00267       /* Concatenate the headers and data pbufs together. */
00268       pbuf_cat(seg->p/*header*/, p/*data*/);
00269       p = NULL;
00270     }
00271 
00272     /* Now that there are more segments queued, we check again if the
00273     length of the queue exceeds the configured maximum or overflows. */
00274     if ((queuelen > TCP_SND_QUEUELEN) || (queuelen > TCP_SNDQUEUELEN_OVERFLOW)) {
00275       LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: queue too long %"U16_F" (%"U16_F")\n", queuelen, TCP_SND_QUEUELEN));
00276       goto memerr;
00277     }
00278 
00279     seg->len = seglen;
00280 
00281     /* build TCP header */
00282     if (pbuf_header(seg->p, TCP_HLEN)) {
00283       LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: no room for TCP header in pbuf.\n"));
00284       TCP_STATS_INC(tcp.err);
00285       goto memerr;
00286     }
00287     seg->tcphdr = static_cast<struct tcp_hdr *>(seg->p->payload);
00288     seg->tcphdr->src = htons(pcb->local_port);
00289     seg->tcphdr->dest = htons(pcb->remote_port);
00290     seg->tcphdr->seqno = htonl(seqno);
00291     seg->tcphdr->urgp = 0;
00292     TCPH_FLAGS_SET(seg->tcphdr, flags);
00293     /* don't fill in tcphdr->ackno and tcphdr->wnd until later */
00294 
00295     /* Copy the options into the header, if they are present. */
00296     if (optdata == NULL) {
00297       TCPH_HDRLEN_SET(seg->tcphdr, 5);
00298     }
00299     else {
00300       TCPH_HDRLEN_SET(seg->tcphdr, (5 + optlen / 4));
00301       /* Copy options into data portion of segment.
00302        Options can thus only be sent in non data carrying
00303        segments such as SYN|ACK. */
00304       SMEMCPY(seg->dataptr, optdata, optlen);
00305     }
00306     LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_TRACE, ("tcp_enqueue: queueing %"U32_F":%"U32_F" (0x%"X16_F")\n",
00307       ntohl(seg->tcphdr->seqno),
00308       ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg),
00309       (u16_t)flags));
00310 
00311     left -= seglen;
00312     seqno += seglen;
00313     ptr = (void *)((u8_t *)ptr + seglen);
00314   }
00315 
00316   /* Now that the data to be enqueued has been broken up into TCP
00317   segments in the queue variable, we add them to the end of the
00318   pcb->unsent queue. */
00319   if (pcb->unsent == NULL) {
00320     useg = NULL;
00321   }
00322   else {
00323     for (useg = pcb->unsent; useg->next != NULL; useg = useg->next);
00324   }
00325   /* { useg is last segment on the unsent queue, NULL if list is empty } */
00326 
00327   /* If there is room in the last pbuf on the unsent queue,
00328   chain the first pbuf on the queue together with that. */
00329   if (useg != NULL &&
00330     TCP_TCPLEN(useg) != 0 &&
00331     !(TCPH_FLAGS(useg->tcphdr) & (TCP_SYN | TCP_FIN)) &&
00332     !(flags & (TCP_SYN | TCP_FIN)) &&
00333     /* fit within max seg size */
00334     useg->len + queue->len <= pcb->mss) {
00335     /* Remove TCP header from first segment of our to-be-queued list */
00336     if(pbuf_header(queue->p, -TCP_HLEN)) {
00337       /* Can we cope with this failing?  Just assert for now */
00338       LWIP_ASSERT("pbuf_header failed\n", 0);
00339       TCP_STATS_INC(tcp.err);
00340       goto memerr;
00341     }
00342     pbuf_cat(useg->p, queue->p);
00343     useg->len += queue->len;
00344     useg->next = queue->next;
00345 
00346     LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("tcp_enqueue: chaining segments, new len %"U16_F"\n", useg->len));
00347     if (seg == queue) {
00348       seg = NULL;
00349     }
00350     memp_free(MEMP_TCP_SEG, queue);
00351   }
00352   else {
00353     /* empty list */
00354     if (useg == NULL) {
00355       /* initialize list with this segment */
00356       pcb->unsent = queue;
00357     }
00358     /* enqueue segment */
00359     else {
00360       useg->next = queue;
00361     }
00362   }
00363   if ((flags & TCP_SYN) || (flags & TCP_FIN)) {
00364     ++len;
00365   }
00366   if (flags & TCP_FIN) {
00367     pcb->flags |= TF_FIN;
00368   }
00369   pcb->snd_lbb += len;
00370 
00371   pcb->snd_buf -= len;
00372 
00373   /* update number of segments on the queues */
00374   pcb->snd_queuelen = queuelen;
00375   LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue: %"S16_F" (after enqueued)\n", pcb->snd_queuelen));
00376   if (pcb->snd_queuelen != 0) {
00377     LWIP_ASSERT("tcp_enqueue: valid queue length",
00378       pcb->unacked != NULL || pcb->unsent != NULL);
00379   }
00380 
00381   /* Set the PSH flag in the last segment that we enqueued, but only
00382   if the segment has data (indicated by seglen > 0). */
00383   if (seg != NULL && seglen > 0 && seg->tcphdr != NULL && ((apiflags & TCP_WRITE_FLAG_MORE)==0)) {
00384     TCPH_SET_FLAG(seg->tcphdr, TCP_PSH);
00385   }
00386 
00387   return ERR_OK;
00388 memerr:
00389   pcb->flags |= TF_NAGLEMEMERR;
00390   TCP_STATS_INC(tcp.memerr);
00391 
00392   if (queue != NULL) {
00393     tcp_segs_free(queue);
00394   }
00395   if (pcb->snd_queuelen != 0) {
00396     LWIP_ASSERT("tcp_enqueue: valid queue length", pcb->unacked != NULL ||
00397       pcb->unsent != NULL);
00398   }
00399   LWIP_DEBUGF(TCP_QLEN_DEBUG | LWIP_DBG_STATE, ("tcp_enqueue: %"S16_F" (with mem err)\n", pcb->snd_queuelen));
00400   return ERR_MEM;
00401 }
00402 
00403 /**
00404  * Find out what we can send and send it
00405  *
00406  * @param pcb Protocol control block for the TCP connection to send data
00407  * @return ERR_OK if data has been sent or nothing to send
00408  *         another err_t on error
00409  */
00410 err_t
00411 tcp_output(struct tcp_pcb *pcb)
00412 {
00413   struct pbuf *p;
00414   struct tcp_hdr *tcphdr;
00415   struct tcp_seg *seg, *useg;
00416   u32_t wnd;
00417 #if TCP_CWND_DEBUG
00418   s16_t i = 0;
00419 #endif /* TCP_CWND_DEBUG */
00420 
00421   /* First, check if we are invoked by the TCP input processing
00422      code. If so, we do not output anything. Instead, we rely on the
00423      input processing code to call us when input processing is done
00424      with. */
00425   if (tcp_input_pcb == pcb) {
00426     return ERR_OK;
00427   }
00428 
00429   wnd = LWIP_MIN(pcb->snd_wnd, pcb->cwnd);
00430 
00431   seg = pcb->unsent;
00432 
00433   /* useg should point to last segment on unacked queue */
00434   useg = pcb->unacked;
00435   if (useg != NULL) {
00436     for (; useg->next != NULL; useg = useg->next);
00437   }                                                                             
00438    
00439   /* If the TF_ACK_NOW flag is set and no data will be sent (either
00440    * because the ->unsent queue is empty or because the window does
00441    * not allow it), construct an empty ACK segment and send it.
00442    *
00443    * If data is to be sent, we will just piggyback the ACK (see below).
00444    */
00445   if (pcb->flags & TF_ACK_NOW &&
00446      (seg == NULL ||
00447       ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len > wnd)) {
00448     p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM);
00449     if (p == NULL) {
00450       LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: (ACK) could not allocate pbuf\n"));
00451       return ERR_BUF;
00452     }
00453     LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: sending ACK for %"U32_F"\n", pcb->rcv_nxt));
00454     /* remove ACK flags from the PCB, as we send an empty ACK now */
00455     pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
00456 
00457     tcphdr = static_cast<struct tcp_hdr *>(p->payload);
00458     tcphdr->src = htons(pcb->local_port);
00459     tcphdr->dest = htons(pcb->remote_port);
00460     tcphdr->seqno = htonl(pcb->snd_nxt);
00461     tcphdr->ackno = htonl(pcb->rcv_nxt);
00462     TCPH_FLAGS_SET(tcphdr, TCP_ACK);
00463     tcphdr->wnd = htons(pcb->rcv_ann_wnd);
00464     tcphdr->urgp = 0;
00465     TCPH_HDRLEN_SET(tcphdr, 5);
00466 
00467     tcphdr->chksum = 0;
00468 #if CHECKSUM_GEN_TCP
00469     tcphdr->chksum = inet_chksum_pseudo(p, &(pcb->local_ip), &(pcb->remote_ip),
00470           IP_PROTO_TCP, p->tot_len);
00471 #endif
00472 #if LWIP_NETIF_HWADDRHINT
00473     {
00474       struct netif *netif;
00475       netif = ip_route(&pcb->remote_ip);
00476       if(netif != NULL){
00477         netif->addr_hint = &(pcb->addr_hint);
00478         ip_output_if(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl,
00479                      pcb->tos, IP_PROTO_TCP, netif);
00480         netif->addr_hint = NULL;
00481       }
00482     }
00483 #else /* LWIP_NETIF_HWADDRHINT*/
00484     ip_output(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
00485         IP_PROTO_TCP);
00486 #endif /* LWIP_NETIF_HWADDRHINT*/
00487     pbuf_free(p);
00488 
00489     return ERR_OK;
00490   }
00491 
00492 #if TCP_OUTPUT_DEBUG
00493   if (seg == NULL) {
00494     LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: nothing to send (%p)\n",
00495                                    (void*)pcb->unsent));
00496   }
00497 #endif /* TCP_OUTPUT_DEBUG */
00498 #if TCP_CWND_DEBUG
00499   if (seg == NULL) {
00500     LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"U16_F
00501                                  ", cwnd %"U16_F", wnd %"U32_F
00502                                  ", seg == NULL, ack %"U32_F"\n",
00503                                  pcb->snd_wnd, pcb->cwnd, wnd, pcb->lastack));
00504   } else {
00505     LWIP_DEBUGF(TCP_CWND_DEBUG, 
00506                 ("tcp_output: snd_wnd %"U16_F", cwnd %"U16_F", wnd %"U32_F
00507                  ", effwnd %"U32_F", seq %"U32_F", ack %"U32_F"\n",
00508                  pcb->snd_wnd, pcb->cwnd, wnd,
00509                  ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len,
00510                  ntohl(seg->tcphdr->seqno), pcb->lastack));
00511   }
00512 #endif /* TCP_CWND_DEBUG */
00513   /* data available and window allows it to be sent? */
00514   while (seg != NULL &&
00515          ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) {
00516     LWIP_ASSERT("RST not expected here!", 
00517                 (TCPH_FLAGS(seg->tcphdr) & TCP_RST) == 0);
00518     /* Stop sending if the nagle algorithm would prevent it
00519      * Don't stop:
00520      * - if tcp_enqueue had a memory error before (prevent delayed ACK timeout) or
00521      * - if FIN was already enqueued for this PCB (SYN is always alone in a segment -
00522      *   either seg->next != NULL or pcb->unacked == NULL;
00523      *   RST is no sent using tcp_enqueue/tcp_output.
00524      */
00525     if((tcp_do_output_nagle(pcb) == 0) &&
00526       ((pcb->flags & (TF_NAGLEMEMERR | TF_FIN)) == 0)){
00527       break;
00528     }
00529 #if TCP_CWND_DEBUG
00530     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",
00531                             pcb->snd_wnd, pcb->cwnd, wnd,
00532                             ntohl(seg->tcphdr->seqno) + seg->len -
00533                             pcb->lastack,
00534                             ntohl(seg->tcphdr->seqno), pcb->lastack, i));
00535     ++i;
00536 #endif /* TCP_CWND_DEBUG */
00537 
00538     pcb->unsent = seg->next;
00539 
00540     if (pcb->state != SYN_SENT) {
00541       TCPH_SET_FLAG(seg->tcphdr, TCP_ACK);
00542       pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
00543     }
00544 
00545     tcp_output_segment(seg, pcb);
00546     pcb->snd_nxt = ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg);
00547     if (TCP_SEQ_LT(pcb->snd_max, pcb->snd_nxt)) {
00548       pcb->snd_max = pcb->snd_nxt;
00549     }
00550     /* put segment on unacknowledged list if length > 0 */
00551     if (TCP_TCPLEN(seg) > 0) {
00552       seg->next = NULL;
00553       /* unacked list is empty? */
00554       if (pcb->unacked == NULL) {
00555         pcb->unacked = seg;
00556         useg = seg;
00557       /* unacked list is not empty? */
00558       } else {
00559         /* In the case of fast retransmit, the packet should not go to the tail
00560          * of the unacked queue, but rather at the head. We need to check for
00561          * this case. -STJ Jul 27, 2004 */
00562         if (TCP_SEQ_LT(ntohl(seg->tcphdr->seqno), ntohl(useg->tcphdr->seqno))){
00563           /* add segment to head of unacked list */
00564           seg->next = pcb->unacked;
00565           pcb->unacked = seg;
00566         } else {
00567           /* add segment to tail of unacked list */
00568           useg->next = seg;
00569           useg = useg->next;
00570         }
00571       }
00572     /* do not queue empty segments on the unacked list */
00573     } else {
00574       tcp_seg_free(seg);
00575     }
00576     seg = pcb->unsent;
00577   }
00578 
00579   if (seg != NULL && pcb->persist_backoff == 0 && 
00580       ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len > pcb->snd_wnd) {
00581     /* prepare for persist timer */
00582     pcb->persist_cnt = 0;
00583     pcb->persist_backoff = 1;
00584   }
00585 
00586   pcb->flags &= ~TF_NAGLEMEMERR;
00587   return ERR_OK;
00588 }
00589 
00590 /**
00591  * Called by tcp_output() to actually send a TCP segment over IP.
00592  *
00593  * @param seg the tcp_seg to send
00594  * @param pcb the tcp_pcb for the TCP connection used to send the segment
00595  */
00596 static void
00597 tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb)
00598 {
00599   u16_t len;
00600   struct netif *netif;
00601 
00602   /** @bug Exclude retransmitted segments from this count. */
00603   snmp_inc_tcpoutsegs();
00604 
00605   /* The TCP header has already been constructed, but the ackno and
00606    wnd fields remain. */
00607   seg->tcphdr->ackno = htonl(pcb->rcv_nxt);
00608 
00609   /* advertise our receive window size in this TCP segment */
00610   seg->tcphdr->wnd = htons(pcb->rcv_ann_wnd);
00611 
00612   /* If we don't have a local IP address, we get one by
00613      calling ip_route(). */
00614   if (ip_addr_isany(&(pcb->local_ip))) {
00615     netif = ip_route(&(pcb->remote_ip));
00616     if (netif == NULL) {
00617       return;
00618     }
00619     ip_addr_set(&(pcb->local_ip), &(netif->ip_addr));
00620   }
00621 
00622   /* Set retransmission timer running if it is not currently enabled */
00623   if(pcb->rtime == -1)
00624     pcb->rtime = 0;
00625 
00626   if (pcb->rttest == 0) {
00627     pcb->rttest = tcp_ticks;
00628     pcb->rtseq = ntohl(seg->tcphdr->seqno);
00629 
00630     LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_output_segment: rtseq %"U32_F"\n", pcb->rtseq));
00631   }
00632   LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output_segment: %"U32_F":%"U32_F"\n",
00633           htonl(seg->tcphdr->seqno), htonl(seg->tcphdr->seqno) +
00634           seg->len));
00635 
00636   len = (u16_t)((u8_t *)seg->tcphdr - (u8_t *)seg->p->payload);
00637 
00638   seg->p->len -= len;
00639   seg->p->tot_len -= len;
00640 
00641   seg->p->payload = seg->tcphdr;
00642 
00643   seg->tcphdr->chksum = 0;
00644 #if CHECKSUM_GEN_TCP
00645   seg->tcphdr->chksum = inet_chksum_pseudo(seg->p,
00646              &(pcb->local_ip),
00647              &(pcb->remote_ip),
00648              IP_PROTO_TCP, seg->p->tot_len);
00649 #endif
00650   TCP_STATS_INC(tcp.xmit);
00651 
00652 #if LWIP_NETIF_HWADDRHINT
00653   {
00654     struct netif *netif;
00655     netif = ip_route(&pcb->remote_ip);
00656     if(netif != NULL){
00657       netif->addr_hint = &(pcb->addr_hint);
00658       ip_output_if(seg->p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl,
00659                    pcb->tos, IP_PROTO_TCP, netif);
00660       netif->addr_hint = NULL;
00661     }
00662   }
00663 #else /* LWIP_NETIF_HWADDRHINT*/
00664   ip_output(seg->p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
00665       IP_PROTO_TCP);
00666 #endif /* LWIP_NETIF_HWADDRHINT*/
00667 }
00668 
00669 /**
00670  * Send a TCP RESET packet (empty segment with RST flag set) either to
00671  * abort a connection or to show that there is no matching local connection
00672  * for a received segment.
00673  *
00674  * Called by tcp_abort() (to abort a local connection), tcp_input() (if no
00675  * matching local pcb was found), tcp_listen_input() (if incoming segment
00676  * has ACK flag set) and tcp_process() (received segment in the wrong state)
00677  *
00678  * Since a RST segment is in most cases not sent for an active connection,
00679  * tcp_rst() has a number of arguments that are taken from a tcp_pcb for
00680  * most other segment output functions.
00681  *
00682  * @param seqno the sequence number to use for the outgoing segment
00683  * @param ackno the acknowledge number to use for the outgoing segment
00684  * @param local_ip the local IP address to send the segment from
00685  * @param remote_ip the remote IP address to send the segment to
00686  * @param local_port the local TCP port to send the segment from
00687  * @param remote_port the remote TCP port to send the segment to
00688  */
00689 void
00690 tcp_rst(u32_t seqno, u32_t ackno,
00691   struct ip_addr *local_ip, struct ip_addr *remote_ip,
00692   u16_t local_port, u16_t remote_port)
00693 {
00694   struct pbuf *p;
00695   struct tcp_hdr *tcphdr;
00696   p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM);
00697   if (p == NULL) {
00698       LWIP_DEBUGF(TCP_DEBUG, ("tcp_rst: could not allocate memory for pbuf\n"));
00699       return;
00700   }
00701   LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr",
00702               (p->len >= sizeof(struct tcp_hdr)));
00703 
00704   tcphdr = static_cast<struct tcp_hdr *>(p->payload);
00705   tcphdr->src = htons(local_port);
00706   tcphdr->dest = htons(remote_port);
00707   tcphdr->seqno = htonl(seqno);
00708   tcphdr->ackno = htonl(ackno);
00709   TCPH_FLAGS_SET(tcphdr, TCP_RST | TCP_ACK);
00710   tcphdr->wnd = htons(TCP_WND);
00711   tcphdr->urgp = 0;
00712   TCPH_HDRLEN_SET(tcphdr, 5);
00713 
00714   tcphdr->chksum = 0;
00715 #if CHECKSUM_GEN_TCP
00716   tcphdr->chksum = inet_chksum_pseudo(p, local_ip, remote_ip,
00717               IP_PROTO_TCP, p->tot_len);
00718 #endif
00719   TCP_STATS_INC(tcp.xmit);
00720   snmp_inc_tcpoutrsts();
00721    /* Send output with hardcoded TTL since we have no access to the pcb */
00722   ip_output(p, local_ip, remote_ip, TCP_TTL, 0, IP_PROTO_TCP);
00723   pbuf_free(p);
00724   LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_rst: seqno %"U32_F" ackno %"U32_F".\n", seqno, ackno));
00725 }
00726 
00727 /**
00728  * Requeue all unacked segments for retransmission
00729  *
00730  * Called by tcp_slowtmr() for slow retransmission.
00731  *
00732  * @param pcb the tcp_pcb for which to re-enqueue all unacked segments
00733  */
00734 void
00735 tcp_rexmit_rto(struct tcp_pcb *pcb)
00736 {
00737   struct tcp_seg *seg;
00738 
00739   if (pcb->unacked == NULL) {
00740     return;
00741   }
00742 
00743   /* Move all unacked segments to the head of the unsent queue */
00744   for (seg = pcb->unacked; seg->next != NULL; seg = seg->next);
00745   /* concatenate unsent queue after unacked queue */
00746   seg->next = pcb->unsent;
00747   /* unsent queue is the concatenated queue (of unacked, unsent) */
00748   pcb->unsent = pcb->unacked;
00749   /* unacked queue is now empty */
00750   pcb->unacked = NULL;
00751 
00752   pcb->snd_nxt = ntohl(pcb->unsent->tcphdr->seqno);
00753   /* increment number of retransmissions */
00754   ++pcb->nrtx;
00755 
00756   /* Don't take any RTT measurements after retransmitting. */
00757   pcb->rttest = 0;
00758 
00759   /* Do the actual retransmission */
00760   tcp_output(pcb);
00761 }
00762 
00763 /**
00764  * Requeue the first unacked segment for retransmission
00765  *
00766  * Called by tcp_receive() for fast retramsmit.
00767  *
00768  * @param pcb the tcp_pcb for which to retransmit the first unacked segment
00769  */
00770 void
00771 tcp_rexmit(struct tcp_pcb *pcb)
00772 {
00773   struct tcp_seg *seg;
00774 
00775   if (pcb->unacked == NULL) {
00776     return;
00777   }
00778 
00779   /* Move the first unacked segment to the unsent queue */
00780   seg = pcb->unacked->next;
00781   pcb->unacked->next = pcb->unsent;
00782   pcb->unsent = pcb->unacked;
00783   pcb->unacked = seg;
00784 
00785   pcb->snd_nxt = ntohl(pcb->unsent->tcphdr->seqno);
00786 
00787   ++pcb->nrtx;
00788 
00789   /* Don't take any rtt measurements after retransmitting. */
00790   pcb->rttest = 0;
00791 
00792   /* Do the actual retransmission. */
00793   snmp_inc_tcpretranssegs();
00794   tcp_output(pcb);
00795 }
00796 
00797 /**
00798  * Send keepalive packets to keep a connection active although
00799  * no data is sent over it.
00800  *
00801  * Called by tcp_slowtmr()
00802  *
00803  * @param pcb the tcp_pcb for which to send a keepalive packet
00804  */
00805 void
00806 tcp_keepalive(struct tcp_pcb *pcb)
00807 {
00808   struct pbuf *p;
00809   struct tcp_hdr *tcphdr;
00810 
00811   LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: sending KEEPALIVE probe to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
00812                           ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip),
00813                           ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip)));
00814 
00815   LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: tcp_ticks %"U32_F"   pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n", 
00816                           tcp_ticks, pcb->tmr, pcb->keep_cnt_sent));
00817    
00818   p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM);
00819    
00820   if(p == NULL) {
00821     LWIP_DEBUGF(TCP_DEBUG, 
00822                 ("tcp_keepalive: could not allocate memory for pbuf\n"));
00823     return;
00824   }
00825   LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr",
00826               (p->len >= sizeof(struct tcp_hdr)));
00827 
00828   tcphdr = static_cast<struct tcp_hdr *>(p->payload);
00829   tcphdr->src = htons(pcb->local_port);
00830   tcphdr->dest = htons(pcb->remote_port);
00831   tcphdr->seqno = htonl(pcb->snd_nxt - 1);
00832   tcphdr->ackno = htonl(pcb->rcv_nxt);
00833   TCPH_FLAGS_SET(tcphdr, 0);
00834   tcphdr->wnd = htons(pcb->rcv_ann_wnd);
00835   tcphdr->urgp = 0;
00836   TCPH_HDRLEN_SET(tcphdr, 5);
00837 
00838   tcphdr->chksum = 0;
00839 #if CHECKSUM_GEN_TCP
00840   tcphdr->chksum = inet_chksum_pseudo(p, &pcb->local_ip, &pcb->remote_ip,
00841                                       IP_PROTO_TCP, p->tot_len);
00842 #endif
00843   TCP_STATS_INC(tcp.xmit);
00844 
00845   /* Send output to IP */
00846 #if LWIP_NETIF_HWADDRHINT
00847   {
00848     struct netif *netif;
00849     netif = ip_route(&pcb->remote_ip);
00850     if(netif != NULL){
00851       netif->addr_hint = &(pcb->addr_hint);
00852       ip_output_if(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl,
00853                    0, IP_PROTO_TCP, netif);
00854       netif->addr_hint = NULL;
00855     }
00856   }
00857 #else /* LWIP_NETIF_HWADDRHINT*/
00858   ip_output(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP);
00859 #endif /* LWIP_NETIF_HWADDRHINT*/
00860 
00861   pbuf_free(p);
00862 
00863   LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: seqno %"U32_F" ackno %"U32_F".\n",
00864                           pcb->snd_nxt - 1, pcb->rcv_nxt));
00865 }
00866 
00867 
00868 /**
00869  * Send persist timer zero-window probes to keep a connection active
00870  * when a window update is lost.
00871  *
00872  * Called by tcp_slowtmr()
00873  *
00874  * @param pcb the tcp_pcb for which to send a zero-window probe packet
00875  */
00876 void
00877 tcp_zero_window_probe(struct tcp_pcb *pcb)
00878 {
00879   struct pbuf *p;
00880   struct tcp_hdr *tcphdr;
00881   struct tcp_seg *seg;
00882 
00883   LWIP_DEBUGF(TCP_DEBUG, 
00884               ("tcp_zero_window_probe: sending ZERO WINDOW probe to %"
00885                U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
00886                ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip),
00887                ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip)));
00888 
00889   LWIP_DEBUGF(TCP_DEBUG, 
00890               ("tcp_zero_window_probe: tcp_ticks %"U32_F
00891                "   pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n", 
00892                tcp_ticks, pcb->tmr, pcb->keep_cnt_sent));
00893 
00894   seg = pcb->unacked;
00895 
00896   if(seg == NULL)
00897     seg = pcb->unsent;
00898 
00899   if(seg == NULL)
00900     return;
00901 
00902   p = pbuf_alloc(PBUF_IP, TCP_HLEN + 1, PBUF_RAM);
00903    
00904   if(p == NULL) {
00905     LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: no memory for pbuf\n"));
00906     return;
00907   }
00908   LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr",
00909               (p->len >= sizeof(struct tcp_hdr)));
00910 
00911   tcphdr = static_cast<struct tcp_hdr *>(p->payload);
00912   tcphdr->src = htons(pcb->local_port);
00913   tcphdr->dest = htons(pcb->remote_port);
00914   tcphdr->seqno = seg->tcphdr->seqno;
00915   tcphdr->ackno = htonl(pcb->rcv_nxt);
00916   TCPH_FLAGS_SET(tcphdr, 0);
00917   tcphdr->wnd = htons(pcb->rcv_ann_wnd);
00918   tcphdr->urgp = 0;
00919   TCPH_HDRLEN_SET(tcphdr, 5);
00920 
00921   /* Copy in one byte from the head of the unacked queue */
00922   *((char *)p->payload + sizeof(struct tcp_hdr)) = *(char *)seg->dataptr;
00923 
00924   tcphdr->chksum = 0;
00925 #if CHECKSUM_GEN_TCP
00926   tcphdr->chksum = inet_chksum_pseudo(p, &pcb->local_ip, &pcb->remote_ip,
00927                                       IP_PROTO_TCP, p->tot_len);
00928 #endif
00929   TCP_STATS_INC(tcp.xmit);
00930 
00931   /* Send output to IP */
00932 #if LWIP_NETIF_HWADDRHINT
00933   {
00934     struct netif *netif;
00935     netif = ip_route(&pcb->remote_ip);
00936     if(netif != NULL){
00937       netif->addr_hint = &(pcb->addr_hint);
00938       ip_output_if(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl,
00939                    0, IP_PROTO_TCP, netif);
00940       netif->addr_hint = NULL;
00941     }
00942   }
00943 #else /* LWIP_NETIF_HWADDRHINT*/
00944   ip_output(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP);
00945 #endif /* LWIP_NETIF_HWADDRHINT*/
00946 
00947   pbuf_free(p);
00948 
00949   LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: seqno %"U32_F
00950                           " ackno %"U32_F".\n",
00951                           pcb->snd_nxt - 1, pcb->rcv_nxt));
00952 }
00953 #endif /* LWIP_TCP */