3 * Transmission Control Protocol, outgoing traffic
5 * The output functions of TCP.
10 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
11 * All rights reserved.
13 * Redistribution and use in source and binary forms, with or without modification,
14 * are permitted provided that the following conditions are met:
16 * 1. Redistributions of source code must retain the above copyright notice,
17 * this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright notice,
19 * this list of conditions and the following disclaimer in the documentation
20 * and/or other materials provided with the distribution.
21 * 3. The name of the author may not be used to endorse or promote products
22 * derived from this software without specific prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
25 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
26 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
27 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
29 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
32 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
35 * This file is part of the lwIP TCP/IP stack.
37 * Author: Adam Dunkels <adam@sics.se>
43 #if LWIP_TCP /* don't build if not configured for use in lwipopts.h */
45 #include "lwip/tcp_impl.h"
48 #include "lwip/memp.h"
49 #include "lwip/ip_addr.h"
50 #include "lwip/netif.h"
51 #include "lwip/inet_chksum.h"
52 #include "lwip/stats.h"
53 #include "lwip/snmp.h"
55 #include "lwip/ip6_addr.h"
56 #include "lwip/inet_chksum.h"
57 #if LWIP_TCP_TIMESTAMPS
63 /* Define some copy-macros for checksum-on-copy so that the code looks
64 nicer by preventing too many ifdef's. */
65 #if TCP_CHECKSUM_ON_COPY
66 #define TCP_DATA_COPY(dst, src, len, seg) do { \
67 tcp_seg_add_chksum(LWIP_CHKSUM_COPY(dst, src, len), \
68 len, &seg->chksum, &seg->chksum_swapped); \
69 seg->flags |= TF_SEG_DATA_CHECKSUMMED; } while(0)
70 #define TCP_DATA_COPY2(dst, src, len, chksum, chksum_swapped) \
71 tcp_seg_add_chksum(LWIP_CHKSUM_COPY(dst, src, len), len, chksum, chksum_swapped);
72 #else /* TCP_CHECKSUM_ON_COPY*/
73 #define TCP_DATA_COPY(dst, src, len, seg) MEMCPY(dst, src, len)
74 #define TCP_DATA_COPY2(dst, src, len, chksum, chksum_swapped) MEMCPY(dst, src, len)
75 #endif /* TCP_CHECKSUM_ON_COPY*/
77 /** Define this to 1 for an extra check that the output checksum is valid
78 * (usefule when the checksum is generated by the application, not the stack) */
79 #ifndef TCP_CHECKSUM_ON_COPY_SANITY_CHECK
80 #define TCP_CHECKSUM_ON_COPY_SANITY_CHECK 0
83 /* Forward declarations.*/
84 static void tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb);
86 /** Allocate a pbuf and create a tcphdr at p->payload, used for output
87 * functions other than the default tcp_output -> tcp_output_segment
88 * (e.g. tcp_send_empty_ack, etc.)
90 * @param pcb tcp pcb for which to send a packet (used to initialize tcp_hdr)
91 * @param optlen length of header-options
92 * @param datalen length of tcp data to reserve in pbuf
93 * @param seqno_be seqno in network byte order (big-endian)
94 * @return pbuf with p->payload being the tcp_hdr
97 tcp_output_alloc_header(struct tcp_pcb *pcb, u16_t optlen, u16_t datalen,
98 u32_t seqno_be /* already in network byte order */)
100 struct tcp_hdr *tcphdr;
101 struct pbuf *p = pbuf_alloc(PBUF_IP, TCP_HLEN + optlen + datalen, PBUF_RAM);
103 LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr",
104 (p->len >= TCP_HLEN + optlen));
105 tcphdr = (struct tcp_hdr *)p->payload;
106 tcphdr->src = htons(pcb->local_port);
107 tcphdr->dest = htons(pcb->remote_port);
108 tcphdr->seqno = seqno_be;
109 tcphdr->ackno = htonl(pcb->rcv_nxt);
110 TCPH_HDRLEN_FLAGS_SET(tcphdr, (5 + optlen / 4), TCP_ACK);
111 tcphdr->wnd = htons(pcb->rcv_ann_wnd);
115 /* If we're sending a packet, update the announced right window edge */
116 pcb->rcv_ann_right_edge = pcb->rcv_nxt + pcb->rcv_ann_wnd;
122 * Called by tcp_close() to send a segment including FIN flag but not data.
124 * @param pcb the tcp_pcb over which to send a segment
125 * @return ERR_OK if sent, another err_t otherwise
128 tcp_send_fin(struct tcp_pcb *pcb)
130 /* first, try to add the fin to the last unsent segment */
131 if (pcb->unsent != NULL) {
132 struct tcp_seg *last_unsent;
133 for (last_unsent = pcb->unsent; last_unsent->next != NULL;
134 last_unsent = last_unsent->next);
136 if ((TCPH_FLAGS(last_unsent->tcphdr) & (TCP_SYN | TCP_FIN | TCP_RST)) == 0) {
137 /* no SYN/FIN/RST flag in the header, we can add the FIN flag */
138 TCPH_SET_FLAG(last_unsent->tcphdr, TCP_FIN);
139 pcb->flags |= TF_FIN;
143 /* no data, no length, flags, copy=1, no optdata */
144 return tcp_enqueue_flags(pcb, TCP_FIN);
148 * Create a TCP segment with prefilled header.
150 * Called by tcp_write and tcp_enqueue_flags.
152 * @param pcb Protocol control block for the TCP connection.
153 * @param p pbuf that is used to hold the TCP header.
154 * @param flags TCP flags for header.
155 * @param seqno TCP sequence number of this packet
156 * @param optflags options to include in TCP header
157 * @return a new tcp_seg pointing to p, or NULL.
158 * The TCP header is filled in except ackno and wnd.
159 * p is freed on failure.
161 static struct tcp_seg *
162 tcp_create_segment(struct tcp_pcb *pcb, struct pbuf *p, u8_t flags, u32_t seqno, u8_t optflags)
165 u8_t optlen = LWIP_TCP_OPT_LENGTH(optflags);
167 if ((seg = (struct tcp_seg *)memp_malloc(MEMP_TCP_SEG)) == NULL) {
168 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_create_segment: no memory.\n"));
172 seg->flags = optflags;
175 seg->len = p->tot_len - optlen;
176 #if TCP_OVERSIZE_DBGCHECK
177 seg->oversize_left = 0;
178 #endif /* TCP_OVERSIZE_DBGCHECK */
179 #if TCP_CHECKSUM_ON_COPY
181 seg->chksum_swapped = 0;
183 LWIP_ASSERT("invalid optflags passed: TF_SEG_DATA_CHECKSUMMED",
184 (optflags & TF_SEG_DATA_CHECKSUMMED) == 0);
185 #endif /* TCP_CHECKSUM_ON_COPY */
187 /* build TCP header */
188 if (pbuf_header(p, TCP_HLEN)) {
189 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_create_segment: no room for TCP header in pbuf.\n"));
190 TCP_STATS_INC(tcp.err);
194 seg->tcphdr = (struct tcp_hdr *)seg->p->payload;
195 seg->tcphdr->src = htons(pcb->local_port);
196 seg->tcphdr->dest = htons(pcb->remote_port);
197 seg->tcphdr->seqno = htonl(seqno);
198 /* ackno is set in tcp_output */
199 TCPH_HDRLEN_FLAGS_SET(seg->tcphdr, (5 + optlen / 4), flags);
200 /* wnd and chksum are set in tcp_output */
201 seg->tcphdr->urgp = 0;
206 * Allocate a PBUF_RAM pbuf, perhaps with extra space at the end.
208 * This function is like pbuf_alloc(layer, length, PBUF_RAM) except
209 * there may be extra bytes available at the end.
211 * @param layer flag to define header size.
212 * @param length size of the pbuf's payload.
213 * @param max_length maximum usable size of payload+oversize.
214 * @param oversize pointer to a u16_t that will receive the number of usable tail bytes.
215 * @param pcb The TCP connection that willo enqueue the pbuf.
216 * @param apiflags API flags given to tcp_write.
217 * @param first_seg true when this pbuf will be used in the first enqueued segment.
222 tcp_pbuf_prealloc(pbuf_layer layer, u16_t length, u16_t max_length,
223 u16_t *oversize, struct tcp_pcb *pcb, u8_t apiflags,
227 u16_t alloc = length;
229 #if LWIP_NETIF_TX_SINGLE_PBUF
230 LWIP_UNUSED_ARG(max_length);
231 LWIP_UNUSED_ARG(pcb);
232 LWIP_UNUSED_ARG(apiflags);
233 LWIP_UNUSED_ARG(first_seg);
234 /* always create MSS-sized pbufs */
236 #else /* LWIP_NETIF_TX_SINGLE_PBUF */
237 if (length < max_length) {
238 /* Should we allocate an oversized pbuf, or just the minimum
239 * length required? If tcp_write is going to be called again
240 * before this segment is transmitted, we want the oversized
241 * buffer. If the segment will be transmitted immediately, we can
242 * save memory by allocating only length. We use a simple
243 * heuristic based on the following information:
245 * Did the user set TCP_WRITE_FLAG_MORE?
247 * Will the Nagle algorithm defer transmission of this segment?
249 if ((apiflags & TCP_WRITE_FLAG_MORE) ||
250 (!(pcb->flags & TF_NODELAY) &&
252 pcb->unsent != NULL ||
253 pcb->unacked != NULL))) {
254 alloc = LWIP_MIN(max_length, LWIP_MEM_ALIGN_SIZE(length + TCP_OVERSIZE));
257 #endif /* LWIP_NETIF_TX_SINGLE_PBUF */
258 p = pbuf_alloc(layer, alloc, PBUF_RAM);
262 LWIP_ASSERT("need unchained pbuf", p->next == NULL);
263 *oversize = p->len - length;
264 /* trim p->len to the currently used size */
265 p->len = p->tot_len = length;
268 #else /* TCP_OVERSIZE */
269 #define tcp_pbuf_prealloc(layer, length, mx, os, pcb, api, fst) pbuf_alloc((layer), (length), PBUF_RAM)
270 #endif /* TCP_OVERSIZE */
272 #if TCP_CHECKSUM_ON_COPY
273 /** Add a checksum of newly added data to the segment */
275 tcp_seg_add_chksum(u16_t chksum, u16_t len, u16_t *seg_chksum,
276 u8_t *seg_chksum_swapped)
279 /* add chksum to old chksum and fold to u16_t */
280 helper = chksum + *seg_chksum;
281 chksum = FOLD_U32T(helper);
282 if ((len & 1) != 0) {
283 *seg_chksum_swapped = 1 - *seg_chksum_swapped;
284 chksum = SWAP_BYTES_IN_WORD(chksum);
286 *seg_chksum = chksum;
288 #endif /* TCP_CHECKSUM_ON_COPY */
290 /** Checks if tcp_write is allowed or not (checks state, snd_buf and snd_queuelen).
292 * @param pcb the tcp pcb to check for
293 * @param len length of data to send (checked agains snd_buf)
294 * @return ERR_OK if tcp_write is allowed to proceed, another err_t otherwise
297 tcp_write_checks(struct tcp_pcb *pcb, u16_t len)
299 /* connection is in invalid state for data transmission? */
300 if ((pcb->state != ESTABLISHED) &&
301 (pcb->state != CLOSE_WAIT) &&
302 (pcb->state != SYN_SENT) &&
303 (pcb->state != SYN_RCVD)) {
304 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_STATE | LWIP_DBG_LEVEL_SEVERE, ("tcp_write() called in invalid state\n"));
306 } else if (len == 0) {
310 /* fail on too much data */
311 if (len > pcb->snd_buf) {
312 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_write: too much data (len=%"U16_F" > snd_buf=%"U16_F")\n",
314 pcb->flags |= TF_NAGLEMEMERR;
318 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_write: queuelen: %"U16_F"\n", (u16_t)pcb->snd_queuelen));
320 /* If total number of pbufs on the unsent/unacked queues exceeds the
321 * configured maximum, return an error */
322 /* check for configured max queuelen and possible overflow */
323 if ((pcb->snd_queuelen >= TCP_SND_QUEUELEN) || (pcb->snd_queuelen > TCP_SNDQUEUELEN_OVERFLOW)) {
324 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_write: too long queue %"U16_F" (max %"U16_F")\n",
325 pcb->snd_queuelen, TCP_SND_QUEUELEN));
326 TCP_STATS_INC(tcp.memerr);
327 pcb->flags |= TF_NAGLEMEMERR;
330 if (pcb->snd_queuelen != 0) {
331 LWIP_ASSERT("tcp_write: pbufs on queue => at least one queue non-empty",
332 pcb->unacked != NULL || pcb->unsent != NULL);
334 LWIP_ASSERT("tcp_write: no pbufs on queue => both queues empty",
335 pcb->unacked == NULL && pcb->unsent == NULL);
341 * Write data for sending (but does not send it immediately).
343 * It waits in the expectation of more data being sent soon (as
344 * it can send them more efficiently by combining them together).
345 * To prompt the system to send data now, call tcp_output() after
346 * calling tcp_write().
348 * @param pcb Protocol control block for the TCP connection to enqueue data for.
349 * @param arg Pointer to the data to be enqueued for sending.
350 * @param len Data length in bytes
351 * @param apiflags combination of following flags :
352 * - TCP_WRITE_FLAG_COPY (0x01) data will be copied into memory belonging to the stack
353 * - TCP_WRITE_FLAG_MORE (0x02) for TCP connection, PSH flag will be set on last segment sent,
354 * @return ERR_OK if enqueued, another err_t on error
357 tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags)
359 struct pbuf *concat_p = NULL;
360 struct tcp_seg *last_unsent = NULL, *seg = NULL, *prev_seg = NULL, *queue = NULL;
361 u16_t pos = 0; /* position in 'arg' data */
367 u16_t oversize_used = 0;
368 #endif /* TCP_OVERSIZE */
369 #if TCP_CHECKSUM_ON_COPY
370 u16_t concat_chksum = 0;
371 u8_t concat_chksum_swapped = 0;
372 u16_t concat_chksummed = 0;
373 #endif /* TCP_CHECKSUM_ON_COPY */
375 /* don't allocate segments bigger than half the maximum window we ever received */
376 u16_t mss_local = LWIP_MIN(pcb->mss, pcb->snd_wnd_max/2);
378 #if LWIP_NETIF_TX_SINGLE_PBUF
379 /* Always copy to try to create single pbufs for TX */
380 apiflags |= TCP_WRITE_FLAG_COPY;
381 #endif /* LWIP_NETIF_TX_SINGLE_PBUF */
383 LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_write(pcb=%p, data=%p, len=%"U16_F", apiflags=%"U16_F")\n",
384 (void *)pcb, arg, len, (u16_t)apiflags));
385 LWIP_ERROR("tcp_write: arg == NULL (programmer violates API)",
386 arg != NULL, return ERR_ARG;);
388 err = tcp_write_checks(pcb, len);
392 queuelen = pcb->snd_queuelen;
394 #if LWIP_TCP_TIMESTAMPS
395 if ((pcb->flags & TF_TIMESTAMP)) {
396 optflags = TF_SEG_OPTS_TS;
397 optlen = LWIP_TCP_OPT_LENGTH(TF_SEG_OPTS_TS);
399 #endif /* LWIP_TCP_TIMESTAMPS */
403 * TCP segmentation is done in three phases with increasing complexity:
405 * 1. Copy data directly into an oversized pbuf.
406 * 2. Chain a new pbuf to the end of pcb->unsent.
407 * 3. Create new segments.
409 * We may run out of memory at any point. In that case we must
410 * return ERR_MEM and not change anything in pcb. Therefore, all
411 * changes are recorded in local variables and committed at the end
412 * of the function. Some pcb fields are maintained in local copies:
414 * queuelen = pcb->snd_queuelen
415 * oversize = pcb->unsent_oversize
417 * These variables are set consistently by the phases:
419 * seg points to the last segment tampered with.
421 * pos records progress as data is segmented.
424 /* Find the tail of the unsent queue. */
425 if (pcb->unsent != NULL) {
429 /* @todo: this could be sped up by keeping last_unsent in the pcb */
430 for (last_unsent = pcb->unsent; last_unsent->next != NULL;
431 last_unsent = last_unsent->next);
433 /* Usable space at the end of the last unsent segment */
434 unsent_optlen = LWIP_TCP_OPT_LENGTH(last_unsent->flags);
435 space = mss_local - (last_unsent->len + unsent_optlen);
438 * Phase 1: Copy data directly into an oversized pbuf.
440 * The number of bytes copied is recorded in the oversize_used
441 * variable. The actual copying is done at the bottom of the
445 #if TCP_OVERSIZE_DBGCHECK
446 /* check that pcb->unsent_oversize matches last_unsent->unsent_oversize */
447 LWIP_ASSERT("unsent_oversize mismatch (pcb vs. last_unsent)",
448 pcb->unsent_oversize == last_unsent->oversize_left);
449 #endif /* TCP_OVERSIZE_DBGCHECK */
450 oversize = pcb->unsent_oversize;
452 LWIP_ASSERT("inconsistent oversize vs. space", oversize_used <= space);
454 oversize_used = oversize < len ? oversize : len;
455 pos += oversize_used;
456 oversize -= oversize_used;
457 space -= oversize_used;
459 /* now we are either finished or oversize is zero */
460 LWIP_ASSERT("inconsistend oversize vs. len", (oversize == 0) || (pos == len));
461 #endif /* TCP_OVERSIZE */
464 * Phase 2: Chain a new pbuf to the end of pcb->unsent.
466 * We don't extend segments containing SYN/FIN flags or options
467 * (len==0). The new pbuf is kept in concat_p and pbuf_cat'ed at
470 if ((pos < len) && (space > 0) && (last_unsent->len > 0)) {
471 u16_t seglen = space < len - pos ? space : len - pos;
474 /* Create a pbuf with a copy or reference to seglen bytes. We
475 * can use PBUF_RAW here since the data appears in the middle of
476 * a segment. A header will never be prepended. */
477 if (apiflags & TCP_WRITE_FLAG_COPY) {
479 if ((concat_p = tcp_pbuf_prealloc(PBUF_RAW, seglen, space, &oversize, pcb, apiflags, 1)) == NULL) {
480 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2,
481 ("tcp_write : could not allocate memory for pbuf copy size %"U16_F"\n",
485 #if TCP_OVERSIZE_DBGCHECK
486 last_unsent->oversize_left = oversize;
487 #endif /* TCP_OVERSIZE_DBGCHECK */
488 TCP_DATA_COPY2(concat_p->payload, (u8_t*)arg + pos, seglen, &concat_chksum, &concat_chksum_swapped);
489 #if TCP_CHECKSUM_ON_COPY
490 concat_chksummed += seglen;
491 #endif /* TCP_CHECKSUM_ON_COPY */
493 /* Data is not copied */
494 if ((concat_p = pbuf_alloc(PBUF_RAW, seglen, PBUF_ROM)) == NULL) {
495 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2,
496 ("tcp_write: could not allocate memory for zero-copy pbuf\n"));
499 #if TCP_CHECKSUM_ON_COPY
500 /* calculate the checksum of nocopy-data */
501 tcp_seg_add_chksum(~inet_chksum((u8_t*)arg + pos, seglen), seglen,
502 &concat_chksum, &concat_chksum_swapped);
503 concat_chksummed += seglen;
504 #endif /* TCP_CHECKSUM_ON_COPY */
505 /* reference the non-volatile payload data */
506 concat_p->payload = (u8_t*)arg + pos;
510 queuelen += pbuf_clen(concat_p);
514 LWIP_ASSERT("unsent_oversize mismatch (pcb->unsent is NULL)",
515 pcb->unsent_oversize == 0);
516 #endif /* TCP_OVERSIZE */
520 * Phase 3: Create new segments.
522 * The new segments are chained together in the local 'queue'
523 * variable, ready to be appended to pcb->unsent.
527 u16_t left = len - pos;
528 u16_t max_len = mss_local - optlen;
529 u16_t seglen = left > max_len ? max_len : left;
530 #if TCP_CHECKSUM_ON_COPY
532 u8_t chksum_swapped = 0;
533 #endif /* TCP_CHECKSUM_ON_COPY */
535 if (apiflags & TCP_WRITE_FLAG_COPY) {
536 /* If copy is set, memory should be allocated and data copied
538 if ((p = tcp_pbuf_prealloc(PBUF_TRANSPORT, seglen + optlen, mss_local, &oversize, pcb, apiflags, queue == NULL)) == NULL) {
539 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_write : could not allocate memory for pbuf copy size %"U16_F"\n", seglen));
542 LWIP_ASSERT("tcp_write: check that first pbuf can hold the complete seglen",
544 TCP_DATA_COPY2((char *)p->payload + optlen, (u8_t*)arg + pos, seglen, &chksum, &chksum_swapped);
546 /* Copy is not set: First allocate a pbuf for holding the data.
547 * Since the referenced data is available at least until it is
548 * sent out on the link (as it has to be ACKed by the remote
549 * party) we can safely use PBUF_ROM instead of PBUF_REF here.
553 LWIP_ASSERT("oversize == 0", oversize == 0);
554 #endif /* TCP_OVERSIZE */
555 if ((p2 = pbuf_alloc(PBUF_TRANSPORT, seglen, PBUF_ROM)) == NULL) {
556 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_write: could not allocate memory for zero-copy pbuf\n"));
559 #if TCP_CHECKSUM_ON_COPY
560 /* calculate the checksum of nocopy-data */
561 chksum = ~inet_chksum((u8_t*)arg + pos, seglen);
562 #endif /* TCP_CHECKSUM_ON_COPY */
563 /* reference the non-volatile payload data */
564 p2->payload = (u8_t*)arg + pos;
566 /* Second, allocate a pbuf for the headers. */
567 if ((p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) {
568 /* If allocation fails, we have to deallocate the data pbuf as
571 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_write: could not allocate memory for header pbuf\n"));
574 /* Concatenate the headers and data pbufs together. */
575 pbuf_cat(p/*header*/, p2/*data*/);
578 queuelen += pbuf_clen(p);
580 /* Now that there are more segments queued, we check again if the
581 * length of the queue exceeds the configured maximum or
583 if ((queuelen > TCP_SND_QUEUELEN) || (queuelen > TCP_SNDQUEUELEN_OVERFLOW)) {
584 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_write: queue too long %"U16_F" (%"U16_F")\n", queuelen, TCP_SND_QUEUELEN));
589 if ((seg = tcp_create_segment(pcb, p, 0, pcb->snd_lbb + pos, optflags)) == NULL) {
592 #if TCP_OVERSIZE_DBGCHECK
593 seg->oversize_left = oversize;
594 #endif /* TCP_OVERSIZE_DBGCHECK */
595 #if TCP_CHECKSUM_ON_COPY
596 seg->chksum = chksum;
597 seg->chksum_swapped = chksum_swapped;
598 seg->flags |= TF_SEG_DATA_CHECKSUMMED;
599 #endif /* TCP_CHECKSUM_ON_COPY */
601 /* first segment of to-be-queued data? */
605 /* Attach the segment to the end of the queued segments */
606 LWIP_ASSERT("prev_seg != NULL", prev_seg != NULL);
607 prev_seg->next = seg;
609 /* remember last segment of to-be-queued data for next iteration */
612 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_TRACE, ("tcp_write: queueing %"U32_F":%"U32_F"\n",
613 ntohl(seg->tcphdr->seqno),
614 ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg)));
620 * All three segmentation phases were successful. We can commit the
625 * Phase 1: If data has been added to the preallocated tail of
626 * last_unsent, we update the length fields of the pbuf chain.
629 if (oversize_used > 0) {
631 /* Bump tot_len of whole chain, len of tail */
632 for (p = last_unsent->p; p; p = p->next) {
633 p->tot_len += oversize_used;
634 if (p->next == NULL) {
635 TCP_DATA_COPY((char *)p->payload + p->len, arg, oversize_used, last_unsent);
636 p->len += oversize_used;
639 last_unsent->len += oversize_used;
640 #if TCP_OVERSIZE_DBGCHECK
641 last_unsent->oversize_left -= oversize_used;
642 #endif /* TCP_OVERSIZE_DBGCHECK */
644 pcb->unsent_oversize = oversize;
645 #endif /* TCP_OVERSIZE */
648 * Phase 2: concat_p can be concatenated onto last_unsent->p
650 if (concat_p != NULL) {
651 LWIP_ASSERT("tcp_write: cannot concatenate when pcb->unsent is empty",
652 (last_unsent != NULL));
653 pbuf_cat(last_unsent->p, concat_p);
654 last_unsent->len += concat_p->tot_len;
655 #if TCP_CHECKSUM_ON_COPY
656 if (concat_chksummed) {
657 tcp_seg_add_chksum(concat_chksum, concat_chksummed, &last_unsent->chksum,
658 &last_unsent->chksum_swapped);
659 last_unsent->flags |= TF_SEG_DATA_CHECKSUMMED;
661 #endif /* TCP_CHECKSUM_ON_COPY */
665 * Phase 3: Append queue to pcb->unsent. Queue may be NULL, but that
668 if (last_unsent == NULL) {
671 last_unsent->next = queue;
675 * Finally update the pcb state.
679 pcb->snd_queuelen = queuelen;
681 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_write: %"S16_F" (after enqueued)\n",
683 if (pcb->snd_queuelen != 0) {
684 LWIP_ASSERT("tcp_write: valid queue length",
685 pcb->unacked != NULL || pcb->unsent != NULL);
688 /* Set the PSH flag in the last segment that we enqueued. */
689 if (seg != NULL && seg->tcphdr != NULL && ((apiflags & TCP_WRITE_FLAG_MORE)==0)) {
690 TCPH_SET_FLAG(seg->tcphdr, TCP_PSH);
695 pcb->flags |= TF_NAGLEMEMERR;
696 TCP_STATS_INC(tcp.memerr);
698 if (concat_p != NULL) {
702 tcp_segs_free(queue);
704 if (pcb->snd_queuelen != 0) {
705 LWIP_ASSERT("tcp_write: valid queue length", pcb->unacked != NULL ||
706 pcb->unsent != NULL);
708 LWIP_DEBUGF(TCP_QLEN_DEBUG | LWIP_DBG_STATE, ("tcp_write: %"S16_F" (with mem err)\n", pcb->snd_queuelen));
713 * Enqueue TCP options for transmission.
715 * Called by tcp_connect(), tcp_listen_input(), and tcp_send_ctrl().
717 * @param pcb Protocol control block for the TCP connection.
718 * @param flags TCP header flags to set in the outgoing segment.
719 * @param optdata pointer to TCP options, or NULL.
720 * @param optlen length of TCP options in bytes.
723 tcp_enqueue_flags(struct tcp_pcb *pcb, u8_t flags)
730 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue_flags: queuelen: %"U16_F"\n", (u16_t)pcb->snd_queuelen));
732 LWIP_ASSERT("tcp_enqueue_flags: need either TCP_SYN or TCP_FIN in flags (programmer violates API)",
733 (flags & (TCP_SYN | TCP_FIN)) != 0);
735 /* check for configured max queuelen and possible overflow */
736 if ((pcb->snd_queuelen >= TCP_SND_QUEUELEN) || (pcb->snd_queuelen > TCP_SNDQUEUELEN_OVERFLOW)) {
737 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue_flags: too long queue %"U16_F" (max %"U16_F")\n",
738 pcb->snd_queuelen, TCP_SND_QUEUELEN));
739 TCP_STATS_INC(tcp.memerr);
740 pcb->flags |= TF_NAGLEMEMERR;
744 if (flags & TCP_SYN) {
745 optflags = TF_SEG_OPTS_MSS;
747 #if LWIP_TCP_TIMESTAMPS
748 if ((pcb->flags & TF_TIMESTAMP)) {
749 optflags |= TF_SEG_OPTS_TS;
751 #endif /* LWIP_TCP_TIMESTAMPS */
752 optlen = LWIP_TCP_OPT_LENGTH(optflags);
754 /* tcp_enqueue_flags is always called with either SYN or FIN in flags.
755 * We need one available snd_buf byte to do that.
756 * This means we can't send FIN while snd_buf==0. A better fix would be to
757 * not include SYN and FIN sequence numbers in the snd_buf count. */
758 if (pcb->snd_buf == 0) {
759 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue_flags: no send buffer available\n"));
760 TCP_STATS_INC(tcp.memerr);
764 /* Allocate pbuf with room for TCP header + options */
765 if ((p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) {
766 pcb->flags |= TF_NAGLEMEMERR;
767 TCP_STATS_INC(tcp.memerr);
770 LWIP_ASSERT("tcp_enqueue_flags: check that first pbuf can hold optlen",
773 /* Allocate memory for tcp_seg, and fill in fields. */
774 if ((seg = tcp_create_segment(pcb, p, flags, pcb->snd_lbb, optflags)) == NULL) {
775 pcb->flags |= TF_NAGLEMEMERR;
776 TCP_STATS_INC(tcp.memerr);
779 LWIP_ASSERT("seg->tcphdr not aligned", ((mem_ptr_t)seg->tcphdr % MEM_ALIGNMENT) == 0);
780 LWIP_ASSERT("tcp_enqueue_flags: invalid segment length", seg->len == 0);
782 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_TRACE,
783 ("tcp_enqueue_flags: queueing %"U32_F":%"U32_F" (0x%"X16_F")\n",
784 ntohl(seg->tcphdr->seqno),
785 ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg),
788 /* Now append seg to pcb->unsent queue */
789 if (pcb->unsent == NULL) {
792 struct tcp_seg *useg;
793 for (useg = pcb->unsent; useg->next != NULL; useg = useg->next);
797 /* The new unsent tail has no space */
798 pcb->unsent_oversize = 0;
799 #endif /* TCP_OVERSIZE */
801 /* SYN and FIN bump the sequence number */
802 if ((flags & TCP_SYN) || (flags & TCP_FIN)) {
804 /* optlen does not influence snd_buf */
807 if (flags & TCP_FIN) {
808 pcb->flags |= TF_FIN;
811 /* update number of segments on the queues */
812 pcb->snd_queuelen += pbuf_clen(seg->p);
813 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue_flags: %"S16_F" (after enqueued)\n", pcb->snd_queuelen));
814 if (pcb->snd_queuelen != 0) {
815 LWIP_ASSERT("tcp_enqueue_flags: invalid queue length",
816 pcb->unacked != NULL || pcb->unsent != NULL);
822 #if LWIP_TCP_TIMESTAMPS
823 /* Build a timestamp option (12 bytes long) at the specified options pointer)
826 * @param opts option pointer where to store the timestamp option
829 tcp_build_timestamp_option(struct tcp_pcb *pcb, u32_t *opts)
831 /* Pad with two NOP options to make everything nicely aligned */
832 opts[0] = PP_HTONL(0x0101080A);
833 opts[1] = htonl(sys_now());
834 opts[2] = htonl(pcb->ts_recent);
838 /** Send an ACK without data.
840 * @param pcb Protocol control block for the TCP connection to send the ACK
843 tcp_send_empty_ack(struct tcp_pcb *pcb)
846 struct tcp_hdr *tcphdr;
849 #if LWIP_TCP_TIMESTAMPS
850 if (pcb->flags & TF_TIMESTAMP) {
851 optlen = LWIP_TCP_OPT_LENGTH(TF_SEG_OPTS_TS);
855 p = tcp_output_alloc_header(pcb, optlen, 0, htonl(pcb->snd_nxt));
857 LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: (ACK) could not allocate pbuf\n"));
860 tcphdr = (struct tcp_hdr *)p->payload;
861 LWIP_DEBUGF(TCP_OUTPUT_DEBUG,
862 ("tcp_output: sending ACK for %"U32_F"\n", pcb->rcv_nxt));
863 /* remove ACK flags from the PCB, as we send an empty ACK now */
864 pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
866 /* NB. MSS option is only sent on SYNs, so ignore it here */
867 #if LWIP_TCP_TIMESTAMPS
868 pcb->ts_lastacksent = pcb->rcv_nxt;
870 if (pcb->flags & TF_TIMESTAMP) {
871 tcp_build_timestamp_option(pcb, (u32_t *)(tcphdr + 1));
876 tcphdr->chksum = ipX_chksum_pseudo(PCB_ISIPV6(pcb), p, IP_PROTO_TCP, p->tot_len,
877 &pcb->local_ip, &pcb->remote_ip);
879 #if LWIP_NETIF_HWADDRHINT
880 ipX_output_hinted(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, pcb->tos,
881 IP_PROTO_TCP, &pcb->addr_hint);
882 #else /* LWIP_NETIF_HWADDRHINT*/
883 ipX_output(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, pcb->tos,
885 #endif /* LWIP_NETIF_HWADDRHINT*/
892 * Find out what we can send and send it
894 * @param pcb Protocol control block for the TCP connection to send data
895 * @return ERR_OK if data has been sent or nothing to send
896 * another err_t on error
899 tcp_output(struct tcp_pcb *pcb)
901 struct tcp_seg *seg, *useg;
905 #endif /* TCP_CWND_DEBUG */
907 /* pcb->state LISTEN not allowed here */
908 LWIP_ASSERT("don't call tcp_output for listen-pcbs",
909 pcb->state != LISTEN);
911 /* First, check if we are invoked by the TCP input processing
912 code. If so, we do not output anything. Instead, we rely on the
913 input processing code to call us when input processing is done
915 if (tcp_input_pcb == pcb) {
919 wnd = LWIP_MIN(pcb->snd_wnd, pcb->cwnd);
923 /* If the TF_ACK_NOW flag is set and no data will be sent (either
924 * because the ->unsent queue is empty or because the window does
925 * not allow it), construct an empty ACK segment and send it.
927 * If data is to be sent, we will just piggyback the ACK (see below).
929 if (pcb->flags & TF_ACK_NOW &&
931 ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len > wnd)) {
932 return tcp_send_empty_ack(pcb);
935 /* useg should point to last segment on unacked queue */
938 for (; useg->next != NULL; useg = useg->next);
943 LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: nothing to send (%p)\n",
944 (void*)pcb->unsent));
946 #endif /* TCP_OUTPUT_DEBUG */
949 LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"U16_F
950 ", cwnd %"U16_F", wnd %"U32_F
951 ", seg == NULL, ack %"U32_F"\n",
952 pcb->snd_wnd, pcb->cwnd, wnd, pcb->lastack));
954 LWIP_DEBUGF(TCP_CWND_DEBUG,
955 ("tcp_output: snd_wnd %"U16_F", cwnd %"U16_F", wnd %"U32_F
956 ", effwnd %"U32_F", seq %"U32_F", ack %"U32_F"\n",
957 pcb->snd_wnd, pcb->cwnd, wnd,
958 ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len,
959 ntohl(seg->tcphdr->seqno), pcb->lastack));
961 #endif /* TCP_CWND_DEBUG */
962 /* data available and window allows it to be sent? */
963 while (seg != NULL &&
964 ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) {
965 LWIP_ASSERT("RST not expected here!",
966 (TCPH_FLAGS(seg->tcphdr) & TCP_RST) == 0);
967 /* Stop sending if the nagle algorithm would prevent it
969 * - if tcp_write had a memory error before (prevent delayed ACK timeout) or
970 * - if FIN was already enqueued for this PCB (SYN is always alone in a segment -
971 * either seg->next != NULL or pcb->unacked == NULL;
972 * RST is no sent using tcp_write/tcp_output.
974 if((tcp_do_output_nagle(pcb) == 0) &&
975 ((pcb->flags & (TF_NAGLEMEMERR | TF_FIN)) == 0)){
979 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",
980 pcb->snd_wnd, pcb->cwnd, wnd,
981 ntohl(seg->tcphdr->seqno) + seg->len -
983 ntohl(seg->tcphdr->seqno), pcb->lastack, i));
985 #endif /* TCP_CWND_DEBUG */
987 pcb->unsent = seg->next;
989 if (pcb->state != SYN_SENT) {
990 TCPH_SET_FLAG(seg->tcphdr, TCP_ACK);
991 pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
994 #if TCP_OVERSIZE_DBGCHECK
995 seg->oversize_left = 0;
996 #endif /* TCP_OVERSIZE_DBGCHECK */
997 tcp_output_segment(seg, pcb);
998 snd_nxt = ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg);
999 if (TCP_SEQ_LT(pcb->snd_nxt, snd_nxt)) {
1000 pcb->snd_nxt = snd_nxt;
1002 /* put segment on unacknowledged list if length > 0 */
1003 if (TCP_TCPLEN(seg) > 0) {
1005 /* unacked list is empty? */
1006 if (pcb->unacked == NULL) {
1009 /* unacked list is not empty? */
1011 /* In the case of fast retransmit, the packet should not go to the tail
1012 * of the unacked queue, but rather somewhere before it. We need to check for
1013 * this case. -STJ Jul 27, 2004 */
1014 if (TCP_SEQ_LT(ntohl(seg->tcphdr->seqno), ntohl(useg->tcphdr->seqno))) {
1015 /* add segment to before tail of unacked list, keeping the list sorted */
1016 struct tcp_seg **cur_seg = &(pcb->unacked);
1018 TCP_SEQ_LT(ntohl((*cur_seg)->tcphdr->seqno), ntohl(seg->tcphdr->seqno))) {
1019 cur_seg = &((*cur_seg)->next );
1021 seg->next = (*cur_seg);
1024 /* add segment to tail of unacked list */
1029 /* do not queue empty segments on the unacked list */
1036 if (pcb->unsent == NULL) {
1037 /* last unsent has been removed, reset unsent_oversize */
1038 pcb->unsent_oversize = 0;
1040 #endif /* TCP_OVERSIZE */
1042 pcb->flags &= ~TF_NAGLEMEMERR;
1047 * Called by tcp_output() to actually send a TCP segment over IP.
1049 * @param seg the tcp_seg to send
1050 * @param pcb the tcp_pcb for the TCP connection used to send the segment
1053 tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb)
1058 /** @bug Exclude retransmitted segments from this count. */
1059 snmp_inc_tcpoutsegs();
1061 /* The TCP header has already been constructed, but the ackno and
1062 wnd fields remain. */
1063 seg->tcphdr->ackno = htonl(pcb->rcv_nxt);
1065 /* advertise our receive window size in this TCP segment */
1066 seg->tcphdr->wnd = htons(pcb->rcv_ann_wnd);
1068 pcb->rcv_ann_right_edge = pcb->rcv_nxt + pcb->rcv_ann_wnd;
1070 /* Add any requested options. NB MSS option is only set on SYN
1071 packets, so ignore it here */
1072 opts = (u32_t *)(void *)(seg->tcphdr + 1);
1073 if (seg->flags & TF_SEG_OPTS_MSS) {
1075 #if TCP_CALCULATE_EFF_SEND_MSS
1076 mss = tcp_eff_send_mss(TCP_MSS, &pcb->local_ip, &pcb->remote_ip, PCB_ISIPV6(pcb));
1077 #else /* TCP_CALCULATE_EFF_SEND_MSS */
1079 #endif /* TCP_CALCULATE_EFF_SEND_MSS */
1080 *opts = TCP_BUILD_MSS_OPTION(mss);
1083 #if LWIP_TCP_TIMESTAMPS
1084 pcb->ts_lastacksent = pcb->rcv_nxt;
1086 if (seg->flags & TF_SEG_OPTS_TS) {
1087 tcp_build_timestamp_option(pcb, opts);
1092 /* Set retransmission timer running if it is not currently enabled
1093 This must be set before checking the route. */
1094 if (pcb->rtime == -1) {
1098 /* If we don't have a local IP address, we get one by
1099 calling ip_route(). */
1100 if (ipX_addr_isany(PCB_ISIPV6(pcb), &pcb->local_ip)) {
1101 struct netif *netif;
1102 ipX_addr_t *local_ip;
1103 ipX_route_get_local_ipX(PCB_ISIPV6(pcb), &pcb->local_ip, &pcb->remote_ip, netif, local_ip);
1104 if ((netif == NULL) || (local_ip == NULL)) {
1107 ipX_addr_copy(PCB_ISIPV6(pcb), pcb->local_ip, *local_ip);
1110 if (pcb->rttest == 0) {
1111 pcb->rttest = tcp_ticks;
1112 pcb->rtseq = ntohl(seg->tcphdr->seqno);
1114 LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_output_segment: rtseq %"U32_F"\n", pcb->rtseq));
1116 LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output_segment: %"U32_F":%"U32_F"\n",
1117 htonl(seg->tcphdr->seqno), htonl(seg->tcphdr->seqno) +
1120 len = (u16_t)((u8_t *)seg->tcphdr - (u8_t *)seg->p->payload);
1123 seg->p->tot_len -= len;
1125 seg->p->payload = seg->tcphdr;
1127 seg->tcphdr->chksum = 0;
1128 #if TCP_CHECKSUM_ON_COPY
1131 #if TCP_CHECKSUM_ON_COPY_SANITY_CHECK
1132 u16_t chksum_slow = ipX_chksum_pseudo(PCB_ISIPV6(pcb), seg->p, IP_PROTO_TCP,
1133 seg->p->tot_len, &pcb->local_ip, &pcb->remote_ip);
1134 #endif /* TCP_CHECKSUM_ON_COPY_SANITY_CHECK */
1135 if ((seg->flags & TF_SEG_DATA_CHECKSUMMED) == 0) {
1136 LWIP_ASSERT("data included but not checksummed",
1137 seg->p->tot_len == (TCPH_HDRLEN(seg->tcphdr) * 4));
1140 /* rebuild TCP header checksum (TCP header changes for retransmissions!) */
1141 acc = ipX_chksum_pseudo_partial(PCB_ISIPV6(pcb), seg->p, IP_PROTO_TCP,
1142 seg->p->tot_len, TCPH_HDRLEN(seg->tcphdr) * 4, &pcb->local_ip, &pcb->remote_ip);
1143 /* add payload checksum */
1144 if (seg->chksum_swapped) {
1145 seg->chksum = SWAP_BYTES_IN_WORD(seg->chksum);
1146 seg->chksum_swapped = 0;
1148 acc += (u16_t)~(seg->chksum);
1149 seg->tcphdr->chksum = FOLD_U32T(acc);
1150 #if TCP_CHECKSUM_ON_COPY_SANITY_CHECK
1151 if (chksum_slow != seg->tcphdr->chksum) {
1152 LWIP_DEBUGF(TCP_DEBUG | LWIP_DBG_LEVEL_WARNING,
1153 ("tcp_output_segment: calculated checksum is %"X16_F" instead of %"X16_F"\n",
1154 seg->tcphdr->chksum, chksum_slow));
1155 seg->tcphdr->chksum = chksum_slow;
1157 #endif /* TCP_CHECKSUM_ON_COPY_SANITY_CHECK */
1159 #else /* TCP_CHECKSUM_ON_COPY */
1160 #if CHECKSUM_GEN_TCP
1161 seg->tcphdr->chksum = ipX_chksum_pseudo(PCB_ISIPV6(pcb), seg->p, IP_PROTO_TCP,
1162 seg->p->tot_len, &pcb->local_ip, &pcb->remote_ip);
1163 #endif /* CHECKSUM_GEN_TCP */
1164 #endif /* TCP_CHECKSUM_ON_COPY */
1165 TCP_STATS_INC(tcp.xmit);
1167 #if LWIP_NETIF_HWADDRHINT
1168 ipX_output_hinted(PCB_ISIPV6(pcb), seg->p, &pcb->local_ip, &pcb->remote_ip,
1169 pcb->ttl, pcb->tos, IP_PROTO_TCP, &pcb->addr_hint);
1170 #else /* LWIP_NETIF_HWADDRHINT*/
1171 ipX_output(PCB_ISIPV6(pcb), seg->p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl,
1172 pcb->tos, IP_PROTO_TCP);
1173 #endif /* LWIP_NETIF_HWADDRHINT*/
1177 * Send a TCP RESET packet (empty segment with RST flag set) either to
1178 * abort a connection or to show that there is no matching local connection
1179 * for a received segment.
1181 * Called by tcp_abort() (to abort a local connection), tcp_input() (if no
1182 * matching local pcb was found), tcp_listen_input() (if incoming segment
1183 * has ACK flag set) and tcp_process() (received segment in the wrong state)
1185 * Since a RST segment is in most cases not sent for an active connection,
1186 * tcp_rst() has a number of arguments that are taken from a tcp_pcb for
1187 * most other segment output functions.
1189 * @param seqno the sequence number to use for the outgoing segment
1190 * @param ackno the acknowledge number to use for the outgoing segment
1191 * @param local_ip the local IP address to send the segment from
1192 * @param remote_ip the remote IP address to send the segment to
1193 * @param local_port the local TCP port to send the segment from
1194 * @param remote_port the remote TCP port to send the segment to
1197 tcp_rst_impl(u32_t seqno, u32_t ackno,
1198 ipX_addr_t *local_ip, ipX_addr_t *remote_ip,
1199 u16_t local_port, u16_t remote_port
1202 #endif /* LWIP_IPV6 */
1206 struct tcp_hdr *tcphdr;
1207 p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM);
1209 LWIP_DEBUGF(TCP_DEBUG, ("tcp_rst: could not allocate memory for pbuf\n"));
1212 LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr",
1213 (p->len >= sizeof(struct tcp_hdr)));
1215 tcphdr = (struct tcp_hdr *)p->payload;
1216 tcphdr->src = htons(local_port);
1217 tcphdr->dest = htons(remote_port);
1218 tcphdr->seqno = htonl(seqno);
1219 tcphdr->ackno = htonl(ackno);
1220 TCPH_HDRLEN_FLAGS_SET(tcphdr, TCP_HLEN/4, TCP_RST | TCP_ACK);
1221 tcphdr->wnd = PP_HTONS(TCP_WND);
1225 TCP_STATS_INC(tcp.xmit);
1226 snmp_inc_tcpoutrsts();
1228 #if CHECKSUM_GEN_TCP
1229 tcphdr->chksum = ipX_chksum_pseudo(isipv6, p, IP_PROTO_TCP, p->tot_len,
1230 local_ip, remote_ip);
1232 /* Send output with hardcoded TTL/HL since we have no access to the pcb */
1233 ipX_output(isipv6, p, local_ip, remote_ip, TCP_TTL, 0, IP_PROTO_TCP);
1235 LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_rst: seqno %"U32_F" ackno %"U32_F".\n", seqno, ackno));
1239 * Requeue all unacked segments for retransmission
1241 * Called by tcp_slowtmr() for slow retransmission.
1243 * @param pcb the tcp_pcb for which to re-enqueue all unacked segments
1246 tcp_rexmit_rto(struct tcp_pcb *pcb)
1248 struct tcp_seg *seg;
1250 if (pcb->unacked == NULL) {
1254 /* Move all unacked segments to the head of the unsent queue */
1255 for (seg = pcb->unacked; seg->next != NULL; seg = seg->next);
1256 /* concatenate unsent queue after unacked queue */
1257 seg->next = pcb->unsent;
1258 /* unsent queue is the concatenated queue (of unacked, unsent) */
1259 pcb->unsent = pcb->unacked;
1260 /* unacked queue is now empty */
1261 pcb->unacked = NULL;
1262 /* last unsent hasn't changed, no need to reset unsent_oversize */
1264 /* increment number of retransmissions */
1267 /* Don't take any RTT measurements after retransmitting. */
1270 /* Do the actual retransmission */
1275 * Requeue the first unacked segment for retransmission
1277 * Called by tcp_receive() for fast retramsmit.
1279 * @param pcb the tcp_pcb for which to retransmit the first unacked segment
1282 tcp_rexmit(struct tcp_pcb *pcb)
1284 struct tcp_seg *seg;
1285 struct tcp_seg **cur_seg;
1287 if (pcb->unacked == NULL) {
1291 /* Move the first unacked segment to the unsent queue */
1292 /* Keep the unsent queue sorted. */
1294 pcb->unacked = seg->next;
1296 cur_seg = &(pcb->unsent);
1298 TCP_SEQ_LT(ntohl((*cur_seg)->tcphdr->seqno), ntohl(seg->tcphdr->seqno))) {
1299 cur_seg = &((*cur_seg)->next );
1301 seg->next = *cur_seg;
1304 if (seg->next == NULL) {
1305 /* the retransmitted segment is last in unsent, so reset unsent_oversize */
1306 pcb->unsent_oversize = 0;
1308 #endif /* TCP_OVERSIZE */
1312 /* Don't take any rtt measurements after retransmitting. */
1315 /* Do the actual retransmission. */
1316 snmp_inc_tcpretranssegs();
1317 /* No need to call tcp_output: we are always called from tcp_input()
1318 and thus tcp_output directly returns. */
1323 * Handle retransmission after three dupacks received
1325 * @param pcb the tcp_pcb for which to retransmit the first unacked segment
1328 tcp_rexmit_fast(struct tcp_pcb *pcb)
1330 if (pcb->unacked != NULL && !(pcb->flags & TF_INFR)) {
1331 /* This is fast retransmit. Retransmit the first unacked segment. */
1332 LWIP_DEBUGF(TCP_FR_DEBUG,
1333 ("tcp_receive: dupacks %"U16_F" (%"U32_F
1334 "), fast retransmit %"U32_F"\n",
1335 (u16_t)pcb->dupacks, pcb->lastack,
1336 ntohl(pcb->unacked->tcphdr->seqno)));
1339 /* Set ssthresh to half of the minimum of the current
1340 * cwnd and the advertised window */
1341 if (pcb->cwnd > pcb->snd_wnd) {
1342 pcb->ssthresh = pcb->snd_wnd / 2;
1344 pcb->ssthresh = pcb->cwnd / 2;
1347 /* The minimum value for ssthresh should be 2 MSS */
1348 if (pcb->ssthresh < 2*pcb->mss) {
1349 LWIP_DEBUGF(TCP_FR_DEBUG,
1350 ("tcp_receive: The minimum value for ssthresh %"U16_F
1351 " should be min 2 mss %"U16_F"...\n",
1352 pcb->ssthresh, 2*pcb->mss));
1353 pcb->ssthresh = 2*pcb->mss;
1356 pcb->cwnd = pcb->ssthresh + 3 * pcb->mss;
1357 pcb->flags |= TF_INFR;
1363 * Send keepalive packets to keep a connection active although
1364 * no data is sent over it.
1366 * Called by tcp_slowtmr()
1368 * @param pcb the tcp_pcb for which to send a keepalive packet
1371 tcp_keepalive(struct tcp_pcb *pcb)
1374 struct tcp_hdr *tcphdr;
1376 LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: sending KEEPALIVE probe to "));
1377 ipX_addr_debug_print(PCB_ISIPV6(pcb), TCP_DEBUG, &pcb->remote_ip);
1378 LWIP_DEBUGF(TCP_DEBUG, ("\n"));
1380 LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: tcp_ticks %"U32_F" pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n",
1381 tcp_ticks, pcb->tmr, pcb->keep_cnt_sent));
1383 p = tcp_output_alloc_header(pcb, 0, 0, htonl(pcb->snd_nxt - 1));
1385 LWIP_DEBUGF(TCP_DEBUG,
1386 ("tcp_keepalive: could not allocate memory for pbuf\n"));
1389 tcphdr = (struct tcp_hdr *)p->payload;
1391 tcphdr->chksum = ipX_chksum_pseudo(PCB_ISIPV6(pcb), p, IP_PROTO_TCP, p->tot_len,
1392 &pcb->local_ip, &pcb->remote_ip);
1393 TCP_STATS_INC(tcp.xmit);
1395 /* Send output to IP */
1396 #if LWIP_NETIF_HWADDRHINT
1397 ipX_output_hinted(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip,
1398 pcb->ttl, 0, IP_PROTO_TCP, &pcb->addr_hint);
1399 #else /* LWIP_NETIF_HWADDRHINT*/
1400 ipX_output(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl,
1402 #endif /* LWIP_NETIF_HWADDRHINT*/
1406 LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: seqno %"U32_F" ackno %"U32_F".\n",
1407 pcb->snd_nxt - 1, pcb->rcv_nxt));
1412 * Send persist timer zero-window probes to keep a connection active
1413 * when a window update is lost.
1415 * Called by tcp_slowtmr()
1417 * @param pcb the tcp_pcb for which to send a zero-window probe packet
1420 tcp_zero_window_probe(struct tcp_pcb *pcb)
1423 struct tcp_hdr *tcphdr;
1424 struct tcp_seg *seg;
1428 LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: sending ZERO WINDOW probe to "));
1429 ipX_addr_debug_print(PCB_ISIPV6(pcb), TCP_DEBUG, &pcb->remote_ip);
1430 LWIP_DEBUGF(TCP_DEBUG, ("\n"));
1432 LWIP_DEBUGF(TCP_DEBUG,
1433 ("tcp_zero_window_probe: tcp_ticks %"U32_F
1434 " pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n",
1435 tcp_ticks, pcb->tmr, pcb->keep_cnt_sent));
1446 is_fin = ((TCPH_FLAGS(seg->tcphdr) & TCP_FIN) != 0) && (seg->len == 0);
1447 /* we want to send one seqno: either FIN or data (no options) */
1448 len = is_fin ? 0 : 1;
1450 p = tcp_output_alloc_header(pcb, 0, len, seg->tcphdr->seqno);
1452 LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: no memory for pbuf\n"));
1455 tcphdr = (struct tcp_hdr *)p->payload;
1458 /* FIN segment, no data */
1459 TCPH_FLAGS_SET(tcphdr, TCP_ACK | TCP_FIN);
1461 /* Data segment, copy in one byte from the head of the unacked queue */
1462 char *d = ((char *)p->payload + TCP_HLEN);
1463 /* Depending on whether the segment has already been sent (unacked) or not
1464 (unsent), seg->p->payload points to the IP header or TCP header.
1465 Ensure we copy the first TCP data byte: */
1466 pbuf_copy_partial(seg->p, d, 1, seg->p->tot_len - seg->len);
1469 #if CHECKSUM_GEN_TCP
1470 tcphdr->chksum = ipX_chksum_pseudo(PCB_ISIPV6(pcb), p, IP_PROTO_TCP, p->tot_len,
1471 &pcb->local_ip, &pcb->remote_ip);
1473 TCP_STATS_INC(tcp.xmit);
1475 /* Send output to IP */
1476 #if LWIP_NETIF_HWADDRHINT
1477 ipX_output_hinted(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl,
1478 0, IP_PROTO_TCP, &pcb->addr_hint);
1479 #else /* LWIP_NETIF_HWADDRHINT*/
1480 ipX_output(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP);
1481 #endif /* LWIP_NETIF_HWADDRHINT*/
1485 LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: seqno %"U32_F
1486 " ackno %"U32_F".\n",
1487 pcb->snd_nxt - 1, pcb->rcv_nxt));
1489 #endif /* LWIP_TCP */