source: mainline/uspace/srv/net/tl/tcp/tqueue.c@ 8c7a054

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 8c7a054 was 8c7a054, checked in by Jiri Svoboda <jiri@…>, 14 years ago

FIN processing (WIP).

  • Property mode set to 100644
File size: 4.4 KB
Line 
1/*
2 * Copyright (c) 2011 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup tcp
30 * @{
31 */
32
33/**
34 * @file TCP transmission queue
35 */
36
37#include <byteorder.h>
38#include <io/log.h>
39#include <macros.h>
40#include <mem.h>
41#include "conn.h"
42#include "header.h"
43#include "rqueue.h"
44#include "segment.h"
45#include "tqueue.h"
46#include "tcp_type.h"
47
48void tcp_tqueue_ctrl_seg(tcp_conn_t *conn, tcp_control_t ctrl)
49{
50 tcp_segment_t *seg;
51
52 log_msg(LVL_DEBUG, "tcp_tqueue_ctrl_seg(%p, %u)", conn, ctrl);
53
54 seg = tcp_segment_make_ctrl(ctrl);
55 tcp_tqueue_seg(conn, seg);
56}
57
58void tcp_tqueue_seg(tcp_conn_t *conn, tcp_segment_t *seg)
59{
60 log_msg(LVL_DEBUG, "tcp_tqueue_seg(%p, %p)", conn, seg);
61 /* XXX queue */
62
63 /*
64 * Always send ACK once we have received SYN, except for RST segments.
65 * (Spec says we should always send ACK once connection has been
66 * established.)
67 */
68 if (tcp_conn_got_syn(conn) && (seg->ctrl & CTL_RST) == 0)
69 seg->ctrl |= CTL_ACK;
70
71 seg->seq = conn->snd_nxt;
72 seg->wnd = conn->rcv_wnd;
73
74 log_msg(LVL_DEBUG, "SEG.SEQ=%" PRIu32 ", SEG.WND=%" PRIu32,
75 seg->seq, seg->wnd);
76
77 if ((seg->ctrl & CTL_ACK) != 0)
78 seg->ack = conn->rcv_nxt;
79 else
80 seg->ack = 0;
81
82 conn->snd_nxt += seg->len;
83
84 tcp_transmit_segment(&conn->ident, seg);
85}
86
87/** Transmit data from the send buffer.
88 *
89 * @param conn Connection
90 */
91void tcp_tqueue_new_data(tcp_conn_t *conn)
92{
93 size_t avail_wnd;
94 size_t xfer_seqlen;
95 size_t snd_buf_seqlen;
96 size_t data_size;
97 tcp_control_t ctrl;
98
99 tcp_segment_t *seg;
100
101 log_msg(LVL_DEBUG, "tcp_tqueue_new_data()");
102
103 /* Number of free sequence numbers in send window */
104 avail_wnd = (conn->snd_una + conn->snd_wnd) - conn->snd_nxt;
105 snd_buf_seqlen = conn->snd_buf_used + (conn->snd_buf_fin ? 1 : 0);
106
107 xfer_seqlen = min(snd_buf_seqlen, avail_wnd);
108 log_msg(LVL_DEBUG, "snd_buf_seqlen = %zu, SND.WND = %zu, "
109 "xfer_seqlen = %zu", snd_buf_seqlen, conn->snd_wnd,
110 xfer_seqlen);
111
112 if (xfer_seqlen == 0)
113 return;
114
115 /* XXX Do not always send immediately */
116
117 data_size = xfer_seqlen - (conn->snd_buf_fin ? 1 : 0);
118 if (conn->snd_buf_fin && data_size + 1 == xfer_seqlen) {
119 /* We are sending out FIN */
120 ctrl = CTL_FIN;
121 } else {
122 ctrl = 0;
123 }
124
125 seg = tcp_segment_make_data(ctrl, conn->snd_buf, data_size);
126 if (seg == NULL) {
127 log_msg(LVL_ERROR, "Memory allocation failure.");
128 return;
129 }
130
131 /* Remove data from send buffer */
132 memmove(conn->snd_buf, conn->snd_buf + data_size,
133 conn->snd_buf_used - data_size);
134 conn->snd_buf_used -= data_size;
135 conn->snd_buf_fin = false;
136
137 tcp_tqueue_seg(conn, seg);
138}
139
140/** Remove ACKed segments from retransmission queue and possibly transmit
141 * more data.
142 *
143 * This should be called when SND.UNA is updated due to incoming ACK.
144 */
145void tcp_tqueue_ack_received(tcp_conn_t *conn)
146{
147 (void) conn;
148
149 tcp_tqueue_new_data(conn);
150}
151
152void tcp_transmit_segment(tcp_sockpair_t *sp, tcp_segment_t *seg)
153{
154 log_msg(LVL_DEBUG, "tcp_transmit_segment(%p, %p)", sp, seg);
155/*
156 tcp_pdu_prepare(conn, seg, &data, &len);
157 tcp_pdu_transmit(data, len);
158*/
159 tcp_rqueue_bounce_seg(sp, seg);
160}
161
162/**
163 * @}
164 */
Note: See TracBrowser for help on using the repository browser.