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

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

Implement RECEIVE user call.

  • Property mode set to 100644
File size: 4.0 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 data_size;
95 tcp_segment_t *seg;
96
97 log_msg(LVL_DEBUG, "tcp_tqueue_new_data()");
98
99 /* Number of free sequence numbers in send window */
100 avail_wnd = (conn->snd_una + conn->snd_wnd) - conn->snd_nxt;
101
102 data_size = min(conn->snd_buf_used, avail_wnd);
103 log_msg(LVL_DEBUG, "conn->snd_buf_used = %zu, SND.WND = %zu, "
104 "data_size = %zu", conn->snd_buf_used, conn->snd_wnd, data_size);
105
106 if (data_size == 0)
107 return;
108
109 /* XXX Do not always send immediately */
110
111 seg = tcp_segment_make_data(0, conn->snd_buf, data_size);
112 if (seg == NULL) {
113 log_msg(LVL_ERROR, "Memory allocation failure.");
114 return;
115 }
116
117 /* Remove data from send buffer */
118 memmove(conn->snd_buf, conn->snd_buf + data_size,
119 conn->snd_buf_used - data_size);
120 conn->snd_buf_used -= data_size;
121
122 tcp_tqueue_seg(conn, seg);
123}
124
125/** Remove ACKed segments from retransmission queue and possibly transmit
126 * more data.
127 *
128 * This should be called when SND.UNA is updated due to incoming ACK.
129 */
130void tcp_tqueue_ack_received(tcp_conn_t *conn)
131{
132 (void) conn;
133
134 tcp_tqueue_new_data(conn);
135}
136
137void tcp_transmit_segment(tcp_sockpair_t *sp, tcp_segment_t *seg)
138{
139 log_msg(LVL_DEBUG, "tcp_transmit_segment(%p, %p)", sp, seg);
140/*
141 tcp_pdu_prepare(conn, seg, &data, &len);
142 tcp_pdu_transmit(data, len);
143*/
144 tcp_rqueue_bounce_seg(sp, seg);
145}
146
147/**
148 * @}
149 */
Note: See TracBrowser for help on using the repository browser.