]> git.sur5r.net Git - freertos/blob - Demo/lwIP_MCF5235_GCC/lwip/src/core/tcp_out.c
Add PIC24, dsPIC and Coldfire files.
[freertos] / Demo / lwIP_MCF5235_GCC / lwip / src / core / tcp_out.c
1 /**
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.*/
58 static void tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb);
59
60 err_t
61 tcp_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
80 err_t
81 tcp_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  */
114 err_t
115 tcp_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;
358 memerr:
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 */
373 err_t
374 tcp_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  */
517 static void
518 tcp_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
577 void
578 tcp_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 */
613 void
614 tcp_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
642 void
643 tcp_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
670 void
671 tcp_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