]> Joshua Wise's Git repositories - netwatch.git/blame - lwip/src/core/tcp_out.c
Add TSC checks to measure how much time we spend in SMM.
[netwatch.git] / lwip / src / core / tcp_out.c
CommitLineData
6e6d4a8b
JP
1/**
2 * @file
3 * Transmission Control Protocol, outgoing traffic
4 *
5 * The output functions of TCP.
6 *
7 */
8
9/*
10 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
11 * All rights reserved.
12 *
13 * Redistribution and use in source and binary forms, with or without modification,
14 * are permitted provided that the following conditions are met:
15 *
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.
23 *
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
33 * OF SUCH DAMAGE.
34 *
35 * This file is part of the lwIP TCP/IP stack.
36 *
37 * Author: Adam Dunkels <adam@sics.se>
38 *
39 */
40
41#include "lwip/opt.h"
42
43#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */
44
45#include "lwip/tcp.h"
46#include "lwip/def.h"
47#include "lwip/mem.h"
48#include "lwip/memp.h"
49#include "lwip/sys.h"
50#include "lwip/ip_addr.h"
51#include "lwip/netif.h"
52#include "lwip/inet.h"
53#include "lwip/inet_chksum.h"
54#include "lwip/stats.h"
55#include "lwip/snmp.h"
56
57#include <string.h>
58
59/* Forward declarations.*/
60static void tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb);
61
62/**
63 * Called by tcp_close() to send a segment including flags but not data.
64 *
65 * @param pcb the tcp_pcb over which to send a segment
66 * @param flags the flags to set in the segment header
67 * @return ERR_OK if sent, another err_t otherwise
68 */
69err_t
70tcp_send_ctrl(struct tcp_pcb *pcb, u8_t flags)
71{
72 /* no data, no length, flags, copy=1, no optdata, no optdatalen */
73 return tcp_enqueue(pcb, NULL, 0, flags, TCP_WRITE_FLAG_COPY, NULL, 0);
74}
75
76/**
77 * Write data for sending (but does not send it immediately).
78 *
79 * It waits in the expectation of more data being sent soon (as
80 * it can send them more efficiently by combining them together).
81 * To prompt the system to send data now, call tcp_output() after
82 * calling tcp_write().
83 *
84 * @param pcb Protocol control block of the TCP connection to enqueue data for.
85 * @param data pointer to the data to send
86 * @param len length (in bytes) of the data to send
87 * @param apiflags combination of following flags :
88 * - TCP_WRITE_FLAG_COPY (0x01) data will be copied into memory belonging to the stack
89 * - TCP_WRITE_FLAG_MORE (0x02) for TCP connection, PSH flag will be set on last segment sent,
90 * @return ERR_OK if enqueued, another err_t on error
91 *
92 * @see tcp_write()
93 */
94err_t
95tcp_write(struct tcp_pcb *pcb, const void *data, u16_t len, u8_t apiflags)
96{
97 LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_write(pcb=%p, data=%p, len=%"U16_F", apiflags=%"U16_F")\n", (void *)pcb,
98 data, len, (u16_t)apiflags));
99 /* connection is in valid state for data transmission? */
100 if (pcb->state == ESTABLISHED ||
101 pcb->state == CLOSE_WAIT ||
102 pcb->state == SYN_SENT ||
103 pcb->state == SYN_RCVD) {
104 if (len > 0) {
105 return tcp_enqueue(pcb, (void *)data, len, 0, apiflags, NULL, 0);
106 }
107 return ERR_OK;
108 } else {
109 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_STATE | 3, ("tcp_write() called in invalid state\n"));
110 return ERR_CONN;
111 }
112}
113
114/**
115 * Enqueue either data or TCP options (but not both) for tranmission
116 *
117 * Called by tcp_connect(), tcp_listen_input(), tcp_send_ctrl() and tcp_write().
118 *
119 * @param pcb Protocol control block for the TCP connection to enqueue data for.
120 * @param arg Pointer to the data to be enqueued for sending.
121 * @param len Data length in bytes
122 * @param flags tcp header flags to set in the outgoing segment
123 * @param apiflags combination of following flags :
124 * - TCP_WRITE_FLAG_COPY (0x01) data will be copied into memory belonging to the stack
125 * - TCP_WRITE_FLAG_MORE (0x02) for TCP connection, PSH flag will be set on last segment sent,
126 * @param optdata
127 * @param optlen
128 */
129err_t
130tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
131 u8_t flags, u8_t apiflags,
132 u8_t *optdata, u8_t optlen)
133{
134 struct pbuf *p;
135 struct tcp_seg *seg, *useg, *queue;
136 u32_t seqno;
137 u16_t left, seglen;
138 void *ptr;
139 u16_t queuelen;
140
141 LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_enqueue(pcb=%p, arg=%p, len=%"U16_F", flags=%"X16_F", apiflags=%"U16_F")\n",
142 (void *)pcb, arg, len, (u16_t)flags, (u16_t)apiflags));
143 LWIP_ERROR("tcp_enqueue: len == 0 || optlen == 0 (programmer violates API)",
144 ((len == 0) || (optlen == 0)), return ERR_ARG;);
145 LWIP_ERROR("tcp_enqueue: arg == NULL || optdata == NULL (programmer violates API)",
146 ((arg == NULL) || (optdata == NULL)), return ERR_ARG;);
147 /* fail on too much data */
148 if (len > pcb->snd_buf) {
149 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue: too much data (len=%"U16_F" > snd_buf=%"U16_F")\n", len, pcb->snd_buf));
150 pcb->flags |= TF_NAGLEMEMERR;
151 return ERR_MEM;
152 }
153 left = len;
154 ptr = arg;
155
156 /* seqno will be the sequence number of the first segment enqueued
157 * by the call to this function. */
158 seqno = pcb->snd_lbb;
159
160 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue: queuelen: %"U16_F"\n", (u16_t)pcb->snd_queuelen));
161
162 /* If total number of pbufs on the unsent/unacked queues exceeds the
163 * configured maximum, return an error */
164 queuelen = pcb->snd_queuelen;
165 /* check for configured max queuelen and possible overflow */
166 if ((queuelen >= TCP_SND_QUEUELEN) || (queuelen > TCP_SNDQUEUELEN_OVERFLOW)) {
167 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue: too long queue %"U16_F" (max %"U16_F")\n", queuelen, TCP_SND_QUEUELEN));
168 TCP_STATS_INC(tcp.memerr);
169 pcb->flags |= TF_NAGLEMEMERR;
170 return ERR_MEM;
171 }
172 if (queuelen != 0) {
173 LWIP_ASSERT("tcp_enqueue: pbufs on queue => at least one queue non-empty",
174 pcb->unacked != NULL || pcb->unsent != NULL);
175 } else {
176 LWIP_ASSERT("tcp_enqueue: no pbufs on queue => both queues empty",
177 pcb->unacked == NULL && pcb->unsent == NULL);
178 }
179
180 /* First, break up the data into segments and tuck them together in
181 * the local "queue" variable. */
182 useg = queue = seg = NULL;
183 seglen = 0;
184 while (queue == NULL || left > 0) {
185
186 /* The segment length should be the MSS if the data to be enqueued
187 * is larger than the MSS. */
188 seglen = left > pcb->mss? pcb->mss: left;
189
190 /* Allocate memory for tcp_seg, and fill in fields. */
191 seg = memp_malloc(MEMP_TCP_SEG);
192 if (seg == NULL) {
193 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: could not allocate memory for tcp_seg\n"));
194 goto memerr;
195 }
196 seg->next = NULL;
197 seg->p = NULL;
198
199 /* first segment of to-be-queued data? */
200 if (queue == NULL) {
201 queue = seg;
202 }
203 /* subsequent segments of to-be-queued data */
204 else {
205 /* Attach the segment to the end of the queued segments */
206 LWIP_ASSERT("useg != NULL", useg != NULL);
207 useg->next = seg;
208 }
209 /* remember last segment of to-be-queued data for next iteration */
210 useg = seg;
211
212 /* If copy is set, memory should be allocated
213 * and data copied into pbuf, otherwise data comes from
214 * ROM or other static memory, and need not be copied. If
215 * optdata is != NULL, we have options instead of data. */
216
217 /* options? */
218 if (optdata != NULL) {
219 if ((seg->p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) {
220 goto memerr;
221 }
222 LWIP_ASSERT("check that first pbuf can hold optlen",
223 (seg->p->len >= optlen));
224 queuelen += pbuf_clen(seg->p);
225 seg->dataptr = seg->p->payload;
226 }
227 /* copy from volatile memory? */
228 else if (apiflags & TCP_WRITE_FLAG_COPY) {
229 if ((seg->p = pbuf_alloc(PBUF_TRANSPORT, seglen, PBUF_RAM)) == NULL) {
230 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue : could not allocate memory for pbuf copy size %"U16_F"\n", seglen));
231 goto memerr;
232 }
233 LWIP_ASSERT("check that first pbuf can hold the complete seglen",
234 (seg->p->len >= seglen));
235 queuelen += pbuf_clen(seg->p);
236 if (arg != NULL) {
237 MEMCPY(seg->p->payload, ptr, seglen);
238 }
239 seg->dataptr = seg->p->payload;
240 }
241 /* do not copy data */
242 else {
243 /* First, allocate a pbuf for holding the data.
244 * since the referenced data is available at least until it is sent out on the
245 * link (as it has to be ACKed by the remote party) we can safely use PBUF_ROM
246 * instead of PBUF_REF here.
247 */
248 if ((p = pbuf_alloc(PBUF_TRANSPORT, seglen, PBUF_ROM)) == NULL) {
249 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: could not allocate memory for zero-copy pbuf\n"));
250 goto memerr;
251 }
252 ++queuelen;
253 /* reference the non-volatile payload data */
254 p->payload = ptr;
255 seg->dataptr = ptr;
256
257 /* Second, allocate a pbuf for the headers. */
258 if ((seg->p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_RAM)) == NULL) {
259 /* If allocation fails, we have to deallocate the data pbuf as
260 * well. */
261 pbuf_free(p);
262 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: could not allocate memory for header pbuf\n"));
263 goto memerr;
264 }
265 queuelen += pbuf_clen(seg->p);
266
267 /* Concatenate the headers and data pbufs together. */
268 pbuf_cat(seg->p/*header*/, p/*data*/);
269 p = NULL;
270 }
271
272 /* Now that there are more segments queued, we check again if the
273 length of the queue exceeds the configured maximum or overflows. */
274 if ((queuelen > TCP_SND_QUEUELEN) || (queuelen > TCP_SNDQUEUELEN_OVERFLOW)) {
275 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: queue too long %"U16_F" (%"U16_F")\n", queuelen, TCP_SND_QUEUELEN));
276 goto memerr;
277 }
278
279 seg->len = seglen;
280
281 /* build TCP header */
282 if (pbuf_header(seg->p, TCP_HLEN)) {
283 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: no room for TCP header in pbuf.\n"));
284 TCP_STATS_INC(tcp.err);
285 goto memerr;
286 }
287 seg->tcphdr = seg->p->payload;
288 seg->tcphdr->src = htons(pcb->local_port);
289 seg->tcphdr->dest = htons(pcb->remote_port);
290 seg->tcphdr->seqno = htonl(seqno);
291 seg->tcphdr->urgp = 0;
292 TCPH_FLAGS_SET(seg->tcphdr, flags);
293 /* don't fill in tcphdr->ackno and tcphdr->wnd until later */
294
295 /* Copy the options into the header, if they are present. */
296 if (optdata == NULL) {
297 TCPH_HDRLEN_SET(seg->tcphdr, 5);
298 }
299 else {
300 TCPH_HDRLEN_SET(seg->tcphdr, (5 + optlen / 4));
301 /* Copy options into data portion of segment.
302 Options can thus only be sent in non data carrying
303 segments such as SYN|ACK. */
304 SMEMCPY(seg->dataptr, optdata, optlen);
305 }
306 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_TRACE, ("tcp_enqueue: queueing %"U32_F":%"U32_F" (0x%"X16_F")\n",
307 ntohl(seg->tcphdr->seqno),
308 ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg),
309 (u16_t)flags));
310
311 left -= seglen;
312 seqno += seglen;
313 ptr = (void *)((u8_t *)ptr + seglen);
314 }
315
316 /* Now that the data to be enqueued has been broken up into TCP
317 segments in the queue variable, we add them to the end of the
318 pcb->unsent queue. */
319 if (pcb->unsent == NULL) {
320 useg = NULL;
321 }
322 else {
323 for (useg = pcb->unsent; useg->next != NULL; useg = useg->next);
324 }
325 /* { useg is last segment on the unsent queue, NULL if list is empty } */
326
327 /* If there is room in the last pbuf on the unsent queue,
328 chain the first pbuf on the queue together with that. */
329 if (useg != NULL &&
330 TCP_TCPLEN(useg) != 0 &&
331 !(TCPH_FLAGS(useg->tcphdr) & (TCP_SYN | TCP_FIN)) &&
332 !(flags & (TCP_SYN | TCP_FIN)) &&
333 /* fit within max seg size */
334 useg->len + queue->len <= pcb->mss) {
335 /* Remove TCP header from first segment of our to-be-queued list */
336 if(pbuf_header(queue->p, -TCP_HLEN)) {
337 /* Can we cope with this failing? Just assert for now */
338 LWIP_ASSERT("pbuf_header failed\n", 0);
339 TCP_STATS_INC(tcp.err);
340 goto memerr;
341 }
342 pbuf_cat(useg->p, queue->p);
343 useg->len += queue->len;
344 useg->next = queue->next;
345
346 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("tcp_enqueue: chaining segments, new len %"U16_F"\n", useg->len));
347 if (seg == queue) {
348 seg = NULL;
349 }
350 memp_free(MEMP_TCP_SEG, queue);
351 }
352 else {
353 /* empty list */
354 if (useg == NULL) {
355 /* initialize list with this segment */
356 pcb->unsent = queue;
357 }
358 /* enqueue segment */
359 else {
360 useg->next = queue;
361 }
362 }
363 if ((flags & TCP_SYN) || (flags & TCP_FIN)) {
364 ++len;
365 }
366 if (flags & TCP_FIN) {
367 pcb->flags |= TF_FIN;
368 }
369 pcb->snd_lbb += len;
370
371 pcb->snd_buf -= len;
372
373 /* update number of segments on the queues */
374 pcb->snd_queuelen = queuelen;
375 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue: %"S16_F" (after enqueued)\n", pcb->snd_queuelen));
376 if (pcb->snd_queuelen != 0) {
377 LWIP_ASSERT("tcp_enqueue: valid queue length",
378 pcb->unacked != NULL || pcb->unsent != NULL);
379 }
380
381 /* Set the PSH flag in the last segment that we enqueued, but only
382 if the segment has data (indicated by seglen > 0). */
383 if (seg != NULL && seglen > 0 && seg->tcphdr != NULL && ((apiflags & TCP_WRITE_FLAG_MORE)==0)) {
384 TCPH_SET_FLAG(seg->tcphdr, TCP_PSH);
385 }
386
387 return ERR_OK;
388memerr:
389 pcb->flags |= TF_NAGLEMEMERR;
390 TCP_STATS_INC(tcp.memerr);
391
392 if (queue != NULL) {
393 tcp_segs_free(queue);
394 }
395 if (pcb->snd_queuelen != 0) {
396 LWIP_ASSERT("tcp_enqueue: valid queue length", pcb->unacked != NULL ||
397 pcb->unsent != NULL);
398 }
399 LWIP_DEBUGF(TCP_QLEN_DEBUG | LWIP_DBG_STATE, ("tcp_enqueue: %"S16_F" (with mem err)\n", pcb->snd_queuelen));
400 return ERR_MEM;
401}
402
403/**
404 * Find out what we can send and send it
405 *
406 * @param pcb Protocol control block for the TCP connection to send data
407 * @return ERR_OK if data has been sent or nothing to send
408 * another err_t on error
409 */
410err_t
411tcp_output(struct tcp_pcb *pcb)
412{
413 struct pbuf *p;
414 struct tcp_hdr *tcphdr;
415 struct tcp_seg *seg, *useg;
416 u32_t wnd;
417#if TCP_CWND_DEBUG
418 s16_t i = 0;
419#endif /* TCP_CWND_DEBUG */
420
421 /* First, check if we are invoked by the TCP input processing
422 code. If so, we do not output anything. Instead, we rely on the
423 input processing code to call us when input processing is done
424 with. */
425 if (tcp_input_pcb == pcb) {
426 return ERR_OK;
427 }
428
429 wnd = LWIP_MIN(pcb->snd_wnd, pcb->cwnd);
430
431 seg = pcb->unsent;
432
433 /* useg should point to last segment on unacked queue */
434 useg = pcb->unacked;
435 if (useg != NULL) {
436 for (; useg->next != NULL; useg = useg->next);
437 }
438
439 /* If the TF_ACK_NOW flag is set and no data will be sent (either
440 * because the ->unsent queue is empty or because the window does
441 * not allow it), construct an empty ACK segment and send it.
442 *
443 * If data is to be sent, we will just piggyback the ACK (see below).
444 */
445 if (pcb->flags & TF_ACK_NOW &&
446 (seg == NULL ||
447 ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len > wnd)) {
448 p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM);
449 if (p == NULL) {
450 LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: (ACK) could not allocate pbuf\n"));
451 return ERR_BUF;
452 }
453 LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: sending ACK for %"U32_F"\n", pcb->rcv_nxt));
454 /* remove ACK flags from the PCB, as we send an empty ACK now */
455 pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
456
457 tcphdr = p->payload;
458 tcphdr->src = htons(pcb->local_port);
459 tcphdr->dest = htons(pcb->remote_port);
460 tcphdr->seqno = htonl(pcb->snd_nxt);
461 tcphdr->ackno = htonl(pcb->rcv_nxt);
462 TCPH_FLAGS_SET(tcphdr, TCP_ACK);
463 tcphdr->wnd = htons(pcb->rcv_ann_wnd);
464 tcphdr->urgp = 0;
465 TCPH_HDRLEN_SET(tcphdr, 5);
466
467 tcphdr->chksum = 0;
468#if CHECKSUM_GEN_TCP
469 tcphdr->chksum = inet_chksum_pseudo(p, &(pcb->local_ip), &(pcb->remote_ip),
470 IP_PROTO_TCP, p->tot_len);
471#endif
472#if LWIP_NETIF_HWADDRHINT
473 {
474 struct netif *netif;
475 netif = ip_route(&pcb->remote_ip);
476 if(netif != NULL){
477 netif->addr_hint = &(pcb->addr_hint);
478 ip_output_if(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl,
479 pcb->tos, IP_PROTO_TCP, netif);
480 netif->addr_hint = NULL;
481 }
482 }
483#else /* LWIP_NETIF_HWADDRHINT*/
484 ip_output(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
485 IP_PROTO_TCP);
486#endif /* LWIP_NETIF_HWADDRHINT*/
487 pbuf_free(p);
488
489 return ERR_OK;
490 }
491
492#if TCP_OUTPUT_DEBUG
493 if (seg == NULL) {
494 LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: nothing to send (%p)\n",
495 (void*)pcb->unsent));
496 }
497#endif /* TCP_OUTPUT_DEBUG */
498#if TCP_CWND_DEBUG
499 if (seg == NULL) {
500 LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"U16_F
501 ", cwnd %"U16_F", wnd %"U32_F
502 ", seg == NULL, ack %"U32_F"\n",
503 pcb->snd_wnd, pcb->cwnd, wnd, pcb->lastack));
504 } else {
505 LWIP_DEBUGF(TCP_CWND_DEBUG,
506 ("tcp_output: snd_wnd %"U16_F", cwnd %"U16_F", wnd %"U32_F
507 ", effwnd %"U32_F", seq %"U32_F", ack %"U32_F"\n",
508 pcb->snd_wnd, pcb->cwnd, wnd,
509 ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len,
510 ntohl(seg->tcphdr->seqno), pcb->lastack));
511 }
512#endif /* TCP_CWND_DEBUG */
513 /* data available and window allows it to be sent? */
514 while (seg != NULL &&
515 ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) {
516 LWIP_ASSERT("RST not expected here!",
517 (TCPH_FLAGS(seg->tcphdr) & TCP_RST) == 0);
518 /* Stop sending if the nagle algorithm would prevent it
519 * Don't stop:
520 * - if tcp_enqueue had a memory error before (prevent delayed ACK timeout) or
521 * - if FIN was already enqueued for this PCB (SYN is always alone in a segment -
522 * either seg->next != NULL or pcb->unacked == NULL;
523 * RST is no sent using tcp_enqueue/tcp_output.
524 */
525 if((tcp_do_output_nagle(pcb) == 0) &&
526 ((pcb->flags & (TF_NAGLEMEMERR | TF_FIN)) == 0)){
527 break;
528 }
529#if TCP_CWND_DEBUG
530 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",
531 pcb->snd_wnd, pcb->cwnd, wnd,
532 ntohl(seg->tcphdr->seqno) + seg->len -
533 pcb->lastack,
534 ntohl(seg->tcphdr->seqno), pcb->lastack, i));
535 ++i;
536#endif /* TCP_CWND_DEBUG */
537
538 pcb->unsent = seg->next;
539
540 if (pcb->state != SYN_SENT) {
541 TCPH_SET_FLAG(seg->tcphdr, TCP_ACK);
542 pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
543 }
544
545 tcp_output_segment(seg, pcb);
546 pcb->snd_nxt = ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg);
547 if (TCP_SEQ_LT(pcb->snd_max, pcb->snd_nxt)) {
548 pcb->snd_max = pcb->snd_nxt;
549 }
550 /* put segment on unacknowledged list if length > 0 */
551 if (TCP_TCPLEN(seg) > 0) {
552 seg->next = NULL;
553 /* unacked list is empty? */
554 if (pcb->unacked == NULL) {
555 pcb->unacked = seg;
556 useg = seg;
557 /* unacked list is not empty? */
558 } else {
559 /* In the case of fast retransmit, the packet should not go to the tail
560 * of the unacked queue, but rather at the head. We need to check for
561 * this case. -STJ Jul 27, 2004 */
562 if (TCP_SEQ_LT(ntohl(seg->tcphdr->seqno), ntohl(useg->tcphdr->seqno))){
563 /* add segment to head of unacked list */
564 seg->next = pcb->unacked;
565 pcb->unacked = seg;
566 } else {
567 /* add segment to tail of unacked list */
568 useg->next = seg;
569 useg = useg->next;
570 }
571 }
572 /* do not queue empty segments on the unacked list */
573 } else {
574 tcp_seg_free(seg);
575 }
576 seg = pcb->unsent;
577 }
578
579 if (seg != NULL && pcb->persist_backoff == 0 &&
580 ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len > pcb->snd_wnd) {
581 /* prepare for persist timer */
582 pcb->persist_cnt = 0;
583 pcb->persist_backoff = 1;
584 }
585
586 pcb->flags &= ~TF_NAGLEMEMERR;
587 return ERR_OK;
588}
589
590/**
591 * Called by tcp_output() to actually send a TCP segment over IP.
592 *
593 * @param seg the tcp_seg to send
594 * @param pcb the tcp_pcb for the TCP connection used to send the segment
595 */
596static void
597tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb)
598{
599 u16_t len;
600 struct netif *netif;
601
602 /** @bug Exclude retransmitted segments from this count. */
603 snmp_inc_tcpoutsegs();
604
605 /* The TCP header has already been constructed, but the ackno and
606 wnd fields remain. */
607 seg->tcphdr->ackno = htonl(pcb->rcv_nxt);
608
609 /* advertise our receive window size in this TCP segment */
610 seg->tcphdr->wnd = htons(pcb->rcv_ann_wnd);
611
612 /* If we don't have a local IP address, we get one by
613 calling ip_route(). */
614 if (ip_addr_isany(&(pcb->local_ip))) {
615 netif = ip_route(&(pcb->remote_ip));
616 if (netif == NULL) {
617 return;
618 }
619 ip_addr_set(&(pcb->local_ip), &(netif->ip_addr));
620 }
621
622 /* Set retransmission timer running if it is not currently enabled */
623 if(pcb->rtime == -1)
624 pcb->rtime = 0;
625
626 if (pcb->rttest == 0) {
627 pcb->rttest = tcp_ticks;
628 pcb->rtseq = ntohl(seg->tcphdr->seqno);
629
630 LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_output_segment: rtseq %"U32_F"\n", pcb->rtseq));
631 }
632 LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output_segment: %"U32_F":%"U32_F"\n",
633 htonl(seg->tcphdr->seqno), htonl(seg->tcphdr->seqno) +
634 seg->len));
635
636 len = (u16_t)((u8_t *)seg->tcphdr - (u8_t *)seg->p->payload);
637
638 seg->p->len -= len;
639 seg->p->tot_len -= len;
640
641 seg->p->payload = seg->tcphdr;
642
643 seg->tcphdr->chksum = 0;
644#if CHECKSUM_GEN_TCP
645 seg->tcphdr->chksum = inet_chksum_pseudo(seg->p,
646 &(pcb->local_ip),
647 &(pcb->remote_ip),
648 IP_PROTO_TCP, seg->p->tot_len);
649#endif
650 TCP_STATS_INC(tcp.xmit);
651
652#if LWIP_NETIF_HWADDRHINT
653 {
654 struct netif *netif;
655 netif = ip_route(&pcb->remote_ip);
656 if(netif != NULL){
657 netif->addr_hint = &(pcb->addr_hint);
658 ip_output_if(seg->p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl,
659 pcb->tos, IP_PROTO_TCP, netif);
660 netif->addr_hint = NULL;
661 }
662 }
663#else /* LWIP_NETIF_HWADDRHINT*/
664 ip_output(seg->p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
665 IP_PROTO_TCP);
666#endif /* LWIP_NETIF_HWADDRHINT*/
667}
668
669/**
670 * Send a TCP RESET packet (empty segment with RST flag set) either to
671 * abort a connection or to show that there is no matching local connection
672 * for a received segment.
673 *
674 * Called by tcp_abort() (to abort a local connection), tcp_input() (if no
675 * matching local pcb was found), tcp_listen_input() (if incoming segment
676 * has ACK flag set) and tcp_process() (received segment in the wrong state)
677 *
678 * Since a RST segment is in most cases not sent for an active connection,
679 * tcp_rst() has a number of arguments that are taken from a tcp_pcb for
680 * most other segment output functions.
681 *
682 * @param seqno the sequence number to use for the outgoing segment
683 * @param ackno the acknowledge number to use for the outgoing segment
684 * @param local_ip the local IP address to send the segment from
685 * @param remote_ip the remote IP address to send the segment to
686 * @param local_port the local TCP port to send the segment from
687 * @param remote_port the remote TCP port to send the segment to
688 */
689void
690tcp_rst(u32_t seqno, u32_t ackno,
691 struct ip_addr *local_ip, struct ip_addr *remote_ip,
692 u16_t local_port, u16_t remote_port)
693{
694 struct pbuf *p;
695 struct tcp_hdr *tcphdr;
696 p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM);
697 if (p == NULL) {
698 LWIP_DEBUGF(TCP_DEBUG, ("tcp_rst: could not allocate memory for pbuf\n"));
699 return;
700 }
701 LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr",
702 (p->len >= sizeof(struct tcp_hdr)));
703
704 tcphdr = p->payload;
705 tcphdr->src = htons(local_port);
706 tcphdr->dest = htons(remote_port);
707 tcphdr->seqno = htonl(seqno);
708 tcphdr->ackno = htonl(ackno);
709 TCPH_FLAGS_SET(tcphdr, TCP_RST | TCP_ACK);
710 tcphdr->wnd = htons(TCP_WND);
711 tcphdr->urgp = 0;
712 TCPH_HDRLEN_SET(tcphdr, 5);
713
714 tcphdr->chksum = 0;
715#if CHECKSUM_GEN_TCP
716 tcphdr->chksum = inet_chksum_pseudo(p, local_ip, remote_ip,
717 IP_PROTO_TCP, p->tot_len);
718#endif
719 TCP_STATS_INC(tcp.xmit);
720 snmp_inc_tcpoutrsts();
721 /* Send output with hardcoded TTL since we have no access to the pcb */
722 ip_output(p, local_ip, remote_ip, TCP_TTL, 0, IP_PROTO_TCP);
723 pbuf_free(p);
724 LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_rst: seqno %"U32_F" ackno %"U32_F".\n", seqno, ackno));
725}
726
727/**
728 * Requeue all unacked segments for retransmission
729 *
730 * Called by tcp_slowtmr() for slow retransmission.
731 *
732 * @param pcb the tcp_pcb for which to re-enqueue all unacked segments
733 */
734void
735tcp_rexmit_rto(struct tcp_pcb *pcb)
736{
737 struct tcp_seg *seg;
738
739 if (pcb->unacked == NULL) {
740 return;
741 }
742
743 /* Move all unacked segments to the head of the unsent queue */
744 for (seg = pcb->unacked; seg->next != NULL; seg = seg->next);
745 /* concatenate unsent queue after unacked queue */
746 seg->next = pcb->unsent;
747 /* unsent queue is the concatenated queue (of unacked, unsent) */
748 pcb->unsent = pcb->unacked;
749 /* unacked queue is now empty */
750 pcb->unacked = NULL;
751
752 pcb->snd_nxt = ntohl(pcb->unsent->tcphdr->seqno);
753 /* increment number of retransmissions */
754 ++pcb->nrtx;
755
756 /* Don't take any RTT measurements after retransmitting. */
757 pcb->rttest = 0;
758
759 /* Do the actual retransmission */
760 tcp_output(pcb);
761}
762
763/**
764 * Requeue the first unacked segment for retransmission
765 *
766 * Called by tcp_receive() for fast retramsmit.
767 *
768 * @param pcb the tcp_pcb for which to retransmit the first unacked segment
769 */
770void
771tcp_rexmit(struct tcp_pcb *pcb)
772{
773 struct tcp_seg *seg;
774
775 if (pcb->unacked == NULL) {
776 return;
777 }
778
779 /* Move the first unacked segment to the unsent queue */
780 seg = pcb->unacked->next;
781 pcb->unacked->next = pcb->unsent;
782 pcb->unsent = pcb->unacked;
783 pcb->unacked = seg;
784
785 pcb->snd_nxt = ntohl(pcb->unsent->tcphdr->seqno);
786
787 ++pcb->nrtx;
788
789 /* Don't take any rtt measurements after retransmitting. */
790 pcb->rttest = 0;
791
792 /* Do the actual retransmission. */
793 snmp_inc_tcpretranssegs();
794 tcp_output(pcb);
795}
796
797/**
798 * Send keepalive packets to keep a connection active although
799 * no data is sent over it.
800 *
801 * Called by tcp_slowtmr()
802 *
803 * @param pcb the tcp_pcb for which to send a keepalive packet
804 */
805void
806tcp_keepalive(struct tcp_pcb *pcb)
807{
808 struct pbuf *p;
809 struct tcp_hdr *tcphdr;
810
811 LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: sending KEEPALIVE probe to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
812 ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip),
813 ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip)));
814
815 LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: tcp_ticks %"U32_F" pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n",
816 tcp_ticks, pcb->tmr, pcb->keep_cnt_sent));
817
818 p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM);
819
820 if(p == NULL) {
821 LWIP_DEBUGF(TCP_DEBUG,
822 ("tcp_keepalive: could not allocate memory for pbuf\n"));
823 return;
824 }
825 LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr",
826 (p->len >= sizeof(struct tcp_hdr)));
827
828 tcphdr = p->payload;
829 tcphdr->src = htons(pcb->local_port);
830 tcphdr->dest = htons(pcb->remote_port);
831 tcphdr->seqno = htonl(pcb->snd_nxt - 1);
832 tcphdr->ackno = htonl(pcb->rcv_nxt);
833 TCPH_FLAGS_SET(tcphdr, 0);
834 tcphdr->wnd = htons(pcb->rcv_ann_wnd);
835 tcphdr->urgp = 0;
836 TCPH_HDRLEN_SET(tcphdr, 5);
837
838 tcphdr->chksum = 0;
839#if CHECKSUM_GEN_TCP
840 tcphdr->chksum = inet_chksum_pseudo(p, &pcb->local_ip, &pcb->remote_ip,
841 IP_PROTO_TCP, p->tot_len);
842#endif
843 TCP_STATS_INC(tcp.xmit);
844
845 /* Send output to IP */
846#if LWIP_NETIF_HWADDRHINT
847 {
848 struct netif *netif;
849 netif = ip_route(&pcb->remote_ip);
850 if(netif != NULL){
851 netif->addr_hint = &(pcb->addr_hint);
852 ip_output_if(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl,
853 0, IP_PROTO_TCP, netif);
854 netif->addr_hint = NULL;
855 }
856 }
857#else /* LWIP_NETIF_HWADDRHINT*/
858 ip_output(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP);
859#endif /* LWIP_NETIF_HWADDRHINT*/
860
861 pbuf_free(p);
862
863 LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: seqno %"U32_F" ackno %"U32_F".\n",
864 pcb->snd_nxt - 1, pcb->rcv_nxt));
865}
866
867
868/**
869 * Send persist timer zero-window probes to keep a connection active
870 * when a window update is lost.
871 *
872 * Called by tcp_slowtmr()
873 *
874 * @param pcb the tcp_pcb for which to send a zero-window probe packet
875 */
876void
877tcp_zero_window_probe(struct tcp_pcb *pcb)
878{
879 struct pbuf *p;
880 struct tcp_hdr *tcphdr;
881 struct tcp_seg *seg;
882
883 LWIP_DEBUGF(TCP_DEBUG,
884 ("tcp_zero_window_probe: sending ZERO WINDOW probe to %"
885 U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
886 ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip),
887 ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip)));
888
889 LWIP_DEBUGF(TCP_DEBUG,
890 ("tcp_zero_window_probe: tcp_ticks %"U32_F
891 " pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n",
892 tcp_ticks, pcb->tmr, pcb->keep_cnt_sent));
893
894 seg = pcb->unacked;
895
896 if(seg == NULL)
897 seg = pcb->unsent;
898
899 if(seg == NULL)
900 return;
901
902 p = pbuf_alloc(PBUF_IP, TCP_HLEN + 1, PBUF_RAM);
903
904 if(p == NULL) {
905 LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: no memory for pbuf\n"));
906 return;
907 }
908 LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr",
909 (p->len >= sizeof(struct tcp_hdr)));
910
911 tcphdr = p->payload;
912 tcphdr->src = htons(pcb->local_port);
913 tcphdr->dest = htons(pcb->remote_port);
914 tcphdr->seqno = seg->tcphdr->seqno;
915 tcphdr->ackno = htonl(pcb->rcv_nxt);
916 TCPH_FLAGS_SET(tcphdr, 0);
917 tcphdr->wnd = htons(pcb->rcv_ann_wnd);
918 tcphdr->urgp = 0;
919 TCPH_HDRLEN_SET(tcphdr, 5);
920
921 /* Copy in one byte from the head of the unacked queue */
922 *((char *)p->payload + sizeof(struct tcp_hdr)) = *(char *)seg->dataptr;
923
924 tcphdr->chksum = 0;
925#if CHECKSUM_GEN_TCP
926 tcphdr->chksum = inet_chksum_pseudo(p, &pcb->local_ip, &pcb->remote_ip,
927 IP_PROTO_TCP, p->tot_len);
928#endif
929 TCP_STATS_INC(tcp.xmit);
930
931 /* Send output to IP */
932#if LWIP_NETIF_HWADDRHINT
933 {
934 struct netif *netif;
935 netif = ip_route(&pcb->remote_ip);
936 if(netif != NULL){
937 netif->addr_hint = &(pcb->addr_hint);
938 ip_output_if(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl,
939 0, IP_PROTO_TCP, netif);
940 netif->addr_hint = NULL;
941 }
942 }
943#else /* LWIP_NETIF_HWADDRHINT*/
944 ip_output(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP);
945#endif /* LWIP_NETIF_HWADDRHINT*/
946
947 pbuf_free(p);
948
949 LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: seqno %"U32_F
950 " ackno %"U32_F".\n",
951 pcb->snd_nxt - 1, pcb->rcv_nxt));
952}
953#endif /* LWIP_TCP */
This page took 0.099495 seconds and 4 git commands to generate.