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"
50 #include "lwip/ip_addr.h"
51 #include "lwip/netif.h"
52 #include "lwip/inet_chksum.h"
53 #include "lwip/stats.h"
54 #include "lwip/snmp.h"
58 /* Define some copy-macros for checksum-on-copy so that the code looks
59 nicer by preventing too many ifdef's. */
60 #if TCP_CHECKSUM_ON_COPY
61 #define TCP_DATA_COPY(dst, src, len, seg) do { \
62 tcp_seg_add_chksum(LWIP_CHKSUM_COPY(dst, src, len), \
63 len, &seg->chksum, &seg->chksum_swapped); \
64 seg->flags |= TF_SEG_DATA_CHECKSUMMED; } while(0)
65 #define TCP_DATA_COPY2(dst, src, len, chksum, chksum_swapped) \
66 tcp_seg_add_chksum(LWIP_CHKSUM_COPY(dst, src, len), len, chksum, chksum_swapped);
67 #else /* TCP_CHECKSUM_ON_COPY*/
68 #define TCP_DATA_COPY(dst, src, len, seg) MEMCPY(dst, src, len)
69 #define TCP_DATA_COPY2(dst, src, len, chksum, chksum_swapped) MEMCPY(dst, src, len)
70 #endif /* TCP_CHECKSUM_ON_COPY*/
72 /** Define this to 1 for an extra check that the output checksum is valid
73 * (usefule when the checksum is generated by the application, not the stack) */
74 #ifndef TCP_CHECKSUM_ON_COPY_SANITY_CHECK
75 #define TCP_CHECKSUM_ON_COPY_SANITY_CHECK 0
78 /* Forward declarations.*/
79 static void tcp_output_segment(struct tcp_seg
*seg
, struct tcp_pcb
*pcb
);
81 /** Allocate a pbuf and create a tcphdr at p->payload, used for output
82 * functions other than the default tcp_output -> tcp_output_segment
83 * (e.g. tcp_send_empty_ack, etc.)
85 * @param pcb tcp pcb for which to send a packet (used to initialize tcp_hdr)
86 * @param optlen length of header-options
87 * @param datalen length of tcp data to reserve in pbuf
88 * @param seqno_be seqno in network byte order (big-endian)
89 * @return pbuf with p->payload being the tcp_hdr
92 tcp_output_alloc_header(struct tcp_pcb
*pcb
, u16_t optlen
, u16_t datalen
,
93 u32_t seqno_be
/* already in network byte order */)
95 struct tcp_hdr
*tcphdr
;
96 struct pbuf
*p
= pbuf_alloc(PBUF_IP
, TCP_HLEN
+ optlen
+ datalen
, PBUF_RAM
);
98 LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr",
99 (p
->len
>= TCP_HLEN
+ optlen
));
100 tcphdr
= (struct tcp_hdr
*)p
->payload
;
101 tcphdr
->src
= htons(pcb
->local_port
);
102 tcphdr
->dest
= htons(pcb
->remote_port
);
103 tcphdr
->seqno
= seqno_be
;
104 tcphdr
->ackno
= htonl(pcb
->rcv_nxt
);
105 TCPH_HDRLEN_FLAGS_SET(tcphdr
, (5 + optlen
/ 4), TCP_ACK
);
106 tcphdr
->wnd
= htons(pcb
->rcv_ann_wnd
);
110 /* If we're sending a packet, update the announced right window edge */
111 pcb
->rcv_ann_right_edge
= pcb
->rcv_nxt
+ pcb
->rcv_ann_wnd
;
117 * Called by tcp_close() to send a segment including FIN flag but not data.
119 * @param pcb the tcp_pcb over which to send a segment
120 * @return ERR_OK if sent, another err_t otherwise
123 tcp_send_fin(struct tcp_pcb
*pcb
)
125 /* first, try to add the fin to the last unsent segment */
126 if (pcb
->unsent
!= NULL
) {
127 struct tcp_seg
*last_unsent
;
128 for (last_unsent
= pcb
->unsent
; last_unsent
->next
!= NULL
;
129 last_unsent
= last_unsent
->next
);
131 if ((TCPH_FLAGS(last_unsent
->tcphdr
) & (TCP_SYN
| TCP_FIN
| TCP_RST
)) == 0) {
132 /* no SYN/FIN/RST flag in the header, we can add the FIN flag */
133 TCPH_SET_FLAG(last_unsent
->tcphdr
, TCP_FIN
);
137 /* no data, no length, flags, copy=1, no optdata */
138 return tcp_enqueue_flags(pcb
, TCP_FIN
);
142 * Create a TCP segment with prefilled header.
144 * Called by tcp_write and tcp_enqueue_flags.
146 * @param pcb Protocol control block for the TCP connection.
147 * @param p pbuf that is used to hold the TCP header.
148 * @param flags TCP flags for header.
149 * @param seqno TCP sequence number of this packet
150 * @param optflags options to include in TCP header
151 * @return a new tcp_seg pointing to p, or NULL.
152 * The TCP header is filled in except ackno and wnd.
153 * p is freed on failure.
155 static struct tcp_seg
*
156 tcp_create_segment(struct tcp_pcb
*pcb
, struct pbuf
*p
, u8_t flags
, u32_t seqno
, u8_t optflags
)
159 u8_t optlen
= LWIP_TCP_OPT_LENGTH(optflags
);
161 if ((seg
= (struct tcp_seg
*)memp_malloc(MEMP_TCP_SEG
)) == NULL
) {
162 LWIP_DEBUGF(TCP_OUTPUT_DEBUG
| 2, ("tcp_create_segment: no memory.\n"));
166 seg
->flags
= optflags
;
169 seg
->dataptr
= p
->payload
;
170 seg
->len
= p
->tot_len
- optlen
;
171 #if TCP_OVERSIZE_DBGCHECK
172 seg
->oversize_left
= 0;
173 #endif /* TCP_OVERSIZE_DBGCHECK */
174 #if TCP_CHECKSUM_ON_COPY
176 seg
->chksum_swapped
= 0;
178 LWIP_ASSERT("invalid optflags passed: TF_SEG_DATA_CHECKSUMMED",
179 (optflags
& TF_SEG_DATA_CHECKSUMMED
) == 0);
180 #endif /* TCP_CHECKSUM_ON_COPY */
182 /* build TCP header */
183 if (pbuf_header(p
, TCP_HLEN
)) {
184 LWIP_DEBUGF(TCP_OUTPUT_DEBUG
| 2, ("tcp_create_segment: no room for TCP header in pbuf.\n"));
185 TCP_STATS_INC(tcp
.err
);
189 seg
->tcphdr
= (struct tcp_hdr
*)seg
->p
->payload
;
190 seg
->tcphdr
->src
= htons(pcb
->local_port
);
191 seg
->tcphdr
->dest
= htons(pcb
->remote_port
);
192 seg
->tcphdr
->seqno
= htonl(seqno
);
193 /* ackno is set in tcp_output */
194 TCPH_HDRLEN_FLAGS_SET(seg
->tcphdr
, (5 + optlen
/ 4), flags
);
195 /* wnd and chksum are set in tcp_output */
196 seg
->tcphdr
->urgp
= 0;
201 * Allocate a PBUF_RAM pbuf, perhaps with extra space at the end.
203 * This function is like pbuf_alloc(layer, length, PBUF_RAM) except
204 * there may be extra bytes available at the end.
206 * @param layer flag to define header size.
207 * @param length size of the pbuf's payload.
208 * @param max_length maximum usable size of payload+oversize.
209 * @param oversize pointer to a u16_t that will receive the number of usable tail bytes.
210 * @param pcb The TCP connection that willo enqueue the pbuf.
211 * @param apiflags API flags given to tcp_write.
212 * @param first_seg true when this pbuf will be used in the first enqueued segment.
217 tcp_pbuf_prealloc(pbuf_layer layer
, u16_t length
, u16_t max_length
,
218 u16_t
*oversize
, struct tcp_pcb
*pcb
, u8_t apiflags
,
222 u16_t alloc
= length
;
224 #if LWIP_NETIF_TX_SINGLE_PBUF
225 LWIP_UNUSED_ARG(max_length
);
226 LWIP_UNUSED_ARG(pcb
);
227 LWIP_UNUSED_ARG(apiflags
);
228 LWIP_UNUSED_ARG(first_seg
);
229 /* always create MSS-sized pbufs */
231 #else /* LWIP_NETIF_TX_SINGLE_PBUF */
232 if (length
< max_length
) {
233 /* Should we allocate an oversized pbuf, or just the minimum
234 * length required? If tcp_write is going to be called again
235 * before this segment is transmitted, we want the oversized
236 * buffer. If the segment will be transmitted immediately, we can
237 * save memory by allocating only length. We use a simple
238 * heuristic based on the following information:
240 * Did the user set TCP_WRITE_FLAG_MORE?
242 * Will the Nagle algorithm defer transmission of this segment?
244 if ((apiflags
& TCP_WRITE_FLAG_MORE
) ||
245 (!(pcb
->flags
& TF_NODELAY
) &&
247 pcb
->unsent
!= NULL
||
248 pcb
->unacked
!= NULL
))) {
249 alloc
= LWIP_MIN(max_length
, LWIP_MEM_ALIGN_SIZE(length
+ TCP_OVERSIZE
));
252 #endif /* LWIP_NETIF_TX_SINGLE_PBUF */
253 p
= pbuf_alloc(layer
, alloc
, PBUF_RAM
);
257 LWIP_ASSERT("need unchained pbuf", p
->next
== NULL
);
258 *oversize
= p
->len
- length
;
259 /* trim p->len to the currently used size */
260 p
->len
= p
->tot_len
= length
;
263 #else /* TCP_OVERSIZE */
264 #define tcp_pbuf_prealloc(layer, length, mx, os, pcb, api, fst) pbuf_alloc((layer), (length), PBUF_RAM)
265 #endif /* TCP_OVERSIZE */
267 #if TCP_CHECKSUM_ON_COPY
268 /** Add a checksum of newly added data to the segment */
270 tcp_seg_add_chksum(u16_t chksum
, u16_t len
, u16_t
*seg_chksum
,
271 u8_t
*seg_chksum_swapped
)
274 /* add chksum to old chksum and fold to u16_t */
275 helper
= chksum
+ *seg_chksum
;
276 chksum
= FOLD_U32T(helper
);
277 if ((len
& 1) != 0) {
278 *seg_chksum_swapped
= 1 - *seg_chksum_swapped
;
279 chksum
= SWAP_BYTES_IN_WORD(chksum
);
281 *seg_chksum
= chksum
;
283 #endif /* TCP_CHECKSUM_ON_COPY */
285 /** Checks if tcp_write is allowed or not (checks state, snd_buf and snd_queuelen).
287 * @param pcb the tcp pcb to check for
288 * @param len length of data to send (checked agains snd_buf)
289 * @return ERR_OK if tcp_write is allowed to proceed, another err_t otherwise
292 tcp_write_checks(struct tcp_pcb
*pcb
, u16_t len
)
294 /* connection is in invalid state for data transmission? */
295 if ((pcb
->state
!= ESTABLISHED
) &&
296 (pcb
->state
!= CLOSE_WAIT
) &&
297 (pcb
->state
!= SYN_SENT
) &&
298 (pcb
->state
!= SYN_RCVD
)) {
299 LWIP_DEBUGF(TCP_OUTPUT_DEBUG
| LWIP_DBG_STATE
| LWIP_DBG_LEVEL_SEVERE
, ("tcp_write() called in invalid state\n"));
301 } else if (len
== 0) {
305 /* fail on too much data */
306 if (len
> pcb
->snd_buf
) {
307 LWIP_DEBUGF(TCP_OUTPUT_DEBUG
| 3, ("tcp_write: too much data (len=%"U16_F
" > snd_buf=%"U16_F
")\n",
309 pcb
->flags
|= TF_NAGLEMEMERR
;
313 LWIP_DEBUGF(TCP_QLEN_DEBUG
, ("tcp_write: queuelen: %"U16_F
"\n", (u16_t
)pcb
->snd_queuelen
));
315 /* If total number of pbufs on the unsent/unacked queues exceeds the
316 * configured maximum, return an error */
317 /* check for configured max queuelen and possible overflow */
318 if ((pcb
->snd_queuelen
>= TCP_SND_QUEUELEN
) || (pcb
->snd_queuelen
> TCP_SNDQUEUELEN_OVERFLOW
)) {
319 LWIP_DEBUGF(TCP_OUTPUT_DEBUG
| 3, ("tcp_write: too long queue %"U16_F
" (max %"U16_F
")\n",
320 pcb
->snd_queuelen
, TCP_SND_QUEUELEN
));
321 TCP_STATS_INC(tcp
.memerr
);
322 pcb
->flags
|= TF_NAGLEMEMERR
;
325 if (pcb
->snd_queuelen
!= 0) {
326 LWIP_ASSERT("tcp_write: pbufs on queue => at least one queue non-empty",
327 pcb
->unacked
!= NULL
|| pcb
->unsent
!= NULL
);
329 LWIP_ASSERT("tcp_write: no pbufs on queue => both queues empty",
330 pcb
->unacked
== NULL
&& pcb
->unsent
== NULL
);
336 * Write data for sending (but does not send it immediately).
338 * It waits in the expectation of more data being sent soon (as
339 * it can send them more efficiently by combining them together).
340 * To prompt the system to send data now, call tcp_output() after
341 * calling tcp_write().
343 * @param pcb Protocol control block for the TCP connection to enqueue data for.
344 * @param arg Pointer to the data to be enqueued for sending.
345 * @param len Data length in bytes
346 * @param apiflags combination of following flags :
347 * - TCP_WRITE_FLAG_COPY (0x01) data will be copied into memory belonging to the stack
348 * - TCP_WRITE_FLAG_MORE (0x02) for TCP connection, PSH flag will be set on last segment sent,
349 * @return ERR_OK if enqueued, another err_t on error
352 tcp_write(struct tcp_pcb
*pcb
, const void *arg
, u16_t len
, u8_t apiflags
)
354 struct pbuf
*concat_p
= NULL
;
355 struct tcp_seg
*last_unsent
= NULL
, *seg
= NULL
, *prev_seg
= NULL
, *queue
= NULL
;
356 u16_t pos
= 0; /* position in 'arg' data */
362 u16_t oversize_used
= 0;
363 #endif /* TCP_OVERSIZE */
364 #if TCP_CHECKSUM_ON_COPY
365 u16_t concat_chksum
= 0;
366 u8_t concat_chksum_swapped
= 0;
367 u16_t concat_chksummed
= 0;
368 #endif /* TCP_CHECKSUM_ON_COPY */
371 #if LWIP_NETIF_TX_SINGLE_PBUF
372 /* Always copy to try to create single pbufs for TX */
373 apiflags
|= TCP_WRITE_FLAG_COPY
;
374 #endif /* LWIP_NETIF_TX_SINGLE_PBUF */
376 LWIP_DEBUGF(TCP_OUTPUT_DEBUG
, ("tcp_write(pcb=%p, data=%p, len=%"U16_F
", apiflags=%"U16_F
")\n",
377 (void *)pcb
, arg
, len
, (u16_t
)apiflags
));
378 LWIP_ERROR("tcp_write: arg == NULL (programmer violates API)",
379 arg
!= NULL
, return ERR_ARG
;);
381 err
= tcp_write_checks(pcb
, len
);
385 queuelen
= pcb
->snd_queuelen
;
387 #if LWIP_TCP_TIMESTAMPS
388 if ((pcb
->flags
& TF_TIMESTAMP
)) {
389 optflags
= TF_SEG_OPTS_TS
;
390 optlen
= LWIP_TCP_OPT_LENGTH(TF_SEG_OPTS_TS
);
392 #endif /* LWIP_TCP_TIMESTAMPS */
396 * TCP segmentation is done in three phases with increasing complexity:
398 * 1. Copy data directly into an oversized pbuf.
399 * 2. Chain a new pbuf to the end of pcb->unsent.
400 * 3. Create new segments.
402 * We may run out of memory at any point. In that case we must
403 * return ERR_MEM and not change anything in pcb. Therefore, all
404 * changes are recorded in local variables and committed at the end
405 * of the function. Some pcb fields are maintained in local copies:
407 * queuelen = pcb->snd_queuelen
408 * oversize = pcb->unsent_oversize
410 * These variables are set consistently by the phases:
412 * seg points to the last segment tampered with.
414 * pos records progress as data is segmented.
417 /* Find the tail of the unsent queue. */
418 if (pcb
->unsent
!= NULL
) {
422 /* @todo: this could be sped up by keeping last_unsent in the pcb */
423 for (last_unsent
= pcb
->unsent
; last_unsent
->next
!= NULL
;
424 last_unsent
= last_unsent
->next
);
426 /* Usable space at the end of the last unsent segment */
427 unsent_optlen
= LWIP_TCP_OPT_LENGTH(last_unsent
->flags
);
428 space
= pcb
->mss
- (last_unsent
->len
+ unsent_optlen
);
431 * Phase 1: Copy data directly into an oversized pbuf.
433 * The number of bytes copied is recorded in the oversize_used
434 * variable. The actual copying is done at the bottom of the
438 #if TCP_OVERSIZE_DBGCHECK
439 /* check that pcb->unsent_oversize matches last_unsent->unsent_oversize */
440 LWIP_ASSERT("unsent_oversize mismatch (pcb vs. last_unsent)",
441 pcb
->unsent_oversize
== last_unsent
->oversize_left
);
442 #endif /* TCP_OVERSIZE_DBGCHECK */
443 oversize
= pcb
->unsent_oversize
;
445 LWIP_ASSERT("inconsistent oversize vs. space", oversize_used
<= space
);
447 oversize_used
= oversize
< len
? oversize
: len
;
448 pos
+= oversize_used
;
449 oversize
-= oversize_used
;
450 space
-= oversize_used
;
452 /* now we are either finished or oversize is zero */
453 LWIP_ASSERT("inconsistend oversize vs. len", (oversize
== 0) || (pos
== len
));
454 #endif /* TCP_OVERSIZE */
457 * Phase 2: Chain a new pbuf to the end of pcb->unsent.
459 * We don't extend segments containing SYN/FIN flags or options
460 * (len==0). The new pbuf is kept in concat_p and pbuf_cat'ed at
463 if ((pos
< len
) && (space
> 0) && (last_unsent
->len
> 0)) {
464 u16_t seglen
= space
< len
- pos
? space
: len
- pos
;
467 /* Create a pbuf with a copy or reference to seglen bytes. We
468 * can use PBUF_RAW here since the data appears in the middle of
469 * a segment. A header will never be prepended. */
470 if (apiflags
& TCP_WRITE_FLAG_COPY
) {
472 if ((concat_p
= tcp_pbuf_prealloc(PBUF_RAW
, seglen
, space
, &oversize
, pcb
, apiflags
, 1)) == NULL
) {
473 LWIP_DEBUGF(TCP_OUTPUT_DEBUG
| 2,
474 ("tcp_write : could not allocate memory for pbuf copy size %"U16_F
"\n",
478 #if TCP_OVERSIZE_DBGCHECK
479 last_unsent
->oversize_left
= oversize
;
480 #endif /* TCP_OVERSIZE_DBGCHECK */
481 TCP_DATA_COPY2(concat_p
->payload
, (u8_t
*)arg
+ pos
, seglen
, &concat_chksum
, &concat_chksum_swapped
);
482 #if TCP_CHECKSUM_ON_COPY
483 concat_chksummed
+= seglen
;
484 #endif /* TCP_CHECKSUM_ON_COPY */
486 /* Data is not copied */
487 if ((concat_p
= pbuf_alloc(PBUF_RAW
, seglen
, PBUF_ROM
)) == NULL
) {
488 LWIP_DEBUGF(TCP_OUTPUT_DEBUG
| 2,
489 ("tcp_write: could not allocate memory for zero-copy pbuf\n"));
492 #if TCP_CHECKSUM_ON_COPY
493 /* calculate the checksum of nocopy-data */
494 tcp_seg_add_chksum(~inet_chksum((u8_t
*)arg
+ pos
, seglen
), seglen
,
495 &concat_chksum
, &concat_chksum_swapped
);
496 concat_chksummed
+= seglen
;
497 #endif /* TCP_CHECKSUM_ON_COPY */
498 /* reference the non-volatile payload data */
499 concat_p
->payload
= (u8_t
*)arg
+ pos
;
503 queuelen
+= pbuf_clen(concat_p
);
507 LWIP_ASSERT("unsent_oversize mismatch (pcb->unsent is NULL)",
508 pcb
->unsent_oversize
== 0);
509 #endif /* TCP_OVERSIZE */
513 * Phase 3: Create new segments.
515 * The new segments are chained together in the local 'queue'
516 * variable, ready to be appended to pcb->unsent.
520 u16_t left
= len
- pos
;
521 u16_t max_len
= pcb
->mss
- optlen
;
522 u16_t seglen
= left
> max_len
? max_len
: left
;
523 #if TCP_CHECKSUM_ON_COPY
525 u8_t chksum_swapped
= 0;
526 #endif /* TCP_CHECKSUM_ON_COPY */
528 if (apiflags
& TCP_WRITE_FLAG_COPY
) {
529 /* If copy is set, memory should be allocated and data copied
531 if ((p
= tcp_pbuf_prealloc(PBUF_TRANSPORT
, seglen
+ optlen
, pcb
->mss
, &oversize
, pcb
, apiflags
, queue
== NULL
)) == NULL
) {
532 LWIP_DEBUGF(TCP_OUTPUT_DEBUG
| 2, ("tcp_write : could not allocate memory for pbuf copy size %"U16_F
"\n", seglen
));
535 LWIP_ASSERT("tcp_write: check that first pbuf can hold the complete seglen",
537 TCP_DATA_COPY2((char *)p
->payload
+ optlen
, (u8_t
*)arg
+ pos
, seglen
, &chksum
, &chksum_swapped
);
539 /* Copy is not set: First allocate a pbuf for holding the data.
540 * Since the referenced data is available at least until it is
541 * sent out on the link (as it has to be ACKed by the remote
542 * party) we can safely use PBUF_ROM instead of PBUF_REF here.
546 LWIP_ASSERT("oversize == 0", oversize
== 0);
547 #endif /* TCP_OVERSIZE */
548 if ((p2
= pbuf_alloc(PBUF_TRANSPORT
, seglen
, PBUF_ROM
)) == NULL
) {
549 LWIP_DEBUGF(TCP_OUTPUT_DEBUG
| 2, ("tcp_write: could not allocate memory for zero-copy pbuf\n"));
552 #if TCP_CHECKSUM_ON_COPY
553 /* calculate the checksum of nocopy-data */
554 chksum
= ~inet_chksum((u8_t
*)arg
+ pos
, seglen
);
555 #endif /* TCP_CHECKSUM_ON_COPY */
556 /* reference the non-volatile payload data */
557 p2
->payload
= (u8_t
*)arg
+ pos
;
559 /* Second, allocate a pbuf for the headers. */
560 if ((p
= pbuf_alloc(PBUF_TRANSPORT
, optlen
, PBUF_RAM
)) == NULL
) {
561 /* If allocation fails, we have to deallocate the data pbuf as
564 LWIP_DEBUGF(TCP_OUTPUT_DEBUG
| 2, ("tcp_write: could not allocate memory for header pbuf\n"));
567 /* Concatenate the headers and data pbufs together. */
568 pbuf_cat(p
/*header*/, p2
/*data*/);
571 queuelen
+= pbuf_clen(p
);
573 /* Now that there are more segments queued, we check again if the
574 * length of the queue exceeds the configured maximum or
576 if ((queuelen
> TCP_SND_QUEUELEN
) || (queuelen
> TCP_SNDQUEUELEN_OVERFLOW
)) {
577 LWIP_DEBUGF(TCP_OUTPUT_DEBUG
| 2, ("tcp_write: queue too long %"U16_F
" (%"U16_F
")\n", queuelen
, TCP_SND_QUEUELEN
));
582 if ((seg
= tcp_create_segment(pcb
, p
, 0, pcb
->snd_lbb
+ pos
, optflags
)) == NULL
) {
585 #if TCP_OVERSIZE_DBGCHECK
586 seg
->oversize_left
= oversize
;
587 #endif /* TCP_OVERSIZE_DBGCHECK */
588 #if TCP_CHECKSUM_ON_COPY
589 seg
->chksum
= chksum
;
590 seg
->chksum_swapped
= chksum_swapped
;
591 seg
->flags
|= TF_SEG_DATA_CHECKSUMMED
;
592 #endif /* TCP_CHECKSUM_ON_COPY */
593 /* Fix dataptr for the nocopy case */
594 if ((apiflags
& TCP_WRITE_FLAG_COPY
) == 0) {
595 seg
->dataptr
= (u8_t
*)arg
+ pos
;
598 /* first segment of to-be-queued data? */
602 /* Attach the segment to the end of the queued segments */
603 LWIP_ASSERT("prev_seg != NULL", prev_seg
!= NULL
);
604 prev_seg
->next
= seg
;
606 /* remember last segment of to-be-queued data for next iteration */
609 LWIP_DEBUGF(TCP_OUTPUT_DEBUG
| LWIP_DBG_TRACE
, ("tcp_write: queueing %"U32_F
":%"U32_F
"\n",
610 ntohl(seg
->tcphdr
->seqno
),
611 ntohl(seg
->tcphdr
->seqno
) + TCP_TCPLEN(seg
)));
617 * All three segmentation phases were successful. We can commit the
622 * Phase 1: If data has been added to the preallocated tail of
623 * last_unsent, we update the length fields of the pbuf chain.
626 if (oversize_used
> 0) {
628 /* Bump tot_len of whole chain, len of tail */
629 for (p
= last_unsent
->p
; p
; p
= p
->next
) {
630 p
->tot_len
+= oversize_used
;
631 if (p
->next
== NULL
) {
632 TCP_DATA_COPY((char *)p
->payload
+ p
->len
, arg
, oversize_used
, last_unsent
);
633 p
->len
+= oversize_used
;
636 last_unsent
->len
+= oversize_used
;
637 #if TCP_OVERSIZE_DBGCHECK
638 last_unsent
->oversize_left
-= oversize_used
;
639 #endif /* TCP_OVERSIZE_DBGCHECK */
641 pcb
->unsent_oversize
= oversize
;
642 #endif /* TCP_OVERSIZE */
645 * Phase 2: concat_p can be concatenated onto last_unsent->p
647 if (concat_p
!= NULL
) {
648 LWIP_ASSERT("tcp_write: cannot concatenate when pcb->unsent is empty",
649 (last_unsent
!= NULL
));
650 pbuf_cat(last_unsent
->p
, concat_p
);
651 last_unsent
->len
+= concat_p
->tot_len
;
652 #if TCP_CHECKSUM_ON_COPY
653 if (concat_chksummed
) {
654 tcp_seg_add_chksum(concat_chksum
, concat_chksummed
, &last_unsent
->chksum
,
655 &last_unsent
->chksum_swapped
);
656 last_unsent
->flags
|= TF_SEG_DATA_CHECKSUMMED
;
658 #endif /* TCP_CHECKSUM_ON_COPY */
662 * Phase 3: Append queue to pcb->unsent. Queue may be NULL, but that
665 if (last_unsent
== NULL
) {
668 last_unsent
->next
= queue
;
672 * Finally update the pcb state.
676 pcb
->snd_queuelen
= queuelen
;
678 LWIP_DEBUGF(TCP_QLEN_DEBUG
, ("tcp_write: %"S16_F
" (after enqueued)\n",
680 if (pcb
->snd_queuelen
!= 0) {
681 LWIP_ASSERT("tcp_write: valid queue length",
682 pcb
->unacked
!= NULL
|| pcb
->unsent
!= NULL
);
685 /* Set the PSH flag in the last segment that we enqueued. */
686 if (seg
!= NULL
&& seg
->tcphdr
!= NULL
&& ((apiflags
& TCP_WRITE_FLAG_MORE
)==0)) {
687 TCPH_SET_FLAG(seg
->tcphdr
, TCP_PSH
);
692 pcb
->flags
|= TF_NAGLEMEMERR
;
693 TCP_STATS_INC(tcp
.memerr
);
695 if (concat_p
!= NULL
) {
699 tcp_segs_free(queue
);
701 if (pcb
->snd_queuelen
!= 0) {
702 LWIP_ASSERT("tcp_write: valid queue length", pcb
->unacked
!= NULL
||
703 pcb
->unsent
!= NULL
);
705 LWIP_DEBUGF(TCP_QLEN_DEBUG
| LWIP_DBG_STATE
, ("tcp_write: %"S16_F
" (with mem err)\n", pcb
->snd_queuelen
));
710 * Enqueue TCP options for transmission.
712 * Called by tcp_connect(), tcp_listen_input(), and tcp_send_ctrl().
714 * @param pcb Protocol control block for the TCP connection.
715 * @param flags TCP header flags to set in the outgoing segment.
716 * @param optdata pointer to TCP options, or NULL.
717 * @param optlen length of TCP options in bytes.
720 tcp_enqueue_flags(struct tcp_pcb
*pcb
, u8_t flags
)
727 LWIP_DEBUGF(TCP_QLEN_DEBUG
, ("tcp_enqueue_flags: queuelen: %"U16_F
"\n", (u16_t
)pcb
->snd_queuelen
));
729 LWIP_ASSERT("tcp_enqueue_flags: need either TCP_SYN or TCP_FIN in flags (programmer violates API)",
730 (flags
& (TCP_SYN
| TCP_FIN
)) != 0);
732 /* check for configured max queuelen and possible overflow */
733 if ((pcb
->snd_queuelen
>= TCP_SND_QUEUELEN
) || (pcb
->snd_queuelen
> TCP_SNDQUEUELEN_OVERFLOW
)) {
734 LWIP_DEBUGF(TCP_OUTPUT_DEBUG
| 3, ("tcp_enqueue_flags: too long queue %"U16_F
" (max %"U16_F
")\n",
735 pcb
->snd_queuelen
, TCP_SND_QUEUELEN
));
736 TCP_STATS_INC(tcp
.memerr
);
737 pcb
->flags
|= TF_NAGLEMEMERR
;
741 if (flags
& TCP_SYN
) {
742 optflags
= TF_SEG_OPTS_MSS
;
744 #if LWIP_TCP_TIMESTAMPS
745 if ((pcb
->flags
& TF_TIMESTAMP
)) {
746 optflags
|= TF_SEG_OPTS_TS
;
748 #endif /* LWIP_TCP_TIMESTAMPS */
749 optlen
= LWIP_TCP_OPT_LENGTH(optflags
);
751 /* tcp_enqueue_flags is always called with either SYN or FIN in flags.
752 * We need one available snd_buf byte to do that.
753 * This means we can't send FIN while snd_buf==0. A better fix would be to
754 * not include SYN and FIN sequence numbers in the snd_buf count. */
755 if (pcb
->snd_buf
== 0) {
756 LWIP_DEBUGF(TCP_OUTPUT_DEBUG
| 3, ("tcp_enqueue_flags: no send buffer available\n"));
757 TCP_STATS_INC(tcp
.memerr
);
761 /* Allocate pbuf with room for TCP header + options */
762 if ((p
= pbuf_alloc(PBUF_TRANSPORT
, optlen
, PBUF_RAM
)) == NULL
) {
763 pcb
->flags
|= TF_NAGLEMEMERR
;
764 TCP_STATS_INC(tcp
.memerr
);
767 LWIP_ASSERT("tcp_enqueue_flags: check that first pbuf can hold optlen",
770 /* Allocate memory for tcp_seg, and fill in fields. */
771 if ((seg
= tcp_create_segment(pcb
, p
, flags
, pcb
->snd_lbb
, optflags
)) == NULL
) {
772 pcb
->flags
|= TF_NAGLEMEMERR
;
773 TCP_STATS_INC(tcp
.memerr
);
776 LWIP_ASSERT("tcp_enqueue_flags: invalid segment length", seg
->len
== 0);
778 LWIP_DEBUGF(TCP_OUTPUT_DEBUG
| LWIP_DBG_TRACE
,
779 ("tcp_enqueue_flags: queueing %"U32_F
":%"U32_F
" (0x%"X16_F
")\n",
780 ntohl(seg
->tcphdr
->seqno
),
781 ntohl(seg
->tcphdr
->seqno
) + TCP_TCPLEN(seg
),
784 /* Now append seg to pcb->unsent queue */
785 if (pcb
->unsent
== NULL
) {
788 struct tcp_seg
*useg
;
789 for (useg
= pcb
->unsent
; useg
->next
!= NULL
; useg
= useg
->next
);
793 /* The new unsent tail has no space */
794 pcb
->unsent_oversize
= 0;
795 #endif /* TCP_OVERSIZE */
797 /* SYN and FIN bump the sequence number */
798 if ((flags
& TCP_SYN
) || (flags
& TCP_FIN
)) {
800 /* optlen does not influence snd_buf */
803 if (flags
& TCP_FIN
) {
804 pcb
->flags
|= TF_FIN
;
807 /* update number of segments on the queues */
808 pcb
->snd_queuelen
+= pbuf_clen(seg
->p
);
809 LWIP_DEBUGF(TCP_QLEN_DEBUG
, ("tcp_enqueue_flags: %"S16_F
" (after enqueued)\n", pcb
->snd_queuelen
));
810 if (pcb
->snd_queuelen
!= 0) {
811 LWIP_ASSERT("tcp_enqueue_flags: invalid queue length",
812 pcb
->unacked
!= NULL
|| pcb
->unsent
!= NULL
);
819 #if LWIP_TCP_TIMESTAMPS
820 /* Build a timestamp option (12 bytes long) at the specified options pointer)
823 * @param opts option pointer where to store the timestamp option
826 tcp_build_timestamp_option(struct tcp_pcb
*pcb
, u32_t
*opts
)
828 /* Pad with two NOP options to make everything nicely aligned */
829 opts
[0] = PP_HTONL(0x0101080A);
830 opts
[1] = htonl(sys_now());
831 opts
[2] = htonl(pcb
->ts_recent
);
835 /** Send an ACK without data.
837 * @param pcb Protocol control block for the TCP connection to send the ACK
840 tcp_send_empty_ack(struct tcp_pcb
*pcb
)
843 struct tcp_hdr
*tcphdr
;
846 #if LWIP_TCP_TIMESTAMPS
847 if (pcb
->flags
& TF_TIMESTAMP
) {
848 optlen
= LWIP_TCP_OPT_LENGTH(TF_SEG_OPTS_TS
);
852 p
= tcp_output_alloc_header(pcb
, optlen
, 0, htonl(pcb
->snd_nxt
));
854 LWIP_DEBUGF(TCP_OUTPUT_DEBUG
, ("tcp_output: (ACK) could not allocate pbuf\n"));
857 tcphdr
= (struct tcp_hdr
*)p
->payload
;
858 LWIP_DEBUGF(TCP_OUTPUT_DEBUG
,
859 ("tcp_output: sending ACK for %"U32_F
"\n", pcb
->rcv_nxt
));
860 /* remove ACK flags from the PCB, as we send an empty ACK now */
861 pcb
->flags
&= ~(TF_ACK_DELAY
| TF_ACK_NOW
);
863 /* NB. MSS option is only sent on SYNs, so ignore it here */
864 #if LWIP_TCP_TIMESTAMPS
865 pcb
->ts_lastacksent
= pcb
->rcv_nxt
;
867 if (pcb
->flags
& TF_TIMESTAMP
) {
868 tcp_build_timestamp_option(pcb
, (u32_t
*)(tcphdr
+ 1));
873 tcphdr
->chksum
= inet_chksum_pseudo(p
, &(pcb
->local_ip
), &(pcb
->remote_ip
),
874 IP_PROTO_TCP
, p
->tot_len
);
876 #if LWIP_NETIF_HWADDRHINT
877 ip_output_hinted(p
, &(pcb
->local_ip
), &(pcb
->remote_ip
), pcb
->ttl
, pcb
->tos
,
878 IP_PROTO_TCP
, &(pcb
->addr_hint
));
879 #else /* LWIP_NETIF_HWADDRHINT*/
880 ip_output(p
, &(pcb
->local_ip
), &(pcb
->remote_ip
), pcb
->ttl
, pcb
->tos
,
882 #endif /* LWIP_NETIF_HWADDRHINT*/
889 * Find out what we can send and send it
891 * @param pcb Protocol control block for the TCP connection to send data
892 * @return ERR_OK if data has been sent or nothing to send
893 * another err_t on error
896 tcp_output(struct tcp_pcb
*pcb
)
898 struct tcp_seg
*seg
, *useg
;
902 #endif /* TCP_CWND_DEBUG */
904 /* First, check if we are invoked by the TCP input processing
905 code. If so, we do not output anything. Instead, we rely on the
906 input processing code to call us when input processing is done
908 if (tcp_input_pcb
== pcb
) {
912 wnd
= LWIP_MIN(pcb
->snd_wnd
, pcb
->cwnd
);
916 /* If the TF_ACK_NOW flag is set and no data will be sent (either
917 * because the ->unsent queue is empty or because the window does
918 * not allow it), construct an empty ACK segment and send it.
920 * If data is to be sent, we will just piggyback the ACK (see below).
922 if (pcb
->flags
& TF_ACK_NOW
&&
924 ntohl(seg
->tcphdr
->seqno
) - pcb
->lastack
+ seg
->len
> wnd
)) {
925 return tcp_send_empty_ack(pcb
);
928 /* useg should point to last segment on unacked queue */
931 for (; useg
->next
!= NULL
; useg
= useg
->next
);
936 LWIP_DEBUGF(TCP_OUTPUT_DEBUG
, ("tcp_output: nothing to send (%p)\n",
937 (void*)pcb
->unsent
));
939 #endif /* TCP_OUTPUT_DEBUG */
942 LWIP_DEBUGF(TCP_CWND_DEBUG
, ("tcp_output: snd_wnd %"U16_F
943 ", cwnd %"U16_F
", wnd %"U32_F
944 ", seg == NULL, ack %"U32_F
"\n",
945 pcb
->snd_wnd
, pcb
->cwnd
, wnd
, pcb
->lastack
));
947 LWIP_DEBUGF(TCP_CWND_DEBUG
,
948 ("tcp_output: snd_wnd %"U16_F
", cwnd %"U16_F
", wnd %"U32_F
949 ", effwnd %"U32_F
", seq %"U32_F
", ack %"U32_F
"\n",
950 pcb
->snd_wnd
, pcb
->cwnd
, wnd
,
951 ntohl(seg
->tcphdr
->seqno
) - pcb
->lastack
+ seg
->len
,
952 ntohl(seg
->tcphdr
->seqno
), pcb
->lastack
));
954 #endif /* TCP_CWND_DEBUG */
955 /* data available and window allows it to be sent? */
956 while (seg
!= NULL
&&
957 ntohl(seg
->tcphdr
->seqno
) - pcb
->lastack
+ seg
->len
<= wnd
) {
958 LWIP_ASSERT("RST not expected here!",
959 (TCPH_FLAGS(seg
->tcphdr
) & TCP_RST
) == 0);
960 /* Stop sending if the nagle algorithm would prevent it
962 * - if tcp_write had a memory error before (prevent delayed ACK timeout) or
963 * - if FIN was already enqueued for this PCB (SYN is always alone in a segment -
964 * either seg->next != NULL or pcb->unacked == NULL;
965 * RST is no sent using tcp_write/tcp_output.
967 if((tcp_do_output_nagle(pcb
) == 0) &&
968 ((pcb
->flags
& (TF_NAGLEMEMERR
| TF_FIN
)) == 0)){
972 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",
973 pcb
->snd_wnd
, pcb
->cwnd
, wnd
,
974 ntohl(seg
->tcphdr
->seqno
) + seg
->len
-
976 ntohl(seg
->tcphdr
->seqno
), pcb
->lastack
, i
));
978 #endif /* TCP_CWND_DEBUG */
980 pcb
->unsent
= seg
->next
;
982 if (pcb
->state
!= SYN_SENT
) {
983 TCPH_SET_FLAG(seg
->tcphdr
, TCP_ACK
);
984 pcb
->flags
&= ~(TF_ACK_DELAY
| TF_ACK_NOW
);
987 tcp_output_segment(seg
, pcb
);
988 snd_nxt
= ntohl(seg
->tcphdr
->seqno
) + TCP_TCPLEN(seg
);
989 if (TCP_SEQ_LT(pcb
->snd_nxt
, snd_nxt
)) {
990 pcb
->snd_nxt
= snd_nxt
;
992 /* put segment on unacknowledged list if length > 0 */
993 if (TCP_TCPLEN(seg
) > 0) {
995 /* unacked list is empty? */
996 if (pcb
->unacked
== NULL
) {
999 /* unacked list is not empty? */
1001 /* In the case of fast retransmit, the packet should not go to the tail
1002 * of the unacked queue, but rather somewhere before it. We need to check for
1003 * this case. -STJ Jul 27, 2004 */
1004 if (TCP_SEQ_LT(ntohl(seg
->tcphdr
->seqno
), ntohl(useg
->tcphdr
->seqno
))) {
1005 /* add segment to before tail of unacked list, keeping the list sorted */
1006 struct tcp_seg
**cur_seg
= &(pcb
->unacked
);
1008 TCP_SEQ_LT(ntohl((*cur_seg
)->tcphdr
->seqno
), ntohl(seg
->tcphdr
->seqno
))) {
1009 cur_seg
= &((*cur_seg
)->next
);
1011 seg
->next
= (*cur_seg
);
1014 /* add segment to tail of unacked list */
1019 /* do not queue empty segments on the unacked list */
1026 if (pcb
->unsent
== NULL
) {
1027 /* last unsent has been removed, reset unsent_oversize */
1028 pcb
->unsent_oversize
= 0;
1030 #endif /* TCP_OVERSIZE */
1032 if (seg
!= NULL
&& pcb
->persist_backoff
== 0 &&
1033 ntohl(seg
->tcphdr
->seqno
) - pcb
->lastack
+ seg
->len
> pcb
->snd_wnd
) {
1034 /* prepare for persist timer */
1035 pcb
->persist_cnt
= 0;
1036 pcb
->persist_backoff
= 1;
1039 pcb
->flags
&= ~TF_NAGLEMEMERR
;
1044 * Called by tcp_output() to actually send a TCP segment over IP.
1046 * @param seg the tcp_seg to send
1047 * @param pcb the tcp_pcb for the TCP connection used to send the segment
1050 tcp_output_segment(struct tcp_seg
*seg
, struct tcp_pcb
*pcb
)
1053 struct netif
*netif
;
1056 /** @bug Exclude retransmitted segments from this count. */
1057 snmp_inc_tcpoutsegs();
1059 /* The TCP header has already been constructed, but the ackno and
1060 wnd fields remain. */
1061 seg
->tcphdr
->ackno
= htonl(pcb
->rcv_nxt
);
1063 /* advertise our receive window size in this TCP segment */
1064 seg
->tcphdr
->wnd
= htons(pcb
->rcv_ann_wnd
);
1066 pcb
->rcv_ann_right_edge
= pcb
->rcv_nxt
+ pcb
->rcv_ann_wnd
;
1068 /* Add any requested options. NB MSS option is only set on SYN
1069 packets, so ignore it here */
1070 LWIP_ASSERT("seg->tcphdr not aligned", ((mem_ptr_t
)(seg
->tcphdr
+ 1) % 4) == 0);
1071 opts
= (u32_t
*)(void *)(seg
->tcphdr
+ 1);
1072 if (seg
->flags
& TF_SEG_OPTS_MSS
) {
1073 TCP_BUILD_MSS_OPTION(*opts
);
1076 #if LWIP_TCP_TIMESTAMPS
1077 pcb
->ts_lastacksent
= pcb
->rcv_nxt
;
1079 if (seg
->flags
& TF_SEG_OPTS_TS
) {
1080 tcp_build_timestamp_option(pcb
, opts
);
1085 /* If we don't have a local IP address, we get one by
1086 calling ip_route(). */
1087 if (ip_addr_isany(&(pcb
->local_ip
))) {
1088 netif
= ip_route(&(pcb
->remote_ip
));
1089 if (netif
== NULL
) {
1092 ip_addr_copy(pcb
->local_ip
, netif
->ip_addr
);
1095 /* Set retransmission timer running if it is not currently enabled */
1096 if(pcb
->rtime
== -1) {
1100 if (pcb
->rttest
== 0) {
1101 pcb
->rttest
= tcp_ticks
;
1102 pcb
->rtseq
= ntohl(seg
->tcphdr
->seqno
);
1104 LWIP_DEBUGF(TCP_RTO_DEBUG
, ("tcp_output_segment: rtseq %"U32_F
"\n", pcb
->rtseq
));
1106 LWIP_DEBUGF(TCP_OUTPUT_DEBUG
, ("tcp_output_segment: %"U32_F
":%"U32_F
"\n",
1107 htonl(seg
->tcphdr
->seqno
), htonl(seg
->tcphdr
->seqno
) +
1110 len
= (u16_t
)((u8_t
*)seg
->tcphdr
- (u8_t
*)seg
->p
->payload
);
1113 seg
->p
->tot_len
-= len
;
1115 seg
->p
->payload
= seg
->tcphdr
;
1117 seg
->tcphdr
->chksum
= 0;
1118 #if CHECKSUM_GEN_TCP
1119 #if TCP_CHECKSUM_ON_COPY
1122 #if TCP_CHECKSUM_ON_COPY_SANITY_CHECK
1123 u16_t chksum_slow
= inet_chksum_pseudo(seg
->p
, &(pcb
->local_ip
),
1125 IP_PROTO_TCP
, seg
->p
->tot_len
);
1126 #endif /* TCP_CHECKSUM_ON_COPY_SANITY_CHECK */
1127 if ((seg
->flags
& TF_SEG_DATA_CHECKSUMMED
) == 0) {
1128 LWIP_ASSERT("data included but not checksummed",
1129 seg
->p
->tot_len
== (TCPH_HDRLEN(seg
->tcphdr
) * 4));
1132 /* rebuild TCP header checksum (TCP header changes for retransmissions!) */
1133 acc
= inet_chksum_pseudo_partial(seg
->p
, &(pcb
->local_ip
),
1135 IP_PROTO_TCP
, seg
->p
->tot_len
, TCPH_HDRLEN(seg
->tcphdr
) * 4);
1136 /* add payload checksum */
1137 if (seg
->chksum_swapped
) {
1138 seg
->chksum
= SWAP_BYTES_IN_WORD(seg
->chksum
);
1139 seg
->chksum_swapped
= 0;
1141 acc
+= (u16_t
)~(seg
->chksum
);
1142 seg
->tcphdr
->chksum
= FOLD_U32T(acc
);
1143 #if TCP_CHECKSUM_ON_COPY_SANITY_CHECK
1144 if (chksum_slow
!= seg
->tcphdr
->chksum
) {
1145 LWIP_DEBUGF(TCP_DEBUG
| LWIP_DBG_LEVEL_WARNING
,
1146 ("tcp_output_segment: calculated checksum is %"X16_F
" instead of %"X16_F
"\n",
1147 seg
->tcphdr
->chksum
, chksum_slow
));
1148 seg
->tcphdr
->chksum
= chksum_slow
;
1150 #endif /* TCP_CHECKSUM_ON_COPY_SANITY_CHECK */
1152 #else /* TCP_CHECKSUM_ON_COPY */
1153 seg
->tcphdr
->chksum
= inet_chksum_pseudo(seg
->p
, &(pcb
->local_ip
),
1155 IP_PROTO_TCP
, seg
->p
->tot_len
);
1156 #endif /* TCP_CHECKSUM_ON_COPY */
1157 #endif /* CHECKSUM_GEN_TCP */
1158 TCP_STATS_INC(tcp
.xmit
);
1160 #if LWIP_NETIF_HWADDRHINT
1161 ip_output_hinted(seg
->p
, &(pcb
->local_ip
), &(pcb
->remote_ip
), pcb
->ttl
, pcb
->tos
,
1162 IP_PROTO_TCP
, &(pcb
->addr_hint
));
1163 #else /* LWIP_NETIF_HWADDRHINT*/
1164 ip_output(seg
->p
, &(pcb
->local_ip
), &(pcb
->remote_ip
), pcb
->ttl
, pcb
->tos
,
1166 #endif /* LWIP_NETIF_HWADDRHINT*/
1170 * Send a TCP RESET packet (empty segment with RST flag set) either to
1171 * abort a connection or to show that there is no matching local connection
1172 * for a received segment.
1174 * Called by tcp_abort() (to abort a local connection), tcp_input() (if no
1175 * matching local pcb was found), tcp_listen_input() (if incoming segment
1176 * has ACK flag set) and tcp_process() (received segment in the wrong state)
1178 * Since a RST segment is in most cases not sent for an active connection,
1179 * tcp_rst() has a number of arguments that are taken from a tcp_pcb for
1180 * most other segment output functions.
1182 * @param seqno the sequence number to use for the outgoing segment
1183 * @param ackno the acknowledge number to use for the outgoing segment
1184 * @param local_ip the local IP address to send the segment from
1185 * @param remote_ip the remote IP address to send the segment to
1186 * @param local_port the local TCP port to send the segment from
1187 * @param remote_port the remote TCP port to send the segment to
1190 tcp_rst(u32_t seqno
, u32_t ackno
,
1191 ip_addr_t
*local_ip
, ip_addr_t
*remote_ip
,
1192 u16_t local_port
, u16_t remote_port
)
1195 struct tcp_hdr
*tcphdr
;
1196 p
= pbuf_alloc(PBUF_IP
, TCP_HLEN
, PBUF_RAM
);
1198 LWIP_DEBUGF(TCP_DEBUG
, ("tcp_rst: could not allocate memory for pbuf\n"));
1201 LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr",
1202 (p
->len
>= sizeof(struct tcp_hdr
)));
1204 tcphdr
= (struct tcp_hdr
*)p
->payload
;
1205 tcphdr
->src
= htons(local_port
);
1206 tcphdr
->dest
= htons(remote_port
);
1207 tcphdr
->seqno
= htonl(seqno
);
1208 tcphdr
->ackno
= htonl(ackno
);
1209 TCPH_HDRLEN_FLAGS_SET(tcphdr
, TCP_HLEN
/4, TCP_RST
| TCP_ACK
);
1210 tcphdr
->wnd
= PP_HTONS(TCP_WND
);
1214 #if CHECKSUM_GEN_TCP
1215 tcphdr
->chksum
= inet_chksum_pseudo(p
, local_ip
, remote_ip
,
1216 IP_PROTO_TCP
, p
->tot_len
);
1218 TCP_STATS_INC(tcp
.xmit
);
1219 snmp_inc_tcpoutrsts();
1220 /* Send output with hardcoded TTL since we have no access to the pcb */
1221 ip_output(p
, local_ip
, remote_ip
, TCP_TTL
, 0, IP_PROTO_TCP
);
1223 LWIP_DEBUGF(TCP_RST_DEBUG
, ("tcp_rst: seqno %"U32_F
" ackno %"U32_F
".\n", seqno
, ackno
));
1227 * Requeue all unacked segments for retransmission
1229 * Called by tcp_slowtmr() for slow retransmission.
1231 * @param pcb the tcp_pcb for which to re-enqueue all unacked segments
1234 tcp_rexmit_rto(struct tcp_pcb
*pcb
)
1236 struct tcp_seg
*seg
;
1238 if (pcb
->unacked
== NULL
) {
1242 /* Move all unacked segments to the head of the unsent queue */
1243 for (seg
= pcb
->unacked
; seg
->next
!= NULL
; seg
= seg
->next
);
1244 /* concatenate unsent queue after unacked queue */
1245 seg
->next
= pcb
->unsent
;
1246 /* unsent queue is the concatenated queue (of unacked, unsent) */
1247 pcb
->unsent
= pcb
->unacked
;
1248 /* unacked queue is now empty */
1249 pcb
->unacked
= NULL
;
1251 /* increment number of retransmissions */
1254 /* Don't take any RTT measurements after retransmitting. */
1257 /* Do the actual retransmission */
1262 * Requeue the first unacked segment for retransmission
1264 * Called by tcp_receive() for fast retramsmit.
1266 * @param pcb the tcp_pcb for which to retransmit the first unacked segment
1269 tcp_rexmit(struct tcp_pcb
*pcb
)
1271 struct tcp_seg
*seg
;
1272 struct tcp_seg
**cur_seg
;
1274 if (pcb
->unacked
== NULL
) {
1278 /* Move the first unacked segment to the unsent queue */
1279 /* Keep the unsent queue sorted. */
1281 pcb
->unacked
= seg
->next
;
1283 cur_seg
= &(pcb
->unsent
);
1285 TCP_SEQ_LT(ntohl((*cur_seg
)->tcphdr
->seqno
), ntohl(seg
->tcphdr
->seqno
))) {
1286 cur_seg
= &((*cur_seg
)->next
);
1288 seg
->next
= *cur_seg
;
1293 /* Don't take any rtt measurements after retransmitting. */
1296 /* Do the actual retransmission. */
1297 snmp_inc_tcpretranssegs();
1298 /* No need to call tcp_output: we are always called from tcp_input()
1299 and thus tcp_output directly returns. */
1304 * Handle retransmission after three dupacks received
1306 * @param pcb the tcp_pcb for which to retransmit the first unacked segment
1309 tcp_rexmit_fast(struct tcp_pcb
*pcb
)
1311 if (pcb
->unacked
!= NULL
&& !(pcb
->flags
& TF_INFR
)) {
1312 /* This is fast retransmit. Retransmit the first unacked segment. */
1313 LWIP_DEBUGF(TCP_FR_DEBUG
,
1314 ("tcp_receive: dupacks %"U16_F
" (%"U32_F
1315 "), fast retransmit %"U32_F
"\n",
1316 (u16_t
)pcb
->dupacks
, pcb
->lastack
,
1317 ntohl(pcb
->unacked
->tcphdr
->seqno
)));
1320 /* Set ssthresh to half of the minimum of the current
1321 * cwnd and the advertised window */
1322 if (pcb
->cwnd
> pcb
->snd_wnd
) {
1323 pcb
->ssthresh
= pcb
->snd_wnd
/ 2;
1325 pcb
->ssthresh
= pcb
->cwnd
/ 2;
1328 /* The minimum value for ssthresh should be 2 MSS */
1329 if (pcb
->ssthresh
< 2*pcb
->mss
) {
1330 LWIP_DEBUGF(TCP_FR_DEBUG
,
1331 ("tcp_receive: The minimum value for ssthresh %"U16_F
1332 " should be min 2 mss %"U16_F
"...\n",
1333 pcb
->ssthresh
, 2*pcb
->mss
));
1334 pcb
->ssthresh
= 2*pcb
->mss
;
1337 pcb
->cwnd
= pcb
->ssthresh
+ 3 * pcb
->mss
;
1338 pcb
->flags
|= TF_INFR
;
1344 * Send keepalive packets to keep a connection active although
1345 * no data is sent over it.
1347 * Called by tcp_slowtmr()
1349 * @param pcb the tcp_pcb for which to send a keepalive packet
1352 tcp_keepalive(struct tcp_pcb
*pcb
)
1355 struct tcp_hdr
*tcphdr
;
1357 LWIP_DEBUGF(TCP_DEBUG
, ("tcp_keepalive: sending KEEPALIVE probe to %"U16_F
".%"U16_F
".%"U16_F
".%"U16_F
"\n",
1358 ip4_addr1_16(&pcb
->remote_ip
), ip4_addr2_16(&pcb
->remote_ip
),
1359 ip4_addr3_16(&pcb
->remote_ip
), ip4_addr4_16(&pcb
->remote_ip
)));
1361 LWIP_DEBUGF(TCP_DEBUG
, ("tcp_keepalive: tcp_ticks %"U32_F
" pcb->tmr %"U32_F
" pcb->keep_cnt_sent %"U16_F
"\n",
1362 tcp_ticks
, pcb
->tmr
, pcb
->keep_cnt_sent
));
1364 p
= tcp_output_alloc_header(pcb
, 0, 0, htonl(pcb
->snd_nxt
- 1));
1366 LWIP_DEBUGF(TCP_DEBUG
,
1367 ("tcp_keepalive: could not allocate memory for pbuf\n"));
1370 tcphdr
= (struct tcp_hdr
*)p
->payload
;
1372 #if CHECKSUM_GEN_TCP
1373 tcphdr
->chksum
= inet_chksum_pseudo(p
, &pcb
->local_ip
, &pcb
->remote_ip
,
1374 IP_PROTO_TCP
, p
->tot_len
);
1376 TCP_STATS_INC(tcp
.xmit
);
1378 /* Send output to IP */
1379 #if LWIP_NETIF_HWADDRHINT
1380 ip_output_hinted(p
, &pcb
->local_ip
, &pcb
->remote_ip
, pcb
->ttl
, 0, IP_PROTO_TCP
,
1382 #else /* LWIP_NETIF_HWADDRHINT*/
1383 ip_output(p
, &pcb
->local_ip
, &pcb
->remote_ip
, pcb
->ttl
, 0, IP_PROTO_TCP
);
1384 #endif /* LWIP_NETIF_HWADDRHINT*/
1388 LWIP_DEBUGF(TCP_DEBUG
, ("tcp_keepalive: seqno %"U32_F
" ackno %"U32_F
".\n",
1389 pcb
->snd_nxt
- 1, pcb
->rcv_nxt
));
1394 * Send persist timer zero-window probes to keep a connection active
1395 * when a window update is lost.
1397 * Called by tcp_slowtmr()
1399 * @param pcb the tcp_pcb for which to send a zero-window probe packet
1402 tcp_zero_window_probe(struct tcp_pcb
*pcb
)
1405 struct tcp_hdr
*tcphdr
;
1406 struct tcp_seg
*seg
;
1410 LWIP_DEBUGF(TCP_DEBUG
,
1411 ("tcp_zero_window_probe: sending ZERO WINDOW probe to %"
1412 U16_F
".%"U16_F
".%"U16_F
".%"U16_F
"\n",
1413 ip4_addr1_16(&pcb
->remote_ip
), ip4_addr2_16(&pcb
->remote_ip
),
1414 ip4_addr3_16(&pcb
->remote_ip
), ip4_addr4_16(&pcb
->remote_ip
)));
1416 LWIP_DEBUGF(TCP_DEBUG
,
1417 ("tcp_zero_window_probe: tcp_ticks %"U32_F
1418 " pcb->tmr %"U32_F
" pcb->keep_cnt_sent %"U16_F
"\n",
1419 tcp_ticks
, pcb
->tmr
, pcb
->keep_cnt_sent
));
1430 is_fin
= ((TCPH_FLAGS(seg
->tcphdr
) & TCP_FIN
) != 0) && (seg
->len
== 0);
1431 /* we want to send one seqno: either FIN or data (no options) */
1432 len
= is_fin
? 0 : 1;
1434 p
= tcp_output_alloc_header(pcb
, 0, len
, seg
->tcphdr
->seqno
);
1436 LWIP_DEBUGF(TCP_DEBUG
, ("tcp_zero_window_probe: no memory for pbuf\n"));
1439 tcphdr
= (struct tcp_hdr
*)p
->payload
;
1442 /* FIN segment, no data */
1443 TCPH_FLAGS_SET(tcphdr
, TCP_ACK
| TCP_FIN
);
1445 /* Data segment, copy in one byte from the head of the unacked queue */
1446 *((char *)p
->payload
+ TCP_HLEN
) = *(char *)seg
->dataptr
;
1449 #if CHECKSUM_GEN_TCP
1450 tcphdr
->chksum
= inet_chksum_pseudo(p
, &pcb
->local_ip
, &pcb
->remote_ip
,
1451 IP_PROTO_TCP
, p
->tot_len
);
1453 TCP_STATS_INC(tcp
.xmit
);
1455 /* Send output to IP */
1456 #if LWIP_NETIF_HWADDRHINT
1457 ip_output_hinted(p
, &pcb
->local_ip
, &pcb
->remote_ip
, pcb
->ttl
, 0, IP_PROTO_TCP
,
1459 #else /* LWIP_NETIF_HWADDRHINT*/
1460 ip_output(p
, &pcb
->local_ip
, &pcb
->remote_ip
, pcb
->ttl
, 0, IP_PROTO_TCP
);
1461 #endif /* LWIP_NETIF_HWADDRHINT*/
1465 LWIP_DEBUGF(TCP_DEBUG
, ("tcp_zero_window_probe: seqno %"U32_F
1466 " ackno %"U32_F
".\n",
1467 pcb
->snd_nxt
- 1, pcb
->rcv_nxt
));
1469 #endif /* LWIP_TCP */