A version of LWIP, provided for backwards compatibility.
Dependents: AA_DemoBoard DemoBoard HelloServerDemo DemoBoard_RangeIndicator ... more
tcp_out.c
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 */
Generated on Tue Jul 12 2022 16:06:25 by 1.7.2