Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
lwip_tcp_out.c
00001 /** 00002 * @file 00003 * Transmission Control Protocol, outgoing traffic 00004 * 00005 * The output functions of TCP. 00006 * 00007 * There are two distinct ways for TCP segments to get sent: 00008 * - queued data: these are segments transferring data or segments containing 00009 * SYN or FIN (which both count as one sequence number). They are created as 00010 * struct @ref pbuf together with a struct tcp_seg and enqueue to the 00011 * unsent list of the pcb. They are sent by tcp_output: 00012 * - @ref tcp_write : creates data segments 00013 * - @ref tcp_split_unsent_seg : splits a data segment 00014 * - @ref tcp_enqueue_flags : creates SYN-only or FIN-only segments 00015 * - @ref tcp_output / tcp_output_segment : finalize the tcp header 00016 * (e.g. sequence numbers, options, checksum) and output to IP 00017 * - the various tcp_rexmit functions shuffle around segments between the 00018 * unsent an unacked lists to retransmit them 00019 * - tcp_create_segment and tcp_pbuf_prealloc allocate pbuf and 00020 * segment for these functions 00021 * - direct send: these segments don't contain data but control the connection 00022 * behaviour. They are created as pbuf only and sent directly without 00023 * enqueueing them: 00024 * - @ref tcp_send_empty_ack sends an ACK-only segment 00025 * - @ref tcp_rst sends a RST segment 00026 * - @ref tcp_keepalive sends a keepalive segment 00027 * - @ref tcp_zero_window_probe sends a window probe segment 00028 * - tcp_output_alloc_header allocates a header-only pbuf for these functions 00029 */ 00030 00031 /* 00032 * Copyright (c) 2001-2004 Swedish Institute of Computer Science. 00033 * All rights reserved. 00034 * 00035 * Redistribution and use in source and binary forms, with or without modification, 00036 * are permitted provided that the following conditions are met: 00037 * 00038 * 1. Redistributions of source code must retain the above copyright notice, 00039 * this list of conditions and the following disclaimer. 00040 * 2. Redistributions in binary form must reproduce the above copyright notice, 00041 * this list of conditions and the following disclaimer in the documentation 00042 * and/or other materials provided with the distribution. 00043 * 3. The name of the author may not be used to endorse or promote products 00044 * derived from this software without specific prior written permission. 00045 * 00046 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 00047 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 00048 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 00049 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00050 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 00051 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00052 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00053 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 00054 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 00055 * OF SUCH DAMAGE. 00056 * 00057 * This file is part of the lwIP TCP/IP stack. 00058 * 00059 * Author: Adam Dunkels <adam@sics.se> 00060 * 00061 */ 00062 00063 #include "lwip/opt.h" 00064 00065 #if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ 00066 00067 #include "lwip/priv/tcp_priv.h" 00068 #include "lwip/def.h" 00069 #include "lwip/mem.h" 00070 #include "lwip/memp.h" 00071 #include "lwip/ip_addr.h" 00072 #include "lwip/netif.h" 00073 #include "lwip/inet_chksum.h" 00074 #include "lwip/stats.h" 00075 #include "lwip/ip6.h" 00076 #include "lwip/ip6_addr.h" 00077 #if LWIP_TCP_TIMESTAMPS 00078 #include "lwip/sys.h" 00079 #endif 00080 00081 #include <string.h> 00082 00083 #ifdef LWIP_HOOK_FILENAME 00084 #include LWIP_HOOK_FILENAME 00085 #endif 00086 00087 /* Allow to add custom TCP header options by defining this hook */ 00088 #ifdef LWIP_HOOK_TCP_OUT_TCPOPT_LENGTH 00089 #define LWIP_TCP_OPT_LENGTH_SEGMENT(flags, pcb) LWIP_HOOK_TCP_OUT_TCPOPT_LENGTH(pcb, LWIP_TCP_OPT_LENGTH(flags)) 00090 #else 00091 #define LWIP_TCP_OPT_LENGTH_SEGMENT(flags, pcb) LWIP_TCP_OPT_LENGTH(flags) 00092 #endif 00093 00094 /* Define some copy-macros for checksum-on-copy so that the code looks 00095 nicer by preventing too many ifdef's. */ 00096 #if TCP_CHECKSUM_ON_COPY 00097 #define TCP_DATA_COPY(dst, src, len, seg) do { \ 00098 tcp_seg_add_chksum(LWIP_CHKSUM_COPY(dst, src, len), \ 00099 len, &seg->chksum, &seg->chksum_swapped); \ 00100 seg->flags |= TF_SEG_DATA_CHECKSUMMED; } while(0) 00101 #define TCP_DATA_COPY2(dst, src, len, chksum, chksum_swapped) \ 00102 tcp_seg_add_chksum(LWIP_CHKSUM_COPY(dst, src, len), len, chksum, chksum_swapped); 00103 #else /* TCP_CHECKSUM_ON_COPY*/ 00104 #define TCP_DATA_COPY(dst, src, len, seg) MEMCPY(dst, src, len) 00105 #define TCP_DATA_COPY2(dst, src, len, chksum, chksum_swapped) MEMCPY(dst, src, len) 00106 #endif /* TCP_CHECKSUM_ON_COPY*/ 00107 00108 /** Define this to 1 for an extra check that the output checksum is valid 00109 * (usefule when the checksum is generated by the application, not the stack) */ 00110 #ifndef TCP_CHECKSUM_ON_COPY_SANITY_CHECK 00111 #define TCP_CHECKSUM_ON_COPY_SANITY_CHECK 0 00112 #endif 00113 /* Allow to override the failure of sanity check from warning to e.g. hard failure */ 00114 #if TCP_CHECKSUM_ON_COPY_SANITY_CHECK 00115 #ifndef TCP_CHECKSUM_ON_COPY_SANITY_CHECK_FAIL 00116 #define TCP_CHECKSUM_ON_COPY_SANITY_CHECK_FAIL(msg) LWIP_DEBUGF(TCP_DEBUG | LWIP_DBG_LEVEL_WARNING, msg) 00117 #endif 00118 #endif 00119 00120 #if TCP_OVERSIZE 00121 /** The size of segment pbufs created when TCP_OVERSIZE is enabled */ 00122 #ifndef TCP_OVERSIZE_CALC_LENGTH 00123 #define TCP_OVERSIZE_CALC_LENGTH(length) ((length) + TCP_OVERSIZE) 00124 #endif 00125 #endif 00126 00127 /* Forward declarations.*/ 00128 static err_t tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif); 00129 00130 /* tcp_route: common code that returns a fixed bound netif or calls ip_route */ 00131 static struct netif * 00132 tcp_route(const struct tcp_pcb *pcb, const ip_addr_t *src, const ip_addr_t *dst) 00133 { 00134 LWIP_UNUSED_ARG(src); /* in case IPv4-only and source-based routing is disabled */ 00135 00136 if ((pcb != NULL) && (pcb->netif_idx != NETIF_NO_INDEX)) { 00137 return netif_get_by_index(pcb->netif_idx); 00138 } else { 00139 return ip_route(src, dst); 00140 } 00141 } 00142 00143 /** 00144 * Create a TCP segment with prefilled header. 00145 * 00146 * Called by @ref tcp_write, @ref tcp_enqueue_flags and @ref tcp_split_unsent_seg 00147 * 00148 * @param pcb Protocol control block for the TCP connection. 00149 * @param p pbuf that is used to hold the TCP header. 00150 * @param hdrflags TCP flags for header. 00151 * @param seqno TCP sequence number of this packet 00152 * @param optflags options to include in TCP header 00153 * @return a new tcp_seg pointing to p, or NULL. 00154 * The TCP header is filled in except ackno and wnd. 00155 * p is freed on failure. 00156 */ 00157 static struct tcp_seg * 00158 tcp_create_segment(const struct tcp_pcb *pcb, struct pbuf *p, u8_t hdrflags, u32_t seqno, u8_t optflags) 00159 { 00160 struct tcp_seg *seg; 00161 u8_t optlen; 00162 00163 LWIP_ASSERT("tcp_create_segment: invalid pcb", pcb != NULL); 00164 LWIP_ASSERT("tcp_create_segment: invalid pbuf", p != NULL); 00165 00166 optlen = LWIP_TCP_OPT_LENGTH_SEGMENT(optflags, pcb); 00167 00168 if ((seg = (struct tcp_seg *)memp_malloc(MEMP_TCP_SEG)) == NULL) { 00169 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_create_segment: no memory.\n")); 00170 pbuf_free(p); 00171 return NULL; 00172 } 00173 seg->flags = optflags; 00174 seg->next = NULL; 00175 seg->p = p; 00176 LWIP_ASSERT("p->tot_len >= optlen", p->tot_len >= optlen); 00177 seg->len = p->tot_len - optlen; 00178 #if TCP_OVERSIZE_DBGCHECK 00179 seg->oversize_left = 0; 00180 #endif /* TCP_OVERSIZE_DBGCHECK */ 00181 #if TCP_CHECKSUM_ON_COPY 00182 seg->chksum = 0; 00183 seg->chksum_swapped = 0; 00184 /* check optflags */ 00185 LWIP_ASSERT("invalid optflags passed: TF_SEG_DATA_CHECKSUMMED", 00186 (optflags & TF_SEG_DATA_CHECKSUMMED) == 0); 00187 #endif /* TCP_CHECKSUM_ON_COPY */ 00188 00189 /* build TCP header */ 00190 if (pbuf_add_header(p, TCP_HLEN)) { 00191 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_create_segment: no room for TCP header in pbuf.\n")); 00192 TCP_STATS_INC(tcp.err); 00193 tcp_seg_free(seg); 00194 return NULL; 00195 } 00196 seg->tcphdr = (struct tcp_hdr *)seg->p->payload; 00197 seg->tcphdr->src = lwip_htons(pcb->local_port); 00198 seg->tcphdr->dest = lwip_htons(pcb->remote_port); 00199 seg->tcphdr->seqno = lwip_htonl(seqno); 00200 /* ackno is set in tcp_output */ 00201 TCPH_HDRLEN_FLAGS_SET(seg->tcphdr, (5 + optlen / 4), hdrflags); 00202 /* wnd and chksum are set in tcp_output */ 00203 seg->tcphdr->urgp = 0; 00204 return seg; 00205 } 00206 00207 /** 00208 * Allocate a PBUF_RAM pbuf, perhaps with extra space at the end. 00209 * 00210 * This function is like pbuf_alloc(layer, length, PBUF_RAM) except 00211 * there may be extra bytes available at the end. 00212 * 00213 * Called by @ref tcp_write 00214 * 00215 * @param layer flag to define header size. 00216 * @param length size of the pbuf's payload. 00217 * @param max_length maximum usable size of payload+oversize. 00218 * @param oversize pointer to a u16_t that will receive the number of usable tail bytes. 00219 * @param pcb The TCP connection that will enqueue the pbuf. 00220 * @param apiflags API flags given to tcp_write. 00221 * @param first_seg true when this pbuf will be used in the first enqueued segment. 00222 */ 00223 #if TCP_OVERSIZE 00224 static struct pbuf * 00225 tcp_pbuf_prealloc(pbuf_layer layer, u16_t length, u16_t max_length, 00226 u16_t *oversize, const struct tcp_pcb *pcb, u8_t apiflags, 00227 u8_t first_seg) 00228 { 00229 struct pbuf *p; 00230 u16_t alloc = length; 00231 00232 LWIP_ASSERT("tcp_pbuf_prealloc: invalid oversize", oversize != NULL); 00233 LWIP_ASSERT("tcp_pbuf_prealloc: invalid pcb", pcb != NULL); 00234 00235 #if LWIP_NETIF_TX_SINGLE_PBUF 00236 LWIP_UNUSED_ARG(max_length); 00237 LWIP_UNUSED_ARG(pcb); 00238 LWIP_UNUSED_ARG(apiflags); 00239 LWIP_UNUSED_ARG(first_seg); 00240 alloc = max_length; 00241 #else /* LWIP_NETIF_TX_SINGLE_PBUF */ 00242 if (length < max_length) { 00243 /* Should we allocate an oversized pbuf, or just the minimum 00244 * length required? If tcp_write is going to be called again 00245 * before this segment is transmitted, we want the oversized 00246 * buffer. If the segment will be transmitted immediately, we can 00247 * save memory by allocating only length. We use a simple 00248 * heuristic based on the following information: 00249 * 00250 * Did the user set TCP_WRITE_FLAG_MORE? 00251 * 00252 * Will the Nagle algorithm defer transmission of this segment? 00253 */ 00254 if ((apiflags & TCP_WRITE_FLAG_MORE) || 00255 (!(pcb->flags & TF_NODELAY) && 00256 (!first_seg || 00257 pcb->unsent != NULL || 00258 pcb->unacked != NULL))) { 00259 alloc = LWIP_MIN(max_length, LWIP_MEM_ALIGN_SIZE(TCP_OVERSIZE_CALC_LENGTH(length))); 00260 } 00261 } 00262 #endif /* LWIP_NETIF_TX_SINGLE_PBUF */ 00263 p = pbuf_alloc(layer, alloc, PBUF_RAM); 00264 if (p == NULL) { 00265 return NULL; 00266 } 00267 LWIP_ASSERT("need unchained pbuf", p->next == NULL); 00268 *oversize = p->len - length; 00269 /* trim p->len to the currently used size */ 00270 p->len = p->tot_len = length; 00271 return p; 00272 } 00273 #else /* TCP_OVERSIZE */ 00274 #define tcp_pbuf_prealloc(layer, length, mx, os, pcb, api, fst) pbuf_alloc((layer), (length), PBUF_RAM) 00275 #endif /* TCP_OVERSIZE */ 00276 00277 #if TCP_CHECKSUM_ON_COPY 00278 /** Add a checksum of newly added data to the segment. 00279 * 00280 * Called by tcp_write and tcp_split_unsent_seg. 00281 */ 00282 static void 00283 tcp_seg_add_chksum(u16_t chksum, u16_t len, u16_t *seg_chksum, 00284 u8_t *seg_chksum_swapped) 00285 { 00286 u32_t helper; 00287 /* add chksum to old chksum and fold to u16_t */ 00288 helper = chksum + *seg_chksum; 00289 chksum = FOLD_U32T(helper); 00290 if ((len & 1) != 0) { 00291 *seg_chksum_swapped = 1 - *seg_chksum_swapped; 00292 chksum = SWAP_BYTES_IN_WORD(chksum); 00293 } 00294 *seg_chksum = chksum; 00295 } 00296 #endif /* TCP_CHECKSUM_ON_COPY */ 00297 00298 /** Checks if tcp_write is allowed or not (checks state, snd_buf and snd_queuelen). 00299 * 00300 * @param pcb the tcp pcb to check for 00301 * @param len length of data to send (checked agains snd_buf) 00302 * @return ERR_OK if tcp_write is allowed to proceed, another err_t otherwise 00303 */ 00304 static err_t 00305 tcp_write_checks(struct tcp_pcb *pcb, u16_t len) 00306 { 00307 LWIP_ASSERT("tcp_write_checks: invalid pcb", pcb != NULL); 00308 00309 /* connection is in invalid state for data transmission? */ 00310 if ((pcb->state != ESTABLISHED) && 00311 (pcb->state != CLOSE_WAIT) && 00312 (pcb->state != SYN_SENT) && 00313 (pcb->state != SYN_RCVD)) { 00314 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_STATE | LWIP_DBG_LEVEL_SEVERE, ("tcp_write() called in invalid state\n")); 00315 return ERR_CONN; 00316 } else if (len == 0) { 00317 return ERR_OK; 00318 } 00319 00320 /* fail on too much data */ 00321 if (len > pcb->snd_buf) { 00322 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("tcp_write: too much data (len=%"U16_F" > snd_buf=%"TCPWNDSIZE_F")\n", 00323 len, pcb->snd_buf)); 00324 tcp_set_flags(pcb, TF_NAGLEMEMERR); 00325 return ERR_MEM; 00326 } 00327 00328 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_write: queuelen: %"TCPWNDSIZE_F"\n", (tcpwnd_size_t)pcb->snd_queuelen)); 00329 00330 /* If total number of pbufs on the unsent/unacked queues exceeds the 00331 * configured maximum, return an error */ 00332 /* check for configured max queuelen and possible overflow */ 00333 if (pcb->snd_queuelen >= LWIP_MIN(TCP_SND_QUEUELEN, (TCP_SNDQUEUELEN_OVERFLOW + 1))) { 00334 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("tcp_write: too long queue %"U16_F" (max %"U16_F")\n", 00335 pcb->snd_queuelen, (u16_t)TCP_SND_QUEUELEN)); 00336 TCP_STATS_INC(tcp.memerr); 00337 tcp_set_flags(pcb, TF_NAGLEMEMERR); 00338 return ERR_MEM; 00339 } 00340 if (pcb->snd_queuelen != 0) { 00341 LWIP_ASSERT("tcp_write: pbufs on queue => at least one queue non-empty", 00342 pcb->unacked != NULL || pcb->unsent != NULL); 00343 } else { 00344 LWIP_ASSERT("tcp_write: no pbufs on queue => both queues empty", 00345 pcb->unacked == NULL && pcb->unsent == NULL); 00346 } 00347 return ERR_OK; 00348 } 00349 00350 /** 00351 * @ingroup tcp_raw 00352 * Write data for sending (but does not send it immediately). 00353 * 00354 * It waits in the expectation of more data being sent soon (as 00355 * it can send them more efficiently by combining them together). 00356 * To prompt the system to send data now, call tcp_output() after 00357 * calling tcp_write(). 00358 * 00359 * This function enqueues the data pointed to by the argument dataptr. The length of 00360 * the data is passed as the len parameter. The apiflags can be one or more of: 00361 * - TCP_WRITE_FLAG_COPY: indicates whether the new memory should be allocated 00362 * for the data to be copied into. If this flag is not given, no new memory 00363 * should be allocated and the data should only be referenced by pointer. This 00364 * also means that the memory behind dataptr must not change until the data is 00365 * ACKed by the remote host 00366 * - TCP_WRITE_FLAG_MORE: indicates that more data follows. If this is omitted, 00367 * the PSH flag is set in the last segment created by this call to tcp_write. 00368 * If this flag is given, the PSH flag is not set. 00369 * 00370 * The tcp_write() function will fail and return ERR_MEM if the length 00371 * of the data exceeds the current send buffer size or if the length of 00372 * the queue of outgoing segment is larger than the upper limit defined 00373 * in lwipopts.h. The number of bytes available in the output queue can 00374 * be retrieved with the tcp_sndbuf() function. 00375 * 00376 * The proper way to use this function is to call the function with at 00377 * most tcp_sndbuf() bytes of data. If the function returns ERR_MEM, 00378 * the application should wait until some of the currently enqueued 00379 * data has been successfully received by the other host and try again. 00380 * 00381 * @param pcb Protocol control block for the TCP connection to enqueue data for. 00382 * @param arg Pointer to the data to be enqueued for sending. 00383 * @param len Data length in bytes 00384 * @param apiflags combination of following flags : 00385 * - TCP_WRITE_FLAG_COPY (0x01) data will be copied into memory belonging to the stack 00386 * - TCP_WRITE_FLAG_MORE (0x02) for TCP connection, PSH flag will not be set on last segment sent, 00387 * @return ERR_OK if enqueued, another err_t on error 00388 */ 00389 err_t 00390 tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) 00391 { 00392 struct pbuf *concat_p = NULL; 00393 struct tcp_seg *last_unsent = NULL, *seg = NULL, *prev_seg = NULL, *queue = NULL; 00394 u16_t pos = 0; /* position in 'arg' data */ 00395 u16_t queuelen; 00396 u8_t optlen; 00397 u8_t optflags = 0; 00398 #if TCP_OVERSIZE 00399 u16_t oversize = 0; 00400 u16_t oversize_used = 0; 00401 #if TCP_OVERSIZE_DBGCHECK 00402 u16_t oversize_add = 0; 00403 #endif /* TCP_OVERSIZE_DBGCHECK*/ 00404 #endif /* TCP_OVERSIZE */ 00405 u16_t extendlen = 0; 00406 #if TCP_CHECKSUM_ON_COPY 00407 u16_t concat_chksum = 0; 00408 u8_t concat_chksum_swapped = 0; 00409 u16_t concat_chksummed = 0; 00410 #endif /* TCP_CHECKSUM_ON_COPY */ 00411 err_t err; 00412 u16_t mss_local; 00413 00414 LWIP_ERROR("tcp_write: invalid pcb", pcb != NULL, return ERR_ARG); 00415 00416 /* don't allocate segments bigger than half the maximum window we ever received */ 00417 mss_local = LWIP_MIN(pcb->mss, TCPWND_MIN16(pcb->snd_wnd_max / 2)); 00418 mss_local = mss_local ? mss_local : pcb->mss; 00419 00420 LWIP_ASSERT_CORE_LOCKED(); 00421 00422 #if LWIP_NETIF_TX_SINGLE_PBUF 00423 /* Always copy to try to create single pbufs for TX */ 00424 apiflags |= TCP_WRITE_FLAG_COPY; 00425 #endif /* LWIP_NETIF_TX_SINGLE_PBUF */ 00426 00427 LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_write(pcb=%p, data=%p, len=%"U16_F", apiflags=%"U16_F")\n", 00428 (void *)pcb, arg, len, (u16_t)apiflags)); 00429 LWIP_ERROR("tcp_write: arg == NULL (programmer violates API)", 00430 arg != NULL, return ERR_ARG;); 00431 00432 err = tcp_write_checks(pcb, len); 00433 if (err != ERR_OK) { 00434 return err; 00435 } 00436 queuelen = pcb->snd_queuelen; 00437 00438 #if LWIP_TCP_TIMESTAMPS 00439 if ((pcb->flags & TF_TIMESTAMP)) { 00440 /* Make sure the timestamp option is only included in data segments if we 00441 agreed about it with the remote host. */ 00442 optflags = TF_SEG_OPTS_TS; 00443 optlen = LWIP_TCP_OPT_LENGTH_SEGMENT(TF_SEG_OPTS_TS, pcb); 00444 /* ensure that segments can hold at least one data byte... */ 00445 mss_local = LWIP_MAX(mss_local, LWIP_TCP_OPT_LEN_TS + 1); 00446 } else 00447 #endif /* LWIP_TCP_TIMESTAMPS */ 00448 { 00449 optlen = LWIP_TCP_OPT_LENGTH_SEGMENT(0, pcb); 00450 } 00451 00452 00453 /* 00454 * TCP segmentation is done in three phases with increasing complexity: 00455 * 00456 * 1. Copy data directly into an oversized pbuf. 00457 * 2. Chain a new pbuf to the end of pcb->unsent. 00458 * 3. Create new segments. 00459 * 00460 * We may run out of memory at any point. In that case we must 00461 * return ERR_MEM and not change anything in pcb. Therefore, all 00462 * changes are recorded in local variables and committed at the end 00463 * of the function. Some pcb fields are maintained in local copies: 00464 * 00465 * queuelen = pcb->snd_queuelen 00466 * oversize = pcb->unsent_oversize 00467 * 00468 * These variables are set consistently by the phases: 00469 * 00470 * seg points to the last segment tampered with. 00471 * 00472 * pos records progress as data is segmented. 00473 */ 00474 00475 /* Find the tail of the unsent queue. */ 00476 if (pcb->unsent != NULL) { 00477 u16_t space; 00478 u16_t unsent_optlen; 00479 00480 /* @todo: this could be sped up by keeping last_unsent in the pcb */ 00481 for (last_unsent = pcb->unsent; last_unsent->next != NULL; 00482 last_unsent = last_unsent->next); 00483 00484 /* Usable space at the end of the last unsent segment */ 00485 unsent_optlen = LWIP_TCP_OPT_LENGTH_SEGMENT(last_unsent->flags, pcb); 00486 LWIP_ASSERT("mss_local is too small", mss_local >= last_unsent->len + unsent_optlen); 00487 space = mss_local - (last_unsent->len + unsent_optlen); 00488 00489 /* 00490 * Phase 1: Copy data directly into an oversized pbuf. 00491 * 00492 * The number of bytes copied is recorded in the oversize_used 00493 * variable. The actual copying is done at the bottom of the 00494 * function. 00495 */ 00496 #if TCP_OVERSIZE 00497 #if TCP_OVERSIZE_DBGCHECK 00498 /* check that pcb->unsent_oversize matches last_unsent->oversize_left */ 00499 LWIP_ASSERT("unsent_oversize mismatch (pcb vs. last_unsent)", 00500 pcb->unsent_oversize == last_unsent->oversize_left); 00501 #endif /* TCP_OVERSIZE_DBGCHECK */ 00502 oversize = pcb->unsent_oversize; 00503 if (oversize > 0) { 00504 LWIP_ASSERT("inconsistent oversize vs. space", oversize <= space); 00505 seg = last_unsent; 00506 oversize_used = LWIP_MIN(space, LWIP_MIN(oversize, len)); 00507 pos += oversize_used; 00508 oversize -= oversize_used; 00509 space -= oversize_used; 00510 } 00511 /* now we are either finished or oversize is zero */ 00512 LWIP_ASSERT("inconsistent oversize vs. len", (oversize == 0) || (pos == len)); 00513 #endif /* TCP_OVERSIZE */ 00514 00515 #if !LWIP_NETIF_TX_SINGLE_PBUF 00516 /* 00517 * Phase 2: Chain a new pbuf to the end of pcb->unsent. 00518 * 00519 * As an exception when NOT copying the data, if the given data buffer 00520 * directly follows the last unsent data buffer in memory, extend the last 00521 * ROM pbuf reference to the buffer, thus saving a ROM pbuf allocation. 00522 * 00523 * We don't extend segments containing SYN/FIN flags or options 00524 * (len==0). The new pbuf is kept in concat_p and pbuf_cat'ed at 00525 * the end. 00526 * 00527 * This phase is skipped for LWIP_NETIF_TX_SINGLE_PBUF as we could only execute 00528 * it after rexmit puts a segment from unacked to unsent and at this point, 00529 * oversize info is lost. 00530 */ 00531 if ((pos < len) && (space > 0) && (last_unsent->len > 0)) { 00532 u16_t seglen = LWIP_MIN(space, len - pos); 00533 seg = last_unsent; 00534 00535 /* Create a pbuf with a copy or reference to seglen bytes. We 00536 * can use PBUF_RAW here since the data appears in the middle of 00537 * a segment. A header will never be prepended. */ 00538 if (apiflags & TCP_WRITE_FLAG_COPY) { 00539 /* Data is copied */ 00540 if ((concat_p = tcp_pbuf_prealloc(PBUF_RAW, seglen, space, &oversize, pcb, apiflags, 1)) == NULL) { 00541 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, 00542 ("tcp_write : could not allocate memory for pbuf copy size %"U16_F"\n", 00543 seglen)); 00544 goto memerr; 00545 } 00546 #if TCP_OVERSIZE_DBGCHECK 00547 oversize_add = oversize; 00548 #endif /* TCP_OVERSIZE_DBGCHECK */ 00549 TCP_DATA_COPY2(concat_p->payload, (const u8_t *)arg + pos, seglen, &concat_chksum, &concat_chksum_swapped); 00550 #if TCP_CHECKSUM_ON_COPY 00551 concat_chksummed += seglen; 00552 #endif /* TCP_CHECKSUM_ON_COPY */ 00553 queuelen += pbuf_clen(concat_p); 00554 } else { 00555 /* Data is not copied */ 00556 /* If the last unsent pbuf is of type PBUF_ROM, try to extend it. */ 00557 struct pbuf *p; 00558 for (p = last_unsent->p; p->next != NULL; p = p->next); 00559 if (((p->type_internal & (PBUF_TYPE_FLAG_STRUCT_DATA_CONTIGUOUS | PBUF_TYPE_FLAG_DATA_VOLATILE)) == 0) && 00560 (const u8_t *)p->payload + p->len == (const u8_t *)arg) { 00561 LWIP_ASSERT("tcp_write: ROM pbufs cannot be oversized", pos == 0); 00562 extendlen = seglen; 00563 } else { 00564 if ((concat_p = pbuf_alloc(PBUF_RAW, seglen, PBUF_ROM)) == NULL) { 00565 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, 00566 ("tcp_write: could not allocate memory for zero-copy pbuf\n")); 00567 goto memerr; 00568 } 00569 /* reference the non-volatile payload data */ 00570 ((struct pbuf_rom *)concat_p)->payload = (const u8_t *)arg + pos; 00571 queuelen += pbuf_clen(concat_p); 00572 } 00573 #if TCP_CHECKSUM_ON_COPY 00574 /* calculate the checksum of nocopy-data */ 00575 tcp_seg_add_chksum(~inet_chksum((const u8_t *)arg + pos, seglen), seglen, 00576 &concat_chksum, &concat_chksum_swapped); 00577 concat_chksummed += seglen; 00578 #endif /* TCP_CHECKSUM_ON_COPY */ 00579 } 00580 00581 pos += seglen; 00582 } 00583 #endif /* !LWIP_NETIF_TX_SINGLE_PBUF */ 00584 } else { 00585 #if TCP_OVERSIZE 00586 LWIP_ASSERT("unsent_oversize mismatch (pcb->unsent is NULL)", 00587 pcb->unsent_oversize == 0); 00588 #endif /* TCP_OVERSIZE */ 00589 } 00590 00591 /* 00592 * Phase 3: Create new segments. 00593 * 00594 * The new segments are chained together in the local 'queue' 00595 * variable, ready to be appended to pcb->unsent. 00596 */ 00597 while (pos < len) { 00598 struct pbuf *p; 00599 u16_t left = len - pos; 00600 u16_t max_len = mss_local - optlen; 00601 u16_t seglen = LWIP_MIN(left, max_len); 00602 #if TCP_CHECKSUM_ON_COPY 00603 u16_t chksum = 0; 00604 u8_t chksum_swapped = 0; 00605 #endif /* TCP_CHECKSUM_ON_COPY */ 00606 00607 if (apiflags & TCP_WRITE_FLAG_COPY) { 00608 /* If copy is set, memory should be allocated and data copied 00609 * into pbuf */ 00610 if ((p = tcp_pbuf_prealloc(PBUF_TRANSPORT, seglen + optlen, mss_local, &oversize, pcb, apiflags, queue == NULL)) == NULL) { 00611 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_write : could not allocate memory for pbuf copy size %"U16_F"\n", seglen)); 00612 goto memerr; 00613 } 00614 LWIP_ASSERT("tcp_write: check that first pbuf can hold the complete seglen", 00615 (p->len >= seglen)); 00616 TCP_DATA_COPY2((char *)p->payload + optlen, (const u8_t *)arg + pos, seglen, &chksum, &chksum_swapped); 00617 } else { 00618 /* Copy is not set: First allocate a pbuf for holding the data. 00619 * Since the referenced data is available at least until it is 00620 * sent out on the link (as it has to be ACKed by the remote 00621 * party) we can safely use PBUF_ROM instead of PBUF_REF here. 00622 */ 00623 struct pbuf *p2; 00624 #if TCP_OVERSIZE 00625 LWIP_ASSERT("oversize == 0", oversize == 0); 00626 #endif /* TCP_OVERSIZE */ 00627 if ((p2 = pbuf_alloc(PBUF_TRANSPORT, seglen, PBUF_ROM)) == NULL) { 00628 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_write: could not allocate memory for zero-copy pbuf\n")); 00629 goto memerr; 00630 } 00631 #if TCP_CHECKSUM_ON_COPY 00632 /* calculate the checksum of nocopy-data */ 00633 chksum = ~inet_chksum((const u8_t *)arg + pos, seglen); 00634 if (seglen & 1) { 00635 chksum_swapped = 1; 00636 chksum = SWAP_BYTES_IN_WORD(chksum); 00637 } 00638 #endif /* TCP_CHECKSUM_ON_COPY */ 00639 /* reference the non-volatile payload data */ 00640 ((struct pbuf_rom *)p2)->payload = (const u8_t *)arg + pos; 00641 00642 /* Second, allocate a pbuf for the headers. */ 00643 if ((p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) { 00644 /* If allocation fails, we have to deallocate the data pbuf as 00645 * well. */ 00646 pbuf_free(p2); 00647 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_write: could not allocate memory for header pbuf\n")); 00648 goto memerr; 00649 } 00650 /* Concatenate the headers and data pbufs together. */ 00651 pbuf_cat(p/*header*/, p2/*data*/); 00652 } 00653 00654 queuelen += pbuf_clen(p); 00655 00656 /* Now that there are more segments queued, we check again if the 00657 * length of the queue exceeds the configured maximum or 00658 * overflows. */ 00659 if (queuelen > LWIP_MIN(TCP_SND_QUEUELEN, TCP_SNDQUEUELEN_OVERFLOW)) { 00660 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_write: queue too long %"U16_F" (%d)\n", 00661 queuelen, (int)TCP_SND_QUEUELEN)); 00662 pbuf_free(p); 00663 goto memerr; 00664 } 00665 00666 if ((seg = tcp_create_segment(pcb, p, 0, pcb->snd_lbb + pos, optflags)) == NULL) { 00667 goto memerr; 00668 } 00669 #if TCP_OVERSIZE_DBGCHECK 00670 seg->oversize_left = oversize; 00671 #endif /* TCP_OVERSIZE_DBGCHECK */ 00672 #if TCP_CHECKSUM_ON_COPY 00673 seg->chksum = chksum; 00674 seg->chksum_swapped = chksum_swapped; 00675 seg->flags |= TF_SEG_DATA_CHECKSUMMED; 00676 #endif /* TCP_CHECKSUM_ON_COPY */ 00677 00678 /* first segment of to-be-queued data? */ 00679 if (queue == NULL) { 00680 queue = seg; 00681 } else { 00682 /* Attach the segment to the end of the queued segments */ 00683 LWIP_ASSERT("prev_seg != NULL", prev_seg != NULL); 00684 prev_seg->next = seg; 00685 } 00686 /* remember last segment of to-be-queued data for next iteration */ 00687 prev_seg = seg; 00688 00689 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_TRACE, ("tcp_write: queueing %"U32_F":%"U32_F"\n", 00690 lwip_ntohl(seg->tcphdr->seqno), 00691 lwip_ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg))); 00692 00693 pos += seglen; 00694 } 00695 00696 /* 00697 * All three segmentation phases were successful. We can commit the 00698 * transaction. 00699 */ 00700 #if TCP_OVERSIZE_DBGCHECK 00701 if ((last_unsent != NULL) && (oversize_add != 0)) { 00702 last_unsent->oversize_left += oversize_add; 00703 } 00704 #endif /* TCP_OVERSIZE_DBGCHECK */ 00705 00706 /* 00707 * Phase 1: If data has been added to the preallocated tail of 00708 * last_unsent, we update the length fields of the pbuf chain. 00709 */ 00710 #if TCP_OVERSIZE 00711 if (oversize_used > 0) { 00712 struct pbuf *p; 00713 /* Bump tot_len of whole chain, len of tail */ 00714 for (p = last_unsent->p; p; p = p->next) { 00715 p->tot_len += oversize_used; 00716 if (p->next == NULL) { 00717 TCP_DATA_COPY((char *)p->payload + p->len, arg, oversize_used, last_unsent); 00718 p->len += oversize_used; 00719 } 00720 } 00721 last_unsent->len += oversize_used; 00722 #if TCP_OVERSIZE_DBGCHECK 00723 LWIP_ASSERT("last_unsent->oversize_left >= oversize_used", 00724 last_unsent->oversize_left >= oversize_used); 00725 last_unsent->oversize_left -= oversize_used; 00726 #endif /* TCP_OVERSIZE_DBGCHECK */ 00727 } 00728 pcb->unsent_oversize = oversize; 00729 #endif /* TCP_OVERSIZE */ 00730 00731 /* 00732 * Phase 2: concat_p can be concatenated onto last_unsent->p, unless we 00733 * determined that the last ROM pbuf can be extended to include the new data. 00734 */ 00735 if (concat_p != NULL) { 00736 LWIP_ASSERT("tcp_write: cannot concatenate when pcb->unsent is empty", 00737 (last_unsent != NULL)); 00738 pbuf_cat(last_unsent->p, concat_p); 00739 last_unsent->len += concat_p->tot_len; 00740 } else if (extendlen > 0) { 00741 struct pbuf *p; 00742 LWIP_ASSERT("tcp_write: extension of reference requires reference", 00743 last_unsent != NULL && last_unsent->p != NULL); 00744 for (p = last_unsent->p; p->next != NULL; p = p->next) { 00745 p->tot_len += extendlen; 00746 } 00747 p->tot_len += extendlen; 00748 p->len += extendlen; 00749 last_unsent->len += extendlen; 00750 } 00751 00752 #if TCP_CHECKSUM_ON_COPY 00753 if (concat_chksummed) { 00754 LWIP_ASSERT("tcp_write: concat checksum needs concatenated data", 00755 concat_p != NULL || extendlen > 0); 00756 /*if concat checksumm swapped - swap it back */ 00757 if (concat_chksum_swapped) { 00758 concat_chksum = SWAP_BYTES_IN_WORD(concat_chksum); 00759 } 00760 tcp_seg_add_chksum(concat_chksum, concat_chksummed, &last_unsent->chksum, 00761 &last_unsent->chksum_swapped); 00762 last_unsent->flags |= TF_SEG_DATA_CHECKSUMMED; 00763 } 00764 #endif /* TCP_CHECKSUM_ON_COPY */ 00765 00766 /* 00767 * Phase 3: Append queue to pcb->unsent. Queue may be NULL, but that 00768 * is harmless 00769 */ 00770 if (last_unsent == NULL) { 00771 pcb->unsent = queue; 00772 } else { 00773 last_unsent->next = queue; 00774 } 00775 00776 /* 00777 * Finally update the pcb state. 00778 */ 00779 pcb->snd_lbb += len; 00780 pcb->snd_buf -= len; 00781 pcb->snd_queuelen = queuelen; 00782 00783 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_write: %"S16_F" (after enqueued)\n", 00784 pcb->snd_queuelen)); 00785 if (pcb->snd_queuelen != 0) { 00786 LWIP_ASSERT("tcp_write: valid queue length", 00787 pcb->unacked != NULL || pcb->unsent != NULL); 00788 } 00789 00790 /* Set the PSH flag in the last segment that we enqueued. */ 00791 if (seg != NULL && seg->tcphdr != NULL && ((apiflags & TCP_WRITE_FLAG_MORE) == 0)) { 00792 TCPH_SET_FLAG(seg->tcphdr, TCP_PSH); 00793 } 00794 00795 return ERR_OK; 00796 memerr: 00797 tcp_set_flags(pcb, TF_NAGLEMEMERR); 00798 TCP_STATS_INC(tcp.memerr); 00799 00800 if (concat_p != NULL) { 00801 pbuf_free(concat_p); 00802 } 00803 if (queue != NULL) { 00804 tcp_segs_free(queue); 00805 } 00806 if (pcb->snd_queuelen != 0) { 00807 LWIP_ASSERT("tcp_write: valid queue length", pcb->unacked != NULL || 00808 pcb->unsent != NULL); 00809 } 00810 LWIP_DEBUGF(TCP_QLEN_DEBUG | LWIP_DBG_STATE, ("tcp_write: %"S16_F" (with mem err)\n", pcb->snd_queuelen)); 00811 return ERR_MEM; 00812 } 00813 00814 /** 00815 * Split segment on the head of the unsent queue. If return is not 00816 * ERR_OK, existing head remains intact 00817 * 00818 * The split is accomplished by creating a new TCP segment and pbuf 00819 * which holds the remainder payload after the split. The original 00820 * pbuf is trimmed to new length. This allows splitting of read-only 00821 * pbufs 00822 * 00823 * @param pcb the tcp_pcb for which to split the unsent head 00824 * @param split the amount of payload to remain in the head 00825 */ 00826 err_t 00827 tcp_split_unsent_seg(struct tcp_pcb *pcb, u16_t split) 00828 { 00829 struct tcp_seg *seg = NULL, *useg = NULL; 00830 struct pbuf *p = NULL; 00831 u8_t optlen; 00832 u8_t optflags; 00833 u8_t split_flags; 00834 u8_t remainder_flags; 00835 u16_t remainder; 00836 u16_t offset; 00837 #if TCP_CHECKSUM_ON_COPY 00838 u16_t chksum = 0; 00839 u8_t chksum_swapped = 0; 00840 struct pbuf *q; 00841 #endif /* TCP_CHECKSUM_ON_COPY */ 00842 00843 LWIP_ASSERT("tcp_split_unsent_seg: invalid pcb", pcb != NULL); 00844 00845 useg = pcb->unsent; 00846 if (useg == NULL) { 00847 return ERR_MEM; 00848 } 00849 00850 if (split == 0) { 00851 LWIP_ASSERT("Can't split segment into length 0", 0); 00852 return ERR_VAL; 00853 } 00854 00855 if (useg->len <= split) { 00856 return ERR_OK; 00857 } 00858 00859 LWIP_ASSERT("split <= mss", split <= pcb->mss); 00860 LWIP_ASSERT("useg->len > 0", useg->len > 0); 00861 00862 /* We should check that we don't exceed TCP_SND_QUEUELEN but we need 00863 * to split this packet so we may actually exceed the max value by 00864 * one! 00865 */ 00866 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue: split_unsent_seg: %u\n", (unsigned int)pcb->snd_queuelen)); 00867 00868 optflags = useg->flags; 00869 #if TCP_CHECKSUM_ON_COPY 00870 /* Remove since checksum is not stored until after tcp_create_segment() */ 00871 optflags &= ~TF_SEG_DATA_CHECKSUMMED; 00872 #endif /* TCP_CHECKSUM_ON_COPY */ 00873 optlen = LWIP_TCP_OPT_LENGTH(optflags); 00874 remainder = useg->len - split; 00875 00876 /* Create new pbuf for the remainder of the split */ 00877 p = pbuf_alloc(PBUF_TRANSPORT, remainder + optlen, PBUF_RAM); 00878 if (p == NULL) { 00879 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, 00880 ("tcp_split_unsent_seg: could not allocate memory for pbuf remainder %u\n", remainder)); 00881 goto memerr; 00882 } 00883 00884 /* Offset into the original pbuf is past TCP/IP headers, options, and split amount */ 00885 offset = useg->p->tot_len - useg->len + split; 00886 /* Copy remainder into new pbuf, headers and options will not be filled out */ 00887 if (pbuf_copy_partial(useg->p, (u8_t *)p->payload + optlen, remainder, offset ) != remainder) { 00888 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, 00889 ("tcp_split_unsent_seg: could not copy pbuf remainder %u\n", remainder)); 00890 goto memerr; 00891 } 00892 #if TCP_CHECKSUM_ON_COPY 00893 /* calculate the checksum on remainder data */ 00894 tcp_seg_add_chksum(~inet_chksum((const u8_t *)p->payload + optlen, remainder), remainder, 00895 &chksum, &chksum_swapped); 00896 #endif /* TCP_CHECKSUM_ON_COPY */ 00897 00898 /* Options are created when calling tcp_output() */ 00899 00900 /* Migrate flags from original segment */ 00901 split_flags = TCPH_FLAGS(useg->tcphdr); 00902 remainder_flags = 0; /* ACK added in tcp_output() */ 00903 00904 if (split_flags & TCP_PSH) { 00905 split_flags &= ~TCP_PSH; 00906 remainder_flags |= TCP_PSH; 00907 } 00908 if (split_flags & TCP_FIN) { 00909 split_flags &= ~TCP_FIN; 00910 remainder_flags |= TCP_FIN; 00911 } 00912 /* SYN should be left on split, RST should not be present with data */ 00913 00914 seg = tcp_create_segment(pcb, p, remainder_flags, lwip_ntohl(useg->tcphdr->seqno) + split, optflags); 00915 if (seg == NULL) { 00916 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, 00917 ("tcp_split_unsent_seg: could not create new TCP segment\n")); 00918 goto memerr; 00919 } 00920 00921 #if TCP_CHECKSUM_ON_COPY 00922 seg->chksum = chksum; 00923 seg->chksum_swapped = chksum_swapped; 00924 seg->flags |= TF_SEG_DATA_CHECKSUMMED; 00925 #endif /* TCP_CHECKSUM_ON_COPY */ 00926 00927 /* Remove this segment from the queue since trimming it may free pbufs */ 00928 pcb->snd_queuelen -= pbuf_clen(useg->p); 00929 00930 /* Trim the original pbuf into our split size. At this point our remainder segment must be setup 00931 successfully because we are modifying the original segment */ 00932 pbuf_realloc(useg->p, useg->p->tot_len - remainder); 00933 useg->len -= remainder; 00934 TCPH_SET_FLAG(useg->tcphdr, split_flags); 00935 #if TCP_OVERSIZE_DBGCHECK 00936 /* By trimming, realloc may have actually shrunk the pbuf, so clear oversize_left */ 00937 useg->oversize_left = 0; 00938 #endif /* TCP_OVERSIZE_DBGCHECK */ 00939 00940 /* Add back to the queue with new trimmed pbuf */ 00941 pcb->snd_queuelen += pbuf_clen(useg->p); 00942 00943 #if TCP_CHECKSUM_ON_COPY 00944 /* The checksum on the split segment is now incorrect. We need to re-run it over the split */ 00945 useg->chksum = 0; 00946 useg->chksum_swapped = 0; 00947 q = useg->p; 00948 offset = q->tot_len - useg->len; /* Offset due to exposed headers */ 00949 00950 /* Advance to the pbuf where the offset ends */ 00951 while (q != NULL && offset > q->len) { 00952 offset -= q->len; 00953 q = q->next; 00954 } 00955 LWIP_ASSERT("Found start of payload pbuf", q != NULL); 00956 /* Checksum the first payload pbuf accounting for offset, then other pbufs are all payload */ 00957 for (; q != NULL; offset = 0, q = q->next) { 00958 tcp_seg_add_chksum(~inet_chksum((const u8_t *)q->payload + offset, q->len - offset), q->len - offset, 00959 &useg->chksum, &useg->chksum_swapped); 00960 } 00961 #endif /* TCP_CHECKSUM_ON_COPY */ 00962 00963 /* Update number of segments on the queues. Note that length now may 00964 * exceed TCP_SND_QUEUELEN! We don't have to touch pcb->snd_buf 00965 * because the total amount of data is constant when packet is split */ 00966 pcb->snd_queuelen += pbuf_clen(seg->p); 00967 00968 /* Finally insert remainder into queue after split (which stays head) */ 00969 seg->next = useg->next; 00970 useg->next = seg; 00971 00972 #if TCP_OVERSIZE 00973 /* If remainder is last segment on the unsent, ensure we clear the oversize amount 00974 * because the remainder is always sized to the exact remaining amount */ 00975 if (seg->next == NULL) { 00976 pcb->unsent_oversize = 0; 00977 } 00978 #endif /* TCP_OVERSIZE */ 00979 00980 return ERR_OK; 00981 memerr: 00982 TCP_STATS_INC(tcp.memerr); 00983 00984 LWIP_ASSERT("seg == NULL", seg == NULL); 00985 if (p != NULL) { 00986 pbuf_free(p); 00987 } 00988 00989 return ERR_MEM; 00990 } 00991 00992 /** 00993 * Called by tcp_close() to send a segment including FIN flag but not data. 00994 * This FIN may be added to an existing segment or a new, otherwise empty 00995 * segment is enqueued. 00996 * 00997 * @param pcb the tcp_pcb over which to send a segment 00998 * @return ERR_OK if sent, another err_t otherwise 00999 */ 01000 err_t 01001 tcp_send_fin(struct tcp_pcb *pcb) 01002 { 01003 LWIP_ASSERT("tcp_send_fin: invalid pcb", pcb != NULL); 01004 01005 /* first, try to add the fin to the last unsent segment */ 01006 if (pcb->unsent != NULL) { 01007 struct tcp_seg *last_unsent; 01008 for (last_unsent = pcb->unsent; last_unsent->next != NULL; 01009 last_unsent = last_unsent->next); 01010 01011 if ((TCPH_FLAGS(last_unsent->tcphdr) & (TCP_SYN | TCP_FIN | TCP_RST)) == 0) { 01012 /* no SYN/FIN/RST flag in the header, we can add the FIN flag */ 01013 TCPH_SET_FLAG(last_unsent->tcphdr, TCP_FIN); 01014 tcp_set_flags(pcb, TF_FIN); 01015 return ERR_OK; 01016 } 01017 } 01018 /* no data, no length, flags, copy=1, no optdata */ 01019 return tcp_enqueue_flags(pcb, TCP_FIN); 01020 } 01021 01022 /** 01023 * Enqueue SYN or FIN for transmission. 01024 * 01025 * Called by @ref tcp_connect, tcp_listen_input, and @ref tcp_close 01026 * (via @ref tcp_send_fin) 01027 * 01028 * @param pcb Protocol control block for the TCP connection. 01029 * @param flags TCP header flags to set in the outgoing segment. 01030 */ 01031 err_t 01032 tcp_enqueue_flags(struct tcp_pcb *pcb, u8_t flags) 01033 { 01034 struct pbuf *p; 01035 struct tcp_seg *seg; 01036 u8_t optflags = 0; 01037 u8_t optlen = 0; 01038 01039 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue_flags: queuelen: %"U16_F"\n", (u16_t)pcb->snd_queuelen)); 01040 01041 LWIP_ASSERT("tcp_enqueue_flags: need either TCP_SYN or TCP_FIN in flags (programmer violates API)", 01042 (flags & (TCP_SYN | TCP_FIN)) != 0); 01043 LWIP_ASSERT("tcp_enqueue_flags: invalid pcb", pcb != NULL); 01044 01045 /* No need to check pcb->snd_queuelen if only SYN or FIN are allowed! */ 01046 01047 /* Get options for this segment. This is a special case since this is the 01048 only place where a SYN can be sent. */ 01049 if (flags & TCP_SYN) { 01050 optflags = TF_SEG_OPTS_MSS; 01051 #if LWIP_WND_SCALE 01052 if ((pcb->state != SYN_RCVD) || (pcb->flags & TF_WND_SCALE)) { 01053 /* In a <SYN,ACK> (sent in state SYN_RCVD), the window scale option may only 01054 be sent if we received a window scale option from the remote host. */ 01055 optflags |= TF_SEG_OPTS_WND_SCALE; 01056 } 01057 #endif /* LWIP_WND_SCALE */ 01058 #if LWIP_TCP_SACK_OUT 01059 if ((pcb->state != SYN_RCVD) || (pcb->flags & TF_SACK)) { 01060 /* In a <SYN,ACK> (sent in state SYN_RCVD), the SACK_PERM option may only 01061 be sent if we received a SACK_PERM option from the remote host. */ 01062 optflags |= TF_SEG_OPTS_SACK_PERM; 01063 } 01064 #endif /* LWIP_TCP_SACK_OUT */ 01065 } 01066 #if LWIP_TCP_TIMESTAMPS 01067 if ((pcb->flags & TF_TIMESTAMP) || ((flags & TCP_SYN) && (pcb->state != SYN_RCVD))) { 01068 /* Make sure the timestamp option is only included in data segments if we 01069 agreed about it with the remote host (and in active open SYN segments). */ 01070 optflags |= TF_SEG_OPTS_TS; 01071 } 01072 #endif /* LWIP_TCP_TIMESTAMPS */ 01073 optlen = LWIP_TCP_OPT_LENGTH_SEGMENT(optflags, pcb); 01074 01075 /* Allocate pbuf with room for TCP header + options */ 01076 if ((p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) { 01077 tcp_set_flags(pcb, TF_NAGLEMEMERR); 01078 TCP_STATS_INC(tcp.memerr); 01079 return ERR_MEM; 01080 } 01081 LWIP_ASSERT("tcp_enqueue_flags: check that first pbuf can hold optlen", 01082 (p->len >= optlen)); 01083 01084 /* Allocate memory for tcp_seg, and fill in fields. */ 01085 if ((seg = tcp_create_segment(pcb, p, flags, pcb->snd_lbb, optflags)) == NULL) { 01086 tcp_set_flags(pcb, TF_NAGLEMEMERR); 01087 TCP_STATS_INC(tcp.memerr); 01088 return ERR_MEM; 01089 } 01090 LWIP_ASSERT("seg->tcphdr not aligned", ((mem_ptr_t)seg->tcphdr % LWIP_MIN(MEM_ALIGNMENT, 4)) == 0); 01091 LWIP_ASSERT("tcp_enqueue_flags: invalid segment length", seg->len == 0); 01092 01093 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_TRACE, 01094 ("tcp_enqueue_flags: queueing %"U32_F":%"U32_F" (0x%"X16_F")\n", 01095 lwip_ntohl(seg->tcphdr->seqno), 01096 lwip_ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg), 01097 (u16_t)flags)); 01098 01099 /* Now append seg to pcb->unsent queue */ 01100 if (pcb->unsent == NULL) { 01101 pcb->unsent = seg; 01102 } else { 01103 struct tcp_seg *useg; 01104 for (useg = pcb->unsent; useg->next != NULL; useg = useg->next); 01105 useg->next = seg; 01106 } 01107 #if TCP_OVERSIZE 01108 /* The new unsent tail has no space */ 01109 pcb->unsent_oversize = 0; 01110 #endif /* TCP_OVERSIZE */ 01111 01112 /* SYN and FIN bump the sequence number */ 01113 if ((flags & TCP_SYN) || (flags & TCP_FIN)) { 01114 pcb->snd_lbb++; 01115 /* optlen does not influence snd_buf */ 01116 } 01117 if (flags & TCP_FIN) { 01118 tcp_set_flags(pcb, TF_FIN); 01119 } 01120 01121 /* update number of segments on the queues */ 01122 pcb->snd_queuelen += pbuf_clen(seg->p); 01123 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue_flags: %"S16_F" (after enqueued)\n", pcb->snd_queuelen)); 01124 if (pcb->snd_queuelen != 0) { 01125 LWIP_ASSERT("tcp_enqueue_flags: invalid queue length", 01126 pcb->unacked != NULL || pcb->unsent != NULL); 01127 } 01128 01129 return ERR_OK; 01130 } 01131 01132 #if LWIP_TCP_TIMESTAMPS 01133 /* Build a timestamp option (12 bytes long) at the specified options pointer) 01134 * 01135 * @param pcb tcp_pcb 01136 * @param opts option pointer where to store the timestamp option 01137 */ 01138 static void 01139 tcp_build_timestamp_option(const struct tcp_pcb *pcb, u32_t *opts) 01140 { 01141 LWIP_ASSERT("tcp_build_timestamp_option: invalid pcb", pcb != NULL); 01142 01143 /* Pad with two NOP options to make everything nicely aligned */ 01144 opts[0] = PP_HTONL(0x0101080A); 01145 opts[1] = lwip_htonl(sys_now()); 01146 opts[2] = lwip_htonl(pcb->ts_recent); 01147 } 01148 #endif 01149 01150 #if LWIP_TCP_SACK_OUT 01151 /** 01152 * Calculates the number of SACK entries that should be generated. 01153 * It takes into account whether TF_SACK flag is set, 01154 * the number of SACK entries in tcp_pcb that are valid, 01155 * as well as the available options size. 01156 * 01157 * @param pcb tcp_pcb 01158 * @param optlen the length of other TCP options (in bytes) 01159 * @return the number of SACK ranges that can be used 01160 */ 01161 static u8_t 01162 tcp_get_num_sacks(const struct tcp_pcb *pcb, u8_t optlen) 01163 { 01164 u8_t num_sacks = 0; 01165 01166 LWIP_ASSERT("tcp_get_num_sacks: invalid pcb", pcb != NULL); 01167 01168 if (pcb->flags & TF_SACK) { 01169 u8_t i; 01170 01171 /* The first SACK takes up 12 bytes (it includes SACK header and two NOP options), 01172 each additional one - 8 bytes. */ 01173 optlen += 12; 01174 01175 /* Max options size = 40, number of SACK array entries = LWIP_TCP_MAX_SACK_NUM */ 01176 for (i = 0; (i < LWIP_TCP_MAX_SACK_NUM) && (optlen <= TCP_MAX_OPTION_BYTES) && 01177 LWIP_TCP_SACK_VALID(pcb, i); ++i) { 01178 ++num_sacks; 01179 optlen += 8; 01180 } 01181 } 01182 01183 return num_sacks; 01184 } 01185 01186 /** Build a SACK option (12 or more bytes long) at the specified options pointer) 01187 * 01188 * @param pcb tcp_pcb 01189 * @param opts option pointer where to store the SACK option 01190 * @param num_sacks the number of SACKs to store 01191 */ 01192 static void 01193 tcp_build_sack_option(const struct tcp_pcb *pcb, u32_t *opts, u8_t num_sacks) 01194 { 01195 u8_t i; 01196 01197 LWIP_ASSERT("tcp_build_sack_option: invalid pcb", pcb != NULL); 01198 LWIP_ASSERT("tcp_build_sack_option: invalid opts", opts != NULL); 01199 01200 /* Pad with two NOP options to make everything nicely aligned. 01201 We add the length (of just the SACK option, not the NOPs in front of it), 01202 which is 2B of header, plus 8B for each SACK. */ 01203 *(opts++) = PP_HTONL(0x01010500 + 2 + num_sacks * 8); 01204 01205 for (i = 0; i < num_sacks; ++i) { 01206 *(opts++) = lwip_htonl(pcb->rcv_sacks[i].left); 01207 *(opts++) = lwip_htonl(pcb->rcv_sacks[i].right); 01208 } 01209 } 01210 01211 #endif 01212 01213 #if LWIP_WND_SCALE 01214 /** Build a window scale option (3 bytes long) at the specified options pointer) 01215 * 01216 * @param opts option pointer where to store the window scale option 01217 */ 01218 static void 01219 tcp_build_wnd_scale_option(u32_t *opts) 01220 { 01221 LWIP_ASSERT("tcp_build_wnd_scale_option: invalid opts", opts != NULL); 01222 01223 /* Pad with one NOP option to make everything nicely aligned */ 01224 opts[0] = PP_HTONL(0x01030300 | TCP_RCV_SCALE); 01225 } 01226 #endif 01227 01228 /** 01229 * @ingroup tcp_raw 01230 * Find out what we can send and send it 01231 * 01232 * @param pcb Protocol control block for the TCP connection to send data 01233 * @return ERR_OK if data has been sent or nothing to send 01234 * another err_t on error 01235 */ 01236 err_t 01237 tcp_output(struct tcp_pcb *pcb) 01238 { 01239 struct tcp_seg *seg, *useg; 01240 u32_t wnd, snd_nxt; 01241 err_t err; 01242 struct netif *netif; 01243 #if TCP_CWND_DEBUG 01244 s16_t i = 0; 01245 #endif /* TCP_CWND_DEBUG */ 01246 01247 LWIP_ASSERT_CORE_LOCKED(); 01248 01249 LWIP_ASSERT("tcp_output: invalid pcb", pcb != NULL); 01250 /* pcb->state LISTEN not allowed here */ 01251 LWIP_ASSERT("don't call tcp_output for listen-pcbs", 01252 pcb->state != LISTEN); 01253 01254 /* First, check if we are invoked by the TCP input processing 01255 code. If so, we do not output anything. Instead, we rely on the 01256 input processing code to call us when input processing is done 01257 with. */ 01258 if (tcp_input_pcb == pcb) { 01259 return ERR_OK; 01260 } 01261 01262 wnd = LWIP_MIN(pcb->snd_wnd, pcb->cwnd); 01263 01264 seg = pcb->unsent; 01265 01266 if (seg == NULL) { 01267 LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: nothing to send (%p)\n", 01268 (void *)pcb->unsent)); 01269 LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"TCPWNDSIZE_F 01270 ", cwnd %"TCPWNDSIZE_F", wnd %"U32_F 01271 ", seg == NULL, ack %"U32_F"\n", 01272 pcb->snd_wnd, pcb->cwnd, wnd, pcb->lastack)); 01273 01274 /* If the TF_ACK_NOW flag is set and the ->unsent queue is empty, construct 01275 * an empty ACK segment and send it. */ 01276 if (pcb->flags & TF_ACK_NOW) { 01277 return tcp_send_empty_ack(pcb); 01278 } 01279 /* nothing to send: shortcut out of here */ 01280 goto output_done; 01281 } else { 01282 LWIP_DEBUGF(TCP_CWND_DEBUG, 01283 ("tcp_output: snd_wnd %"TCPWNDSIZE_F", cwnd %"TCPWNDSIZE_F", wnd %"U32_F 01284 ", effwnd %"U32_F", seq %"U32_F", ack %"U32_F"\n", 01285 pcb->snd_wnd, pcb->cwnd, wnd, 01286 lwip_ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len, 01287 lwip_ntohl(seg->tcphdr->seqno), pcb->lastack)); 01288 } 01289 01290 netif = tcp_route(pcb, &pcb->local_ip, &pcb->remote_ip); 01291 if (netif == NULL) { 01292 return ERR_RTE; 01293 } 01294 01295 /* If we don't have a local IP address, we get one from netif */ 01296 if (ip_addr_isany(&pcb->local_ip)) { 01297 const ip_addr_t *local_ip = ip_netif_get_local_ip(netif, &pcb->remote_ip); 01298 if (local_ip == NULL) { 01299 return ERR_RTE; 01300 } 01301 ip_addr_copy(pcb->local_ip, *local_ip); 01302 } 01303 01304 /* Handle the current segment not fitting within the window */ 01305 if (lwip_ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len > wnd) { 01306 /* We need to start the persistent timer when the next unsent segment does not fit 01307 * within the remaining (could be 0) send window and RTO timer is not running (we 01308 * have no in-flight data). If window is still too small after persist timer fires, 01309 * then we split the segment. We don't consider the congestion window since a cwnd 01310 * smaller than 1 SMSS implies in-flight data 01311 */ 01312 if (wnd == pcb->snd_wnd && pcb->unacked == NULL && pcb->persist_backoff == 0) { 01313 pcb->persist_cnt = 0; 01314 pcb->persist_backoff = 1; 01315 pcb->persist_probe = 0; 01316 } 01317 /* We need an ACK, but can't send data now, so send an empty ACK */ 01318 if (pcb->flags & TF_ACK_NOW) { 01319 return tcp_send_empty_ack(pcb); 01320 } 01321 goto output_done; 01322 } 01323 /* Stop persist timer, above conditions are not active */ 01324 pcb->persist_backoff = 0; 01325 01326 /* useg should point to last segment on unacked queue */ 01327 useg = pcb->unacked; 01328 if (useg != NULL) { 01329 for (; useg->next != NULL; useg = useg->next); 01330 } 01331 /* data available and window allows it to be sent? */ 01332 while (seg != NULL && 01333 lwip_ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) { 01334 LWIP_ASSERT("RST not expected here!", 01335 (TCPH_FLAGS(seg->tcphdr) & TCP_RST) == 0); 01336 /* Stop sending if the nagle algorithm would prevent it 01337 * Don't stop: 01338 * - if tcp_write had a memory error before (prevent delayed ACK timeout) or 01339 * - if FIN was already enqueued for this PCB (SYN is always alone in a segment - 01340 * either seg->next != NULL or pcb->unacked == NULL; 01341 * RST is no sent using tcp_write/tcp_output. 01342 */ 01343 if ((tcp_do_output_nagle(pcb) == 0) && 01344 ((pcb->flags & (TF_NAGLEMEMERR | TF_FIN)) == 0)) { 01345 break; 01346 } 01347 #if TCP_CWND_DEBUG 01348 LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"TCPWNDSIZE_F", cwnd %"TCPWNDSIZE_F", wnd %"U32_F", effwnd %"U32_F", seq %"U32_F", ack %"U32_F", i %"S16_F"\n", 01349 pcb->snd_wnd, pcb->cwnd, wnd, 01350 lwip_ntohl(seg->tcphdr->seqno) + seg->len - 01351 pcb->lastack, 01352 lwip_ntohl(seg->tcphdr->seqno), pcb->lastack, i)); 01353 ++i; 01354 #endif /* TCP_CWND_DEBUG */ 01355 01356 if (pcb->state != SYN_SENT) { 01357 TCPH_SET_FLAG(seg->tcphdr, TCP_ACK); 01358 } 01359 01360 err = tcp_output_segment(seg, pcb, netif); 01361 if (err != ERR_OK) { 01362 /* segment could not be sent, for whatever reason */ 01363 tcp_set_flags(pcb, TF_NAGLEMEMERR); 01364 return err; 01365 } 01366 #if TCP_OVERSIZE_DBGCHECK 01367 seg->oversize_left = 0; 01368 #endif /* TCP_OVERSIZE_DBGCHECK */ 01369 pcb->unsent = seg->next; 01370 if (pcb->state != SYN_SENT) { 01371 tcp_clear_flags(pcb, TF_ACK_DELAY | TF_ACK_NOW); 01372 } 01373 snd_nxt = lwip_ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg); 01374 if (TCP_SEQ_LT(pcb->snd_nxt, snd_nxt)) { 01375 pcb->snd_nxt = snd_nxt; 01376 } 01377 /* put segment on unacknowledged list if length > 0 */ 01378 if (TCP_TCPLEN(seg) > 0) { 01379 seg->next = NULL; 01380 /* unacked list is empty? */ 01381 if (pcb->unacked == NULL) { 01382 pcb->unacked = seg; 01383 useg = seg; 01384 /* unacked list is not empty? */ 01385 } else { 01386 /* In the case of fast retransmit, the packet should not go to the tail 01387 * of the unacked queue, but rather somewhere before it. We need to check for 01388 * this case. -STJ Jul 27, 2004 */ 01389 if (TCP_SEQ_LT(lwip_ntohl(seg->tcphdr->seqno), lwip_ntohl(useg->tcphdr->seqno))) { 01390 /* add segment to before tail of unacked list, keeping the list sorted */ 01391 struct tcp_seg **cur_seg = &(pcb->unacked); 01392 while (*cur_seg && 01393 TCP_SEQ_LT(lwip_ntohl((*cur_seg)->tcphdr->seqno), lwip_ntohl(seg->tcphdr->seqno))) { 01394 cur_seg = &((*cur_seg)->next ); 01395 } 01396 seg->next = (*cur_seg); 01397 (*cur_seg) = seg; 01398 } else { 01399 /* add segment to tail of unacked list */ 01400 useg->next = seg; 01401 useg = useg->next; 01402 } 01403 } 01404 /* do not queue empty segments on the unacked list */ 01405 } else { 01406 tcp_seg_free(seg); 01407 } 01408 seg = pcb->unsent; 01409 } 01410 #if TCP_OVERSIZE 01411 if (pcb->unsent == NULL) { 01412 /* last unsent has been removed, reset unsent_oversize */ 01413 pcb->unsent_oversize = 0; 01414 } 01415 #endif /* TCP_OVERSIZE */ 01416 01417 output_done: 01418 tcp_clear_flags(pcb, TF_NAGLEMEMERR); 01419 return ERR_OK; 01420 } 01421 01422 /** Check if a segment's pbufs are used by someone else than TCP. 01423 * This can happen on retransmission if the pbuf of this segment is still 01424 * referenced by the netif driver due to deferred transmission. 01425 * This is the case (only!) if someone down the TX call path called 01426 * pbuf_ref() on one of the pbufs! 01427 * 01428 * @arg seg the tcp segment to check 01429 * @return 1 if ref != 1, 0 if ref == 1 01430 */ 01431 static int 01432 tcp_output_segment_busy(const struct tcp_seg *seg) 01433 { 01434 LWIP_ASSERT("tcp_output_segment_busy: invalid seg", seg != NULL); 01435 01436 /* We only need to check the first pbuf here: 01437 If a pbuf is queued for transmission, a driver calls pbuf_ref(), 01438 which only changes the ref count of the first pbuf */ 01439 if (seg->p->ref != 1) { 01440 /* other reference found */ 01441 return 1; 01442 } 01443 /* no other references found */ 01444 return 0; 01445 } 01446 01447 /** 01448 * Called by tcp_output() to actually send a TCP segment over IP. 01449 * 01450 * @param seg the tcp_seg to send 01451 * @param pcb the tcp_pcb for the TCP connection used to send the segment 01452 * @param netif the netif used to send the segment 01453 */ 01454 static err_t 01455 tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif) 01456 { 01457 err_t err; 01458 u16_t len; 01459 u32_t *opts; 01460 #if TCP_CHECKSUM_ON_COPY 01461 int seg_chksum_was_swapped = 0; 01462 #endif 01463 01464 LWIP_ASSERT("tcp_output_segment: invalid seg", seg != NULL); 01465 LWIP_ASSERT("tcp_output_segment: invalid pcb", pcb != NULL); 01466 LWIP_ASSERT("tcp_output_segment: invalid netif", netif != NULL); 01467 01468 if (tcp_output_segment_busy(seg)) { 01469 /* This should not happen: rexmit functions should have checked this. 01470 However, since this function modifies p->len, we must not continue in this case. */ 01471 LWIP_DEBUGF(TCP_RTO_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_output_segment: segment busy\n")); 01472 return ERR_OK; 01473 } 01474 01475 /* The TCP header has already been constructed, but the ackno and 01476 wnd fields remain. */ 01477 seg->tcphdr->ackno = lwip_htonl(pcb->rcv_nxt); 01478 01479 /* advertise our receive window size in this TCP segment */ 01480 #if LWIP_WND_SCALE 01481 if (seg->flags & TF_SEG_OPTS_WND_SCALE) { 01482 /* The Window field in a SYN segment itself (the only type where we send 01483 the window scale option) is never scaled. */ 01484 seg->tcphdr->wnd = lwip_htons(TCPWND_MIN16(pcb->rcv_ann_wnd)); 01485 } else 01486 #endif /* LWIP_WND_SCALE */ 01487 { 01488 seg->tcphdr->wnd = lwip_htons(TCPWND_MIN16(RCV_WND_SCALE(pcb, pcb->rcv_ann_wnd))); 01489 } 01490 01491 pcb->rcv_ann_right_edge = pcb->rcv_nxt + pcb->rcv_ann_wnd; 01492 01493 /* Add any requested options. NB MSS option is only set on SYN 01494 packets, so ignore it here */ 01495 /* cast through void* to get rid of alignment warnings */ 01496 opts = (u32_t *)(void *)(seg->tcphdr + 1); 01497 if (seg->flags & TF_SEG_OPTS_MSS) { 01498 u16_t mss; 01499 #if TCP_CALCULATE_EFF_SEND_MSS 01500 mss = tcp_eff_send_mss_netif(TCP_MSS, netif, &pcb->remote_ip); 01501 #else /* TCP_CALCULATE_EFF_SEND_MSS */ 01502 mss = TCP_MSS; 01503 #endif /* TCP_CALCULATE_EFF_SEND_MSS */ 01504 *opts = TCP_BUILD_MSS_OPTION(mss); 01505 opts += 1; 01506 } 01507 #if LWIP_TCP_TIMESTAMPS 01508 pcb->ts_lastacksent = pcb->rcv_nxt; 01509 01510 if (seg->flags & TF_SEG_OPTS_TS) { 01511 tcp_build_timestamp_option(pcb, opts); 01512 opts += 3; 01513 } 01514 #endif 01515 #if LWIP_WND_SCALE 01516 if (seg->flags & TF_SEG_OPTS_WND_SCALE) { 01517 tcp_build_wnd_scale_option(opts); 01518 opts += 1; 01519 } 01520 #endif 01521 #if LWIP_TCP_SACK_OUT 01522 if (seg->flags & TF_SEG_OPTS_SACK_PERM) { 01523 /* Pad with two NOP options to make everything nicely aligned 01524 * NOTE: When we send both timestamp and SACK_PERM options, 01525 * we could use the first two NOPs before the timestamp to store SACK_PERM option, 01526 * but that would complicate the code. 01527 */ 01528 *(opts++) = PP_HTONL(0x01010402); 01529 } 01530 #endif 01531 01532 /* Set retransmission timer running if it is not currently enabled 01533 This must be set before checking the route. */ 01534 if (pcb->rtime < 0) { 01535 pcb->rtime = 0; 01536 } 01537 01538 if (pcb->rttest == 0) { 01539 pcb->rttest = tcp_ticks; 01540 pcb->rtseq = lwip_ntohl(seg->tcphdr->seqno); 01541 01542 LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_output_segment: rtseq %"U32_F"\n", pcb->rtseq)); 01543 } 01544 LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output_segment: %"U32_F":%"U32_F"\n", 01545 lwip_htonl(seg->tcphdr->seqno), lwip_htonl(seg->tcphdr->seqno) + 01546 seg->len)); 01547 01548 len = (u16_t)((u8_t *)seg->tcphdr - (u8_t *)seg->p->payload); 01549 if (len == 0) { 01550 /** Exclude retransmitted segments from this count. */ 01551 MIB2_STATS_INC(mib2.tcpoutsegs); 01552 } 01553 01554 seg->p->len -= len; 01555 seg->p->tot_len -= len; 01556 01557 seg->p->payload = seg->tcphdr; 01558 01559 seg->tcphdr->chksum = 0; 01560 01561 #ifdef LWIP_HOOK_TCP_OUT_ADD_TCPOPTS 01562 opts = LWIP_HOOK_TCP_OUT_ADD_TCPOPTS(seg->p, seg->tcphdr, pcb, opts); 01563 #endif 01564 LWIP_ASSERT("options not filled", (u8_t *)opts == ((u8_t *)(seg->tcphdr + 1)) + LWIP_TCP_OPT_LENGTH_SEGMENT(seg->flags, pcb)); 01565 01566 #if CHECKSUM_GEN_TCP 01567 IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_TCP) { 01568 #if TCP_CHECKSUM_ON_COPY 01569 u32_t acc; 01570 #if TCP_CHECKSUM_ON_COPY_SANITY_CHECK 01571 u16_t chksum_slow = ip_chksum_pseudo(seg->p, IP_PROTO_TCP, 01572 seg->p->tot_len, &pcb->local_ip, &pcb->remote_ip); 01573 #endif /* TCP_CHECKSUM_ON_COPY_SANITY_CHECK */ 01574 if ((seg->flags & TF_SEG_DATA_CHECKSUMMED) == 0) { 01575 LWIP_ASSERT("data included but not checksummed", 01576 seg->p->tot_len == TCPH_HDRLEN_BYTES(seg->tcphdr)); 01577 } 01578 01579 /* rebuild TCP header checksum (TCP header changes for retransmissions!) */ 01580 acc = ip_chksum_pseudo_partial(seg->p, IP_PROTO_TCP, 01581 seg->p->tot_len, TCPH_HDRLEN_BYTES(seg->tcphdr), &pcb->local_ip, &pcb->remote_ip); 01582 /* add payload checksum */ 01583 if (seg->chksum_swapped) { 01584 seg_chksum_was_swapped = 1; 01585 seg->chksum = SWAP_BYTES_IN_WORD(seg->chksum); 01586 seg->chksum_swapped = 0; 01587 } 01588 acc = (u16_t)~acc + seg->chksum; 01589 seg->tcphdr->chksum = (u16_t)~FOLD_U32T(acc); 01590 #if TCP_CHECKSUM_ON_COPY_SANITY_CHECK 01591 if (chksum_slow != seg->tcphdr->chksum) { 01592 TCP_CHECKSUM_ON_COPY_SANITY_CHECK_FAIL( 01593 ("tcp_output_segment: calculated checksum is %"X16_F" instead of %"X16_F"\n", 01594 seg->tcphdr->chksum, chksum_slow)); 01595 seg->tcphdr->chksum = chksum_slow; 01596 } 01597 #endif /* TCP_CHECKSUM_ON_COPY_SANITY_CHECK */ 01598 #else /* TCP_CHECKSUM_ON_COPY */ 01599 seg->tcphdr->chksum = ip_chksum_pseudo(seg->p, IP_PROTO_TCP, 01600 seg->p->tot_len, &pcb->local_ip, &pcb->remote_ip); 01601 #endif /* TCP_CHECKSUM_ON_COPY */ 01602 } 01603 #endif /* CHECKSUM_GEN_TCP */ 01604 TCP_STATS_INC(tcp.xmit); 01605 01606 NETIF_SET_HINTS(netif, &(pcb->netif_hints)); 01607 err = ip_output_if(seg->p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 01608 pcb->tos, IP_PROTO_TCP, netif); 01609 NETIF_RESET_HINTS(netif); 01610 01611 #if TCP_CHECKSUM_ON_COPY 01612 if (seg_chksum_was_swapped) { 01613 /* if data is added to this segment later, chksum needs to be swapped, 01614 so restore this now */ 01615 seg->chksum = SWAP_BYTES_IN_WORD(seg->chksum); 01616 seg->chksum_swapped = 1; 01617 } 01618 #endif 01619 01620 return err; 01621 } 01622 01623 /** 01624 * Requeue all unacked segments for retransmission 01625 * 01626 * Called by tcp_slowtmr() for slow retransmission. 01627 * 01628 * @param pcb the tcp_pcb for which to re-enqueue all unacked segments 01629 */ 01630 err_t 01631 tcp_rexmit_rto_prepare(struct tcp_pcb *pcb) 01632 { 01633 struct tcp_seg *seg; 01634 01635 LWIP_ASSERT("tcp_rexmit_rto_prepare: invalid pcb", pcb != NULL); 01636 01637 if (pcb->unacked == NULL) { 01638 return ERR_VAL; 01639 } 01640 01641 /* Move all unacked segments to the head of the unsent queue. 01642 However, give up if any of the unsent pbufs are still referenced by the 01643 netif driver due to deferred transmission. No point loading the link further 01644 if it is struggling to flush its buffered writes. */ 01645 for (seg = pcb->unacked; seg->next != NULL; seg = seg->next) { 01646 if (tcp_output_segment_busy(seg)) { 01647 LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_rexmit_rto: segment busy\n")); 01648 return ERR_VAL; 01649 } 01650 } 01651 if (tcp_output_segment_busy(seg)) { 01652 LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_rexmit_rto: segment busy\n")); 01653 return ERR_VAL; 01654 } 01655 /* concatenate unsent queue after unacked queue */ 01656 seg->next = pcb->unsent; 01657 #if TCP_OVERSIZE_DBGCHECK 01658 /* if last unsent changed, we need to update unsent_oversize */ 01659 if (pcb->unsent == NULL) { 01660 pcb->unsent_oversize = seg->oversize_left; 01661 } 01662 #endif /* TCP_OVERSIZE_DBGCHECK */ 01663 /* unsent queue is the concatenated queue (of unacked, unsent) */ 01664 pcb->unsent = pcb->unacked; 01665 /* unacked queue is now empty */ 01666 pcb->unacked = NULL; 01667 01668 /* Mark RTO in-progress */ 01669 tcp_set_flags(pcb, TF_RTO); 01670 /* Record the next byte following retransmit */ 01671 pcb->rto_end = lwip_ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg); 01672 /* Don't take any RTT measurements after retransmitting. */ 01673 pcb->rttest = 0; 01674 01675 return ERR_OK; 01676 } 01677 01678 /** 01679 * Requeue all unacked segments for retransmission 01680 * 01681 * Called by tcp_slowtmr() for slow retransmission. 01682 * 01683 * @param pcb the tcp_pcb for which to re-enqueue all unacked segments 01684 */ 01685 void 01686 tcp_rexmit_rto_commit(struct tcp_pcb *pcb) 01687 { 01688 LWIP_ASSERT("tcp_rexmit_rto_commit: invalid pcb", pcb != NULL); 01689 01690 /* increment number of retransmissions */ 01691 if (pcb->nrtx < 0xFF) { 01692 ++pcb->nrtx; 01693 } 01694 /* Do the actual retransmission */ 01695 tcp_output(pcb); 01696 } 01697 01698 /** 01699 * Requeue all unacked segments for retransmission 01700 * 01701 * Called by tcp_process() only, tcp_slowtmr() needs to do some things between 01702 * "prepare" and "commit". 01703 * 01704 * @param pcb the tcp_pcb for which to re-enqueue all unacked segments 01705 */ 01706 void 01707 tcp_rexmit_rto(struct tcp_pcb *pcb) 01708 { 01709 LWIP_ASSERT("tcp_rexmit_rto: invalid pcb", pcb != NULL); 01710 01711 if (tcp_rexmit_rto_prepare(pcb) == ERR_OK) { 01712 tcp_rexmit_rto_commit(pcb); 01713 } 01714 } 01715 01716 /** 01717 * Requeue the first unacked segment for retransmission 01718 * 01719 * Called by tcp_receive() for fast retransmit. 01720 * 01721 * @param pcb the tcp_pcb for which to retransmit the first unacked segment 01722 */ 01723 err_t 01724 tcp_rexmit(struct tcp_pcb *pcb) 01725 { 01726 struct tcp_seg *seg; 01727 struct tcp_seg **cur_seg; 01728 01729 LWIP_ASSERT("tcp_rexmit: invalid pcb", pcb != NULL); 01730 01731 if (pcb->unacked == NULL) { 01732 return ERR_VAL; 01733 } 01734 01735 seg = pcb->unacked; 01736 01737 /* Give up if the segment is still referenced by the netif driver 01738 due to deferred transmission. */ 01739 if (tcp_output_segment_busy(seg)) { 01740 LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_rexmit busy\n")); 01741 return ERR_VAL; 01742 } 01743 01744 /* Move the first unacked segment to the unsent queue */ 01745 /* Keep the unsent queue sorted. */ 01746 pcb->unacked = seg->next; 01747 01748 cur_seg = &(pcb->unsent); 01749 while (*cur_seg && 01750 TCP_SEQ_LT(lwip_ntohl((*cur_seg)->tcphdr->seqno), lwip_ntohl(seg->tcphdr->seqno))) { 01751 cur_seg = &((*cur_seg)->next ); 01752 } 01753 seg->next = *cur_seg; 01754 *cur_seg = seg; 01755 #if TCP_OVERSIZE 01756 if (seg->next == NULL) { 01757 /* the retransmitted segment is last in unsent, so reset unsent_oversize */ 01758 pcb->unsent_oversize = 0; 01759 } 01760 #endif /* TCP_OVERSIZE */ 01761 01762 if (pcb->nrtx < 0xFF) { 01763 ++pcb->nrtx; 01764 } 01765 01766 /* Don't take any rtt measurements after retransmitting. */ 01767 pcb->rttest = 0; 01768 01769 /* Do the actual retransmission. */ 01770 MIB2_STATS_INC(mib2.tcpretranssegs); 01771 /* No need to call tcp_output: we are always called from tcp_input() 01772 and thus tcp_output directly returns. */ 01773 return ERR_OK; 01774 } 01775 01776 01777 /** 01778 * Handle retransmission after three dupacks received 01779 * 01780 * @param pcb the tcp_pcb for which to retransmit the first unacked segment 01781 */ 01782 void 01783 tcp_rexmit_fast(struct tcp_pcb *pcb) 01784 { 01785 LWIP_ASSERT("tcp_rexmit_fast: invalid pcb", pcb != NULL); 01786 01787 if (pcb->unacked != NULL && !(pcb->flags & TF_INFR)) { 01788 /* This is fast retransmit. Retransmit the first unacked segment. */ 01789 LWIP_DEBUGF(TCP_FR_DEBUG, 01790 ("tcp_receive: dupacks %"U16_F" (%"U32_F 01791 "), fast retransmit %"U32_F"\n", 01792 (u16_t)pcb->dupacks, pcb->lastack, 01793 lwip_ntohl(pcb->unacked->tcphdr->seqno))); 01794 if (tcp_rexmit(pcb) == ERR_OK) { 01795 /* Set ssthresh to half of the minimum of the current 01796 * cwnd and the advertised window */ 01797 pcb->ssthresh = LWIP_MIN(pcb->cwnd, pcb->snd_wnd) / 2; 01798 01799 /* The minimum value for ssthresh should be 2 MSS */ 01800 if (pcb->ssthresh < (2U * pcb->mss)) { 01801 LWIP_DEBUGF(TCP_FR_DEBUG, 01802 ("tcp_receive: The minimum value for ssthresh %"TCPWNDSIZE_F 01803 " should be min 2 mss %"U16_F"...\n", 01804 pcb->ssthresh, (u16_t)(2 * pcb->mss))); 01805 pcb->ssthresh = 2 * pcb->mss; 01806 } 01807 01808 pcb->cwnd = pcb->ssthresh + 3 * pcb->mss; 01809 tcp_set_flags(pcb, TF_INFR); 01810 01811 /* Reset the retransmission timer to prevent immediate rto retransmissions */ 01812 pcb->rtime = 0; 01813 } 01814 } 01815 } 01816 01817 static struct pbuf * 01818 tcp_output_alloc_header_common(u32_t ackno, u16_t optlen, u16_t datalen, 01819 u32_t seqno_be /* already in network byte order */, 01820 u16_t src_port, u16_t dst_port, u8_t flags, u16_t wnd) 01821 { 01822 struct tcp_hdr *tcphdr; 01823 struct pbuf *p; 01824 01825 p = pbuf_alloc(PBUF_IP, TCP_HLEN + optlen + datalen, PBUF_RAM); 01826 if (p != NULL) { 01827 LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr", 01828 (p->len >= TCP_HLEN + optlen)); 01829 tcphdr = (struct tcp_hdr *)p->payload; 01830 tcphdr->src = lwip_htons(src_port); 01831 tcphdr->dest = lwip_htons(dst_port); 01832 tcphdr->seqno = seqno_be; 01833 tcphdr->ackno = lwip_htonl(ackno); 01834 TCPH_HDRLEN_FLAGS_SET(tcphdr, (5 + optlen / 4), flags); 01835 tcphdr->wnd = lwip_htons(wnd); 01836 tcphdr->chksum = 0; 01837 tcphdr->urgp = 0; 01838 } 01839 return p; 01840 } 01841 01842 /** Allocate a pbuf and create a tcphdr at p->payload, used for output 01843 * functions other than the default tcp_output -> tcp_output_segment 01844 * (e.g. tcp_send_empty_ack, etc.) 01845 * 01846 * @param pcb tcp pcb for which to send a packet (used to initialize tcp_hdr) 01847 * @param optlen length of header-options 01848 * @param datalen length of tcp data to reserve in pbuf 01849 * @param seqno_be seqno in network byte order (big-endian) 01850 * @return pbuf with p->payload being the tcp_hdr 01851 */ 01852 static struct pbuf * 01853 tcp_output_alloc_header(struct tcp_pcb *pcb, u16_t optlen, u16_t datalen, 01854 u32_t seqno_be /* already in network byte order */) 01855 { 01856 struct pbuf *p; 01857 01858 LWIP_ASSERT("tcp_output_alloc_header: invalid pcb", pcb != NULL); 01859 01860 p = tcp_output_alloc_header_common(pcb->rcv_nxt, optlen, datalen, 01861 seqno_be, pcb->local_port, pcb->remote_port, TCP_ACK, 01862 TCPWND_MIN16(RCV_WND_SCALE(pcb, pcb->rcv_ann_wnd))); 01863 if (p != NULL) { 01864 /* If we're sending a packet, update the announced right window edge */ 01865 pcb->rcv_ann_right_edge = pcb->rcv_nxt + pcb->rcv_ann_wnd; 01866 } 01867 return p; 01868 } 01869 01870 /* Fill in options for control segments */ 01871 static void 01872 tcp_output_fill_options(const struct tcp_pcb *pcb, struct pbuf *p, u8_t optflags, u8_t num_sacks) 01873 { 01874 struct tcp_hdr *tcphdr; 01875 u32_t *opts; 01876 u16_t sacks_len = 0; 01877 01878 LWIP_ASSERT("tcp_output_fill_options: invalid pbuf", p != NULL); 01879 01880 tcphdr = (struct tcp_hdr *)p->payload; 01881 opts = (u32_t *)(void *)(tcphdr + 1); 01882 01883 /* NB. MSS and window scale options are only sent on SYNs, so ignore them here */ 01884 01885 #if LWIP_TCP_TIMESTAMPS 01886 if (optflags & TF_SEG_OPTS_TS) { 01887 tcp_build_timestamp_option(pcb, opts); 01888 opts += 3; 01889 } 01890 #endif 01891 01892 #if LWIP_TCP_SACK_OUT 01893 if (pcb && (num_sacks > 0)) { 01894 tcp_build_sack_option(pcb, opts, num_sacks); 01895 /* 1 word for SACKs header (including 2xNOP), and 2 words for each SACK */ 01896 sacks_len = 1 + num_sacks * 2; 01897 opts += sacks_len; 01898 } 01899 #else 01900 LWIP_UNUSED_ARG(num_sacks); 01901 #endif 01902 01903 #ifdef LWIP_HOOK_TCP_OUT_ADD_TCPOPTS 01904 opts = LWIP_HOOK_TCP_OUT_ADD_TCPOPTS(p, tcphdr, pcb, opts); 01905 #endif 01906 01907 LWIP_UNUSED_ARG(pcb); 01908 LWIP_UNUSED_ARG(sacks_len); 01909 LWIP_ASSERT("options not filled", (u8_t *)opts == ((u8_t *)(tcphdr + 1)) + sacks_len * 4 + LWIP_TCP_OPT_LENGTH_SEGMENT(optflags, pcb)); 01910 LWIP_UNUSED_ARG(optflags); /* for LWIP_NOASSERT */ 01911 LWIP_UNUSED_ARG(opts); /* for LWIP_NOASSERT */ 01912 } 01913 01914 /** Output a control segment pbuf to IP. 01915 * 01916 * Called from tcp_rst, tcp_send_empty_ack, tcp_keepalive and tcp_zero_window_probe, 01917 * this function combines selecting a netif for transmission, generating the tcp 01918 * header checksum and calling ip_output_if while handling netif hints and stats. 01919 */ 01920 static err_t 01921 tcp_output_control_segment(const struct tcp_pcb *pcb, struct pbuf *p, 01922 const ip_addr_t *src, const ip_addr_t *dst) 01923 { 01924 err_t err; 01925 struct netif *netif; 01926 01927 LWIP_ASSERT("tcp_output_control_segment: invalid pbuf", p != NULL); 01928 01929 netif = tcp_route(pcb, src, dst); 01930 if (netif == NULL) { 01931 err = ERR_RTE; 01932 } else { 01933 u8_t ttl, tos; 01934 #if CHECKSUM_GEN_TCP 01935 IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_TCP) { 01936 struct tcp_hdr *tcphdr = (struct tcp_hdr *)p->payload; 01937 tcphdr->chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len, 01938 src, dst); 01939 } 01940 #endif 01941 if (pcb != NULL) { 01942 NETIF_SET_HINTS(netif, LWIP_CONST_CAST(struct netif_hint*, &(pcb->netif_hints))); 01943 ttl = pcb->ttl; 01944 tos = pcb->tos; 01945 } else { 01946 /* Send output with hardcoded TTL/HL since we have no access to the pcb */ 01947 ttl = TCP_TTL; 01948 tos = 0; 01949 } 01950 TCP_STATS_INC(tcp.xmit); 01951 err = ip_output_if(p, src, dst, ttl, tos, IP_PROTO_TCP, netif); 01952 NETIF_RESET_HINTS(netif); 01953 } 01954 pbuf_free(p); 01955 return err; 01956 } 01957 01958 /** 01959 * Send a TCP RESET packet (empty segment with RST flag set) either to 01960 * abort a connection or to show that there is no matching local connection 01961 * for a received segment. 01962 * 01963 * Called by tcp_abort() (to abort a local connection), tcp_input() (if no 01964 * matching local pcb was found), tcp_listen_input() (if incoming segment 01965 * has ACK flag set) and tcp_process() (received segment in the wrong state) 01966 * 01967 * Since a RST segment is in most cases not sent for an active connection, 01968 * tcp_rst() has a number of arguments that are taken from a tcp_pcb for 01969 * most other segment output functions. 01970 * 01971 * @param pcb TCP pcb (may be NULL if no pcb is available) 01972 * @param seqno the sequence number to use for the outgoing segment 01973 * @param ackno the acknowledge number to use for the outgoing segment 01974 * @param local_ip the local IP address to send the segment from 01975 * @param remote_ip the remote IP address to send the segment to 01976 * @param local_port the local TCP port to send the segment from 01977 * @param remote_port the remote TCP port to send the segment to 01978 */ 01979 void 01980 tcp_rst(const struct tcp_pcb *pcb, u32_t seqno, u32_t ackno, 01981 const ip_addr_t *local_ip, const ip_addr_t *remote_ip, 01982 u16_t local_port, u16_t remote_port) 01983 { 01984 struct pbuf *p; 01985 u16_t wnd; 01986 u8_t optlen; 01987 01988 LWIP_ASSERT("tcp_rst: invalid local_ip", local_ip != NULL); 01989 LWIP_ASSERT("tcp_rst: invalid remote_ip", remote_ip != NULL); 01990 01991 optlen = LWIP_TCP_OPT_LENGTH_SEGMENT(0, pcb); 01992 01993 #if LWIP_WND_SCALE 01994 wnd = PP_HTONS(((TCP_WND >> TCP_RCV_SCALE) & 0xFFFF)); 01995 #else 01996 wnd = PP_HTONS(TCP_WND); 01997 #endif 01998 01999 p = tcp_output_alloc_header_common(ackno, optlen, 0, lwip_htonl(seqno), local_port, 02000 remote_port, TCP_RST | TCP_ACK, wnd); 02001 if (p == NULL) { 02002 LWIP_DEBUGF(TCP_DEBUG, ("tcp_rst: could not allocate memory for pbuf\n")); 02003 return; 02004 } 02005 tcp_output_fill_options(pcb, p, 0, optlen); 02006 02007 MIB2_STATS_INC(mib2.tcpoutrsts); 02008 02009 tcp_output_control_segment(pcb, p, local_ip, remote_ip); 02010 LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_rst: seqno %"U32_F" ackno %"U32_F".\n", seqno, ackno)); 02011 } 02012 02013 /** 02014 * Send an ACK without data. 02015 * 02016 * @param pcb Protocol control block for the TCP connection to send the ACK 02017 */ 02018 err_t 02019 tcp_send_empty_ack(struct tcp_pcb *pcb) 02020 { 02021 err_t err; 02022 struct pbuf *p; 02023 u8_t optlen, optflags = 0; 02024 u8_t num_sacks = 0; 02025 02026 LWIP_ASSERT("tcp_send_empty_ack: invalid pcb", pcb != NULL); 02027 02028 #if LWIP_TCP_TIMESTAMPS 02029 if (pcb->flags & TF_TIMESTAMP) { 02030 optflags = TF_SEG_OPTS_TS; 02031 } 02032 #endif 02033 optlen = LWIP_TCP_OPT_LENGTH_SEGMENT(optflags, pcb); 02034 02035 #if LWIP_TCP_SACK_OUT 02036 /* For now, SACKs are only sent with empty ACKs */ 02037 if ((num_sacks = tcp_get_num_sacks(pcb, optlen)) > 0) { 02038 optlen += 4 + num_sacks * 8; /* 4 bytes for header (including 2*NOP), plus 8B for each SACK */ 02039 } 02040 #endif 02041 02042 p = tcp_output_alloc_header(pcb, optlen, 0, lwip_htonl(pcb->snd_nxt)); 02043 if (p == NULL) { 02044 /* let tcp_fasttmr retry sending this ACK */ 02045 tcp_set_flags(pcb, TF_ACK_DELAY | TF_ACK_NOW); 02046 LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: (ACK) could not allocate pbuf\n")); 02047 return ERR_BUF; 02048 } 02049 tcp_output_fill_options(pcb, p, optflags, num_sacks); 02050 02051 #if LWIP_TCP_TIMESTAMPS 02052 pcb->ts_lastacksent = pcb->rcv_nxt; 02053 #endif 02054 02055 LWIP_DEBUGF(TCP_OUTPUT_DEBUG, 02056 ("tcp_output: sending ACK for %"U32_F"\n", pcb->rcv_nxt)); 02057 err = tcp_output_control_segment(pcb, p, &pcb->local_ip, &pcb->remote_ip); 02058 if (err != ERR_OK) { 02059 /* let tcp_fasttmr retry sending this ACK */ 02060 tcp_set_flags(pcb, TF_ACK_DELAY | TF_ACK_NOW); 02061 } else { 02062 /* remove ACK flags from the PCB, as we sent an empty ACK now */ 02063 tcp_clear_flags(pcb, TF_ACK_DELAY | TF_ACK_NOW); 02064 } 02065 02066 return err; 02067 } 02068 02069 /** 02070 * Send keepalive packets to keep a connection active although 02071 * no data is sent over it. 02072 * 02073 * Called by tcp_slowtmr() 02074 * 02075 * @param pcb the tcp_pcb for which to send a keepalive packet 02076 */ 02077 err_t 02078 tcp_keepalive(struct tcp_pcb *pcb) 02079 { 02080 err_t err; 02081 struct pbuf *p; 02082 u8_t optlen = LWIP_TCP_OPT_LENGTH_SEGMENT(0, pcb); 02083 02084 LWIP_ASSERT("tcp_keepalive: invalid pcb", pcb != NULL); 02085 02086 LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: sending KEEPALIVE probe to ")); 02087 ip_addr_debug_print_val(TCP_DEBUG, pcb->remote_ip); 02088 LWIP_DEBUGF(TCP_DEBUG, ("\n")); 02089 02090 LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: tcp_ticks %"U32_F" pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n", 02091 tcp_ticks, pcb->tmr, (u16_t)pcb->keep_cnt_sent)); 02092 02093 p = tcp_output_alloc_header(pcb, optlen, 0, lwip_htonl(pcb->snd_nxt - 1)); 02094 if (p == NULL) { 02095 LWIP_DEBUGF(TCP_DEBUG, 02096 ("tcp_keepalive: could not allocate memory for pbuf\n")); 02097 return ERR_MEM; 02098 } 02099 tcp_output_fill_options(pcb, p, 0, optlen); 02100 err = tcp_output_control_segment(pcb, p, &pcb->local_ip, &pcb->remote_ip); 02101 02102 LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: seqno %"U32_F" ackno %"U32_F" err %d.\n", 02103 pcb->snd_nxt - 1, pcb->rcv_nxt, (int)err)); 02104 return err; 02105 } 02106 02107 /** 02108 * Send persist timer zero-window probes to keep a connection active 02109 * when a window update is lost. 02110 * 02111 * Called by tcp_slowtmr() 02112 * 02113 * @param pcb the tcp_pcb for which to send a zero-window probe packet 02114 */ 02115 err_t 02116 tcp_zero_window_probe(struct tcp_pcb *pcb) 02117 { 02118 err_t err; 02119 struct pbuf *p; 02120 struct tcp_hdr *tcphdr; 02121 struct tcp_seg *seg; 02122 u16_t len; 02123 u8_t is_fin; 02124 u32_t snd_nxt; 02125 u8_t optlen = LWIP_TCP_OPT_LENGTH_SEGMENT(0, pcb); 02126 02127 LWIP_ASSERT("tcp_zero_window_probe: invalid pcb", pcb != NULL); 02128 02129 LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: sending ZERO WINDOW probe to ")); 02130 ip_addr_debug_print_val(TCP_DEBUG, pcb->remote_ip); 02131 LWIP_DEBUGF(TCP_DEBUG, ("\n")); 02132 02133 LWIP_DEBUGF(TCP_DEBUG, 02134 ("tcp_zero_window_probe: tcp_ticks %"U32_F 02135 " pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n", 02136 tcp_ticks, pcb->tmr, (u16_t)pcb->keep_cnt_sent)); 02137 02138 /* Only consider unsent, persist timer should be off when there is data in-flight */ 02139 seg = pcb->unsent; 02140 if (seg == NULL) { 02141 /* Not expected, persist timer should be off when the send buffer is empty */ 02142 return ERR_OK; 02143 } 02144 02145 /* increment probe count. NOTE: we record probe even if it fails 02146 to actually transmit due to an error. This ensures memory exhaustion/ 02147 routing problem doesn't leave a zero-window pcb as an indefinite zombie. 02148 RTO mechanism has similar behavior, see pcb->nrtx */ 02149 if (pcb->persist_probe < 0xFF) { 02150 ++pcb->persist_probe; 02151 } 02152 02153 is_fin = ((TCPH_FLAGS(seg->tcphdr) & TCP_FIN) != 0) && (seg->len == 0); 02154 /* we want to send one seqno: either FIN or data (no options) */ 02155 len = is_fin ? 0 : 1; 02156 02157 p = tcp_output_alloc_header(pcb, optlen, len, seg->tcphdr->seqno); 02158 if (p == NULL) { 02159 LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: no memory for pbuf\n")); 02160 return ERR_MEM; 02161 } 02162 tcphdr = (struct tcp_hdr *)p->payload; 02163 02164 if (is_fin) { 02165 /* FIN segment, no data */ 02166 TCPH_FLAGS_SET(tcphdr, TCP_ACK | TCP_FIN); 02167 } else { 02168 /* Data segment, copy in one byte from the head of the unacked queue */ 02169 char *d = ((char *)p->payload + TCP_HLEN); 02170 /* Depending on whether the segment has already been sent (unacked) or not 02171 (unsent), seg->p->payload points to the IP header or TCP header. 02172 Ensure we copy the first TCP data byte: */ 02173 pbuf_copy_partial(seg->p, d, 1, seg->p->tot_len - seg->len); 02174 } 02175 02176 /* The byte may be acknowledged without the window being opened. */ 02177 snd_nxt = lwip_ntohl(seg->tcphdr->seqno) + 1; 02178 if (TCP_SEQ_LT(pcb->snd_nxt, snd_nxt)) { 02179 pcb->snd_nxt = snd_nxt; 02180 } 02181 tcp_output_fill_options(pcb, p, 0, optlen); 02182 02183 err = tcp_output_control_segment(pcb, p, &pcb->local_ip, &pcb->remote_ip); 02184 02185 LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: seqno %"U32_F 02186 " ackno %"U32_F" err %d.\n", 02187 pcb->snd_nxt - 1, pcb->rcv_nxt, (int)err)); 02188 return err; 02189 } 02190 #endif /* LWIP_TCP */
Generated on Tue Jul 12 2022 13:54:30 by
