My fork of the HTTPServer (working)
Embed:
(wiki syntax)
Show/hide line numbers
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 */
Generated on Tue Jul 12 2022 19:24:06 by 1.7.2