My fork of the HTTPServer (working)

Dependents:   DGWWebServer LAN2

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