blob: 62982bd14a91e2b38f0b7583988815a41b04491b [file] [log] [blame]
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -07001/**
2 * @file
3 *
4 * Transmission Control Protocol, outgoing traffic
5 *
6 * The output functions of TCP.
7 *
8 */
9
10/*
11 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
12 * All rights reserved.
13 *
14 * Redistribution and use in source and binary forms, with or without modification,
15 * are permitted provided that the following conditions are met:
16 *
17 * 1. Redistributions of source code must retain the above copyright notice,
18 * this list of conditions and the following disclaimer.
19 * 2. Redistributions in binary form must reproduce the above copyright notice,
20 * this list of conditions and the following disclaimer in the documentation
21 * and/or other materials provided with the distribution.
22 * 3. The name of the author may not be used to endorse or promote products
23 * derived from this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
26 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
27 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
28 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
30 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
33 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
34 * OF SUCH DAMAGE.
35 *
36 * This file is part of the lwIP TCP/IP stack.
37 *
38 * Author: Adam Dunkels <adam@sics.se>
39 *
40 */
41
42#include <string.h>
43
44#include "lwip/def.h"
45#include "lwip/opt.h"
46#include "lwip/mem.h"
47#include "lwip/memp.h"
48#include "lwip/sys.h"
49#include "lwip/ip_addr.h"
50#include "lwip/netif.h"
51#include "lwip/inet.h"
52#include "lwip/tcp.h"
53#include "lwip/stats.h"
54
55#if LWIP_TCP
56
57/* Forward declarations.*/
58static void tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb);
59
60err_t
61tcp_send_ctrl(struct tcp_pcb *pcb, u8_t flags)
62{
63 /* no data, no length, flags, copy=1, no optdata, no optdatalen */
64 return tcp_enqueue(pcb, NULL, 0, flags, 1, NULL, 0);
65}
66
67/**
68 * Write data for sending (but does not send it immediately).
69 *
70 * It waits in the expectation of more data being sent soon (as
71 * it can send them more efficiently by combining them together).
72 * To prompt the system to send data now, call tcp_output() after
73 * calling tcp_write().
74 *
75 * @arg pcb Protocol control block of the TCP connection to enqueue data for.
76 *
77 * @see tcp_write()
78 */
79
80err_t
81tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t copy)
82{
83 LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_write(pcb=%p, arg=%p, len=%"U16_F", copy=%"U16_F")\n", (void *)pcb,
84 arg, len, (u16_t)copy));
85 /* connection is in valid state for data transmission? */
86 if (pcb->state == ESTABLISHED ||
87 pcb->state == CLOSE_WAIT ||
88 pcb->state == SYN_SENT ||
89 pcb->state == SYN_RCVD) {
90 if (len > 0) {
91 return tcp_enqueue(pcb, (void *)arg, len, 0, copy, NULL, 0);
92 }
93 return ERR_OK;
94 } else {
95 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | DBG_STATE | 3, ("tcp_write() called in invalid state\n"));
96 return ERR_CONN;
97 }
98}
99
100/**
101 * Enqueue either data or TCP options (but not both) for tranmission
102 *
103 *
104 *
105 * @arg pcb Protocol control block for the TCP connection to enqueue data for.
106 * @arg arg Pointer to the data to be enqueued for sending.
107 * @arg len Data length in bytes
108 * @arg flags
109 * @arg copy 1 if data must be copied, 0 if data is non-volatile and can be
110 * referenced.
111 * @arg optdata
112 * @arg optlen
113 */
114err_t
115tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
116 u8_t flags, u8_t copy,
117 u8_t *optdata, u8_t optlen)
118{
119 struct pbuf *p;
120 struct tcp_seg *seg, *useg, *queue;
121 u32_t left, seqno;
122 u16_t seglen;
123 void *ptr;
124 u8_t queuelen;
125
126 LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_enqueue(pcb=%p, arg=%p, len=%"U16_F", flags=%"X16_F", copy=%"U16_F")\n",
127 (void *)pcb, arg, len, (u16_t)flags, (u16_t)copy));
128 LWIP_ASSERT("tcp_enqueue: len == 0 || optlen == 0 (programmer violates API)",
129 len == 0 || optlen == 0);
130 LWIP_ASSERT("tcp_enqueue: arg == NULL || optdata == NULL (programmer violates API)",
131 arg == NULL || optdata == NULL);
132 /* fail on too much data */
133 if (len > pcb->snd_buf) {
134 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue: too much data (len=%"U16_F" > snd_buf=%"U16_F")\n", len, pcb->snd_buf));
135 return ERR_MEM;
136 }
137 left = len;
138 ptr = arg;
139
140 /* seqno will be the sequence number of the first segment enqueued
141 * by the call to this function. */
142 seqno = pcb->snd_lbb;
143
144 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue: queuelen: %"U16_F"\n", (u16_t)pcb->snd_queuelen));
145
146 /* If total number of pbufs on the unsent/unacked queues exceeds the
147 * configured maximum, return an error */
148 queuelen = pcb->snd_queuelen;
149 if (queuelen >= TCP_SND_QUEUELEN) {
150 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue: too long queue %"U16_F" (max %"U16_F")\n", queuelen, TCP_SND_QUEUELEN));
151 TCP_STATS_INC(tcp.memerr);
152 return ERR_MEM;
153 }
154 if (queuelen != 0) {
155 LWIP_ASSERT("tcp_enqueue: pbufs on queue => at least one queue non-empty",
156 pcb->unacked != NULL || pcb->unsent != NULL);
157 } else {
158 LWIP_ASSERT("tcp_enqueue: no pbufs on queue => both queues empty",
159 pcb->unacked == NULL && pcb->unsent == NULL);
160 }
161
162 /* First, break up the data into segments and tuck them together in
163 * the local "queue" variable. */
164 useg = queue = seg = NULL;
165 seglen = 0;
166 while (queue == NULL || left > 0) {
167
168 /* The segment length should be the MSS if the data to be enqueued
169 * is larger than the MSS. */
170 seglen = left > pcb->mss? pcb->mss: left;
171
172 /* Allocate memory for tcp_seg, and fill in fields. */
173 seg = memp_malloc(MEMP_TCP_SEG);
174 if (seg == NULL) {
175 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: could not allocate memory for tcp_seg\n"));
176 goto memerr;
177 }
178 seg->next = NULL;
179 seg->p = NULL;
180
181 /* first segment of to-be-queued data? */
182 if (queue == NULL) {
183 queue = seg;
184 }
185 /* subsequent segments of to-be-queued data */
186 else {
187 /* Attach the segment to the end of the queued segments */
188 LWIP_ASSERT("useg != NULL", useg != NULL);
189 useg->next = seg;
190 }
191 /* remember last segment of to-be-queued data for next iteration */
192 useg = seg;
193
194 /* If copy is set, memory should be allocated
195 * and data copied into pbuf, otherwise data comes from
196 * ROM or other static memory, and need not be copied. If
197 * optdata is != NULL, we have options instead of data. */
198
199 /* options? */
200 if (optdata != NULL) {
201 if ((seg->p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) {
202 goto memerr;
203 }
204 ++queuelen;
205 seg->dataptr = seg->p->payload;
206 }
207 /* copy from volatile memory? */
208 else if (copy) {
209 if ((seg->p = pbuf_alloc(PBUF_TRANSPORT, seglen, PBUF_RAM)) == NULL) {
210 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue : could not allocate memory for pbuf copy size %"U16_F"\n", seglen));
211 goto memerr;
212 }
213 ++queuelen;
214 if (arg != NULL) {
215 memcpy(seg->p->payload, ptr, seglen);
216 }
217 seg->dataptr = seg->p->payload;
218 }
219 /* do not copy data */
220 else {
221 /* First, allocate a pbuf for holding the data.
222 * since the referenced data is available at least until it is sent out on the
223 * link (as it has to be ACKed by the remote party) we can safely use PBUF_ROM
224 * instead of PBUF_REF here.
225 */
226 if ((p = pbuf_alloc(PBUF_TRANSPORT, seglen, PBUF_ROM)) == NULL) {
227 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: could not allocate memory for zero-copy pbuf\n"));
228 goto memerr;
229 }
230 ++queuelen;
231 /* reference the non-volatile payload data */
232 p->payload = ptr;
233 seg->dataptr = ptr;
234
235 /* Second, allocate a pbuf for the headers. */
236 if ((seg->p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_RAM)) == NULL) {
237 /* If allocation fails, we have to deallocate the data pbuf as
238 * well. */
239 pbuf_free(p);
240 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: could not allocate memory for header pbuf\n"));
241 goto memerr;
242 }
243 ++queuelen;
244
245 /* Concatenate the headers and data pbufs together. */
246 pbuf_cat(seg->p/*header*/, p/*data*/);
247 p = NULL;
248 }
249
250 /* Now that there are more segments queued, we check again if the
251 length of the queue exceeds the configured maximum. */
252 if (queuelen > TCP_SND_QUEUELEN) {
253 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: queue too long %"U16_F" (%"U16_F")\n", queuelen, TCP_SND_QUEUELEN));
254 goto memerr;
255 }
256
257 seg->len = seglen;
258
259 /* build TCP header */
260 if (pbuf_header(seg->p, TCP_HLEN)) {
261 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: no room for TCP header in pbuf.\n"));
262 TCP_STATS_INC(tcp.err);
263 goto memerr;
264 }
265 seg->tcphdr = seg->p->payload;
266 seg->tcphdr->src = htons(pcb->local_port);
267 seg->tcphdr->dest = htons(pcb->remote_port);
268 seg->tcphdr->seqno = htonl(seqno);
269 seg->tcphdr->urgp = 0;
270 TCPH_FLAGS_SET(seg->tcphdr, flags);
271 /* don't fill in tcphdr->ackno and tcphdr->wnd until later */
272
273 /* Copy the options into the header, if they are present. */
274 if (optdata == NULL) {
275 TCPH_HDRLEN_SET(seg->tcphdr, 5);
276 }
277 else {
278 TCPH_HDRLEN_SET(seg->tcphdr, (5 + optlen / 4));
279 /* Copy options into data portion of segment.
280 Options can thus only be sent in non data carrying
281 segments such as SYN|ACK. */
282 memcpy(seg->dataptr, optdata, optlen);
283 }
284 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | DBG_TRACE, ("tcp_enqueue: queueing %"U32_F":%"U32_F" (0x%"X16_F")\n",
285 ntohl(seg->tcphdr->seqno),
286 ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg),
287 (u16_t)flags));
288
289 left -= seglen;
290 seqno += seglen;
291 ptr = (void *)((u8_t *)ptr + seglen);
292 }
293
294 /* Now that the data to be enqueued has been broken up into TCP
295 segments in the queue variable, we add them to the end of the
296 pcb->unsent queue. */
297 if (pcb->unsent == NULL) {
298 useg = NULL;
299 }
300 else {
301 for (useg = pcb->unsent; useg->next != NULL; useg = useg->next);
302 }
303 /* { useg is last segment on the unsent queue, NULL if list is empty } */
304
305 /* If there is room in the last pbuf on the unsent queue,
306 chain the first pbuf on the queue together with that. */
307 if (useg != NULL &&
308 TCP_TCPLEN(useg) != 0 &&
309 !(TCPH_FLAGS(useg->tcphdr) & (TCP_SYN | TCP_FIN)) &&
310 !(flags & (TCP_SYN | TCP_FIN)) &&
311 /* fit within max seg size */
312 useg->len + queue->len <= pcb->mss) {
313 /* Remove TCP header from first segment of our to-be-queued list */
314 pbuf_header(queue->p, -TCP_HLEN);
315 pbuf_cat(useg->p, queue->p);
316 useg->len += queue->len;
317 useg->next = queue->next;
318
319 LWIP_DEBUGF(TCP_OUTPUT_DEBUG | DBG_TRACE | DBG_STATE, ("tcp_enqueue: chaining segments, new len %"U16_F"\n", useg->len));
320 if (seg == queue) {
321 seg = NULL;
322 }
323 memp_free(MEMP_TCP_SEG, queue);
324 }
325 else {
326 /* empty list */
327 if (useg == NULL) {
328 /* initialize list with this segment */
329 pcb->unsent = queue;
330 }
331 /* enqueue segment */
332 else {
333 useg->next = queue;
334 }
335 }
336 if ((flags & TCP_SYN) || (flags & TCP_FIN)) {
337 ++len;
338 }
339 pcb->snd_lbb += len;
340
341 pcb->snd_buf -= len;
342
343 /* update number of segments on the queues */
344 pcb->snd_queuelen = queuelen;
345 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue: %"S16_F" (after enqueued)\n", pcb->snd_queuelen));
346 if (pcb->snd_queuelen != 0) {
347 LWIP_ASSERT("tcp_enqueue: valid queue length",
348 pcb->unacked != NULL || pcb->unsent != NULL);
349 }
350
351 /* Set the PSH flag in the last segment that we enqueued, but only
352 if the segment has data (indicated by seglen > 0). */
353 if (seg != NULL && seglen > 0 && seg->tcphdr != NULL) {
354 TCPH_SET_FLAG(seg->tcphdr, TCP_PSH);
355 }
356
357 return ERR_OK;
358memerr:
359 TCP_STATS_INC(tcp.memerr);
360
361 if (queue != NULL) {
362 tcp_segs_free(queue);
363 }
364 if (pcb->snd_queuelen != 0) {
365 LWIP_ASSERT("tcp_enqueue: valid queue length", pcb->unacked != NULL ||
366 pcb->unsent != NULL);
367 }
368 LWIP_DEBUGF(TCP_QLEN_DEBUG | DBG_STATE, ("tcp_enqueue: %"S16_F" (with mem err)\n", pcb->snd_queuelen));
369 return ERR_MEM;
370}
371
372/* find out what we can send and send it */
373err_t
374tcp_output(struct tcp_pcb *pcb)
375{
376 struct pbuf *p;
377 struct tcp_hdr *tcphdr;
378 struct tcp_seg *seg, *useg;
379 u32_t wnd;
380#if TCP_CWND_DEBUG
381 s16_t i = 0;
382#endif /* TCP_CWND_DEBUG */
383
384 /* First, check if we are invoked by the TCP input processing
385 code. If so, we do not output anything. Instead, we rely on the
386 input processing code to call us when input processing is done
387 with. */
388 if (tcp_input_pcb == pcb) {
389 return ERR_OK;
390 }
391
392 wnd = LWIP_MIN(pcb->snd_wnd, pcb->cwnd);
393
394 seg = pcb->unsent;
395
396 /* useg should point to last segment on unacked queue */
397 useg = pcb->unacked;
398 if (useg != NULL) {
399 for (; useg->next != NULL; useg = useg->next);
400 }
401
402 /* If the TF_ACK_NOW flag is set and no data will be sent (either
403 * because the ->unsent queue is empty or because the window does
404 * not allow it), construct an empty ACK segment and send it.
405 *
406 * If data is to be sent, we will just piggyback the ACK (see below).
407 */
408 if (pcb->flags & TF_ACK_NOW &&
409 (seg == NULL ||
410 ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len > wnd)) {
411 p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM);
412 if (p == NULL) {
413 LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: (ACK) could not allocate pbuf\n"));
414 return ERR_BUF;
415 }
416 LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: sending ACK for %"U32_F"\n", pcb->rcv_nxt));
417 /* remove ACK flags from the PCB, as we send an empty ACK now */
418 pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
419
420 tcphdr = p->payload;
421 tcphdr->src = htons(pcb->local_port);
422 tcphdr->dest = htons(pcb->remote_port);
423 tcphdr->seqno = htonl(pcb->snd_nxt);
424 tcphdr->ackno = htonl(pcb->rcv_nxt);
425 TCPH_FLAGS_SET(tcphdr, TCP_ACK);
426 tcphdr->wnd = htons(pcb->rcv_wnd);
427 tcphdr->urgp = 0;
428 TCPH_HDRLEN_SET(tcphdr, 5);
429
430 tcphdr->chksum = 0;
431#if CHECKSUM_GEN_TCP
432 tcphdr->chksum = inet_chksum_pseudo(p, &(pcb->local_ip), &(pcb->remote_ip),
433 IP_PROTO_TCP, p->tot_len);
434#endif
435 ip_output(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
436 IP_PROTO_TCP);
437 pbuf_free(p);
438
439 return ERR_OK;
440 }
441
442#if TCP_OUTPUT_DEBUG
443 if (seg == NULL) {
444 LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: nothing to send (%p)\n", (void*)pcb->unsent));
445 }
446#endif /* TCP_OUTPUT_DEBUG */
447#if TCP_CWND_DEBUG
448 if (seg == NULL) {
449 LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"U32_F", cwnd %"U16_F", wnd %"U32_F", seg == NULL, ack %"U32_F"\n",
450 pcb->snd_wnd, pcb->cwnd, wnd,
451 pcb->lastack));
452 } else {
453 LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"U32_F", cwnd %"U16_F", wnd %"U32_F", effwnd %"U32_F", seq %"U32_F", ack %"U32_F"\n",
454 pcb->snd_wnd, pcb->cwnd, wnd,
455 ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len,
456 ntohl(seg->tcphdr->seqno), pcb->lastack));
457 }
458#endif /* TCP_CWND_DEBUG */
459 /* data available and window allows it to be sent? */
460 while (seg != NULL &&
461 ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) {
462#if TCP_CWND_DEBUG
463 LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"U32_F", cwnd %"U16_F", wnd %"U32_F", effwnd %"U32_F", seq %"U32_F", ack %"U32_F", i %"S16_F"\n",
464 pcb->snd_wnd, pcb->cwnd, wnd,
465 ntohl(seg->tcphdr->seqno) + seg->len -
466 pcb->lastack,
467 ntohl(seg->tcphdr->seqno), pcb->lastack, i));
468 ++i;
469#endif /* TCP_CWND_DEBUG */
470
471 pcb->unsent = seg->next;
472
473 if (pcb->state != SYN_SENT) {
474 TCPH_SET_FLAG(seg->tcphdr, TCP_ACK);
475 pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
476 }
477
478 tcp_output_segment(seg, pcb);
479 pcb->snd_nxt = ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg);
480 if (TCP_SEQ_LT(pcb->snd_max, pcb->snd_nxt)) {
481 pcb->snd_max = pcb->snd_nxt;
482 }
483 /* put segment on unacknowledged list if length > 0 */
484 if (TCP_TCPLEN(seg) > 0) {
485 seg->next = NULL;
486 /* unacked list is empty? */
487 if (pcb->unacked == NULL) {
488 pcb->unacked = seg;
489 useg = seg;
490 /* unacked list is not empty? */
491 } else {
492 /* In the case of fast retransmit, the packet should not go to the tail
493 * of the unacked queue, but rather at the head. We need to check for
494 * this case. -STJ Jul 27, 2004 */
495 if (TCP_SEQ_LT(ntohl(seg->tcphdr->seqno), ntohl(useg->tcphdr->seqno))){
496 /* add segment to head of unacked list */
497 seg->next = pcb->unacked;
498 pcb->unacked = seg;
499 } else {
500 /* add segment to tail of unacked list */
501 useg->next = seg;
502 useg = useg->next;
503 }
504 }
505 /* do not queue empty segments on the unacked list */
506 } else {
507 tcp_seg_free(seg);
508 }
509 seg = pcb->unsent;
510 }
511 return ERR_OK;
512}
513
514/**
515 * Actually send a TCP segment over IP
516 */
517static void
518tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb)
519{
520 u16_t len;
521 struct netif *netif;
522
523 /* The TCP header has already been constructed, but the ackno and
524 wnd fields remain. */
525 seg->tcphdr->ackno = htonl(pcb->rcv_nxt);
526
527 /* silly window avoidance */
528 if (pcb->rcv_wnd < pcb->mss) {
529 seg->tcphdr->wnd = 0;
530 } else {
531 /* advertise our receive window size in this TCP segment */
532 seg->tcphdr->wnd = htons(pcb->rcv_wnd);
533 }
534
535 /* If we don't have a local IP address, we get one by
536 calling ip_route(). */
537 if (ip_addr_isany(&(pcb->local_ip))) {
538 netif = ip_route(&(pcb->remote_ip));
539 if (netif == NULL) {
540 return;
541 }
542 ip_addr_set(&(pcb->local_ip), &(netif->ip_addr));
543 }
544
545 pcb->rtime = 0;
546
547 if (pcb->rttest == 0) {
548 pcb->rttest = tcp_ticks;
549 pcb->rtseq = ntohl(seg->tcphdr->seqno);
550
551 LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_output_segment: rtseq %"U32_F"\n", pcb->rtseq));
552 }
553 LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output_segment: %"U32_F":%"U32_F"\n",
554 htonl(seg->tcphdr->seqno), htonl(seg->tcphdr->seqno) +
555 seg->len));
556
557 len = (u16_t)((u8_t *)seg->tcphdr - (u8_t *)seg->p->payload);
558
559 seg->p->len -= len;
560 seg->p->tot_len -= len;
561
562 seg->p->payload = seg->tcphdr;
563
564 seg->tcphdr->chksum = 0;
565#if CHECKSUM_GEN_TCP
566 seg->tcphdr->chksum = inet_chksum_pseudo(seg->p,
567 &(pcb->local_ip),
568 &(pcb->remote_ip),
569 IP_PROTO_TCP, seg->p->tot_len);
570#endif
571 TCP_STATS_INC(tcp.xmit);
572
573 ip_output(seg->p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
574 IP_PROTO_TCP);
575}
576
577void
578tcp_rst(u32_t seqno, u32_t ackno,
579 struct ip_addr *local_ip, struct ip_addr *remote_ip,
580 u16_t local_port, u16_t remote_port)
581{
582 struct pbuf *p;
583 struct tcp_hdr *tcphdr;
584 p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM);
585 if (p == NULL) {
586 LWIP_DEBUGF(TCP_DEBUG, ("tcp_rst: could not allocate memory for pbuf\n"));
587 return;
588 }
589
590 tcphdr = p->payload;
591 tcphdr->src = htons(local_port);
592 tcphdr->dest = htons(remote_port);
593 tcphdr->seqno = htonl(seqno);
594 tcphdr->ackno = htonl(ackno);
595 TCPH_FLAGS_SET(tcphdr, TCP_RST | TCP_ACK);
596 tcphdr->wnd = htons(TCP_WND);
597 tcphdr->urgp = 0;
598 TCPH_HDRLEN_SET(tcphdr, 5);
599
600 tcphdr->chksum = 0;
601#if CHECKSUM_GEN_TCP
602 tcphdr->chksum = inet_chksum_pseudo(p, local_ip, remote_ip,
603 IP_PROTO_TCP, p->tot_len);
604#endif
605 TCP_STATS_INC(tcp.xmit);
606 /* Send output with hardcoded TTL since we have no access to the pcb */
607 ip_output(p, local_ip, remote_ip, TCP_TTL, 0, IP_PROTO_TCP);
608 pbuf_free(p);
609 LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_rst: seqno %"U32_F" ackno %"U32_F".\n", seqno, ackno));
610}
611
612/* requeue all unacked segments for retransmission */
613void
614tcp_rexmit_rto(struct tcp_pcb *pcb)
615{
616 struct tcp_seg *seg;
617
618 if (pcb->unacked == NULL) {
619 return;
620 }
621
622 /* Move all unacked segments to the head of the unsent queue */
623 for (seg = pcb->unacked; seg->next != NULL; seg = seg->next);
624 /* concatenate unsent queue after unacked queue */
625 seg->next = pcb->unsent;
626 /* unsent queue is the concatenated queue (of unacked, unsent) */
627 pcb->unsent = pcb->unacked;
628 /* unacked queue is now empty */
629 pcb->unacked = NULL;
630
631 pcb->snd_nxt = ntohl(pcb->unsent->tcphdr->seqno);
632 /* increment number of retransmissions */
633 ++pcb->nrtx;
634
635 /* Don't take any RTT measurements after retransmitting. */
636 pcb->rttest = 0;
637
638 /* Do the actual retransmission */
639 tcp_output(pcb);
640}
641
642void
643tcp_rexmit(struct tcp_pcb *pcb)
644{
645 struct tcp_seg *seg;
646
647 if (pcb->unacked == NULL) {
648 return;
649 }
650
651 /* Move the first unacked segment to the unsent queue */
652 seg = pcb->unacked->next;
653 pcb->unacked->next = pcb->unsent;
654 pcb->unsent = pcb->unacked;
655 pcb->unacked = seg;
656
657 pcb->snd_nxt = ntohl(pcb->unsent->tcphdr->seqno);
658
659 ++pcb->nrtx;
660
661 /* Don't take any rtt measurements after retransmitting. */
662 pcb->rttest = 0;
663
664 /* Do the actual retransmission. */
665 tcp_output(pcb);
666
667}
668
669
670void
671tcp_keepalive(struct tcp_pcb *pcb)
672{
673 struct pbuf *p;
674 struct tcp_hdr *tcphdr;
675
676 LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: sending KEEPALIVE probe to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
677 ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip),
678 ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip)));
679
680 LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: tcp_ticks %"U32_F" pcb->tmr %"U32_F" pcb->keep_cnt %"U16_F"\n", tcp_ticks, pcb->tmr, pcb->keep_cnt));
681
682 p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM);
683
684 if(p == NULL) {
685 LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: could not allocate memory for pbuf\n"));
686 return;
687 }
688
689 tcphdr = p->payload;
690 tcphdr->src = htons(pcb->local_port);
691 tcphdr->dest = htons(pcb->remote_port);
692 tcphdr->seqno = htonl(pcb->snd_nxt - 1);
693 tcphdr->ackno = htonl(pcb->rcv_nxt);
694 tcphdr->wnd = htons(pcb->rcv_wnd);
695 tcphdr->urgp = 0;
696 TCPH_HDRLEN_SET(tcphdr, 5);
697
698 tcphdr->chksum = 0;
699#if CHECKSUM_GEN_TCP
700 tcphdr->chksum = inet_chksum_pseudo(p, &pcb->local_ip, &pcb->remote_ip, IP_PROTO_TCP, p->tot_len);
701#endif
702 TCP_STATS_INC(tcp.xmit);
703
704 /* Send output to IP */
705 ip_output(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP);
706
707 pbuf_free(p);
708
709 LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_keepalive: seqno %"U32_F" ackno %"U32_F".\n", pcb->snd_nxt - 1, pcb->rcv_nxt));
710}
711
712#endif /* LWIP_TCP */
713
714
715
716
717
718
719
720
721