source: mainline/uspace/srv/net/tl/tcp/state.c@ 7cf7ded

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

TCP retransmission (WIP). Allow setting timer in timer handler.
Simulate packet drop. Fixes.

  • Property mode set to 100644
File size: 5.2 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 entry points (close to those defined in the RFC)
35 */
36
37#include <fibril_synch.h>
38#include <io/log.h>
39#include <macros.h>
40#include <mem.h>
41#include "conn.h"
42#include "state.h"
43#include "tcp_type.h"
44#include "tqueue.h"
45
46/*
47 * User calls
48 */
49
50/** OPEN user call
51 *
52 * @param lport Local port
53 * @param fsock Foreign socket
54 * @param acpass Active/passive
55 * @param conn Connection
56 */
57void tcp_uc_open(uint16_t lport, tcp_sock_t *fsock, acpass_t acpass,
58 tcp_conn_t **conn)
59{
60 tcp_conn_t *nconn;
61 tcp_sock_t lsock;
62
63 log_msg(LVL_DEBUG, "tcp_uc_open(%" PRIu16 ", %p, %s, %p)",
64 lport, fsock, acpass == ap_active ? "active" : "passive",
65 conn);
66
67 lsock.port = lport;
68 lsock.addr.ipv4 = 0x7f000001;
69
70 nconn = tcp_conn_new(&lsock, fsock);
71 tcp_conn_add(nconn);
72
73 if (acpass == ap_active) {
74 /* Synchronize (initiate) connection */
75 tcp_conn_sync(nconn);
76 }
77
78 *conn = nconn;
79}
80
81/** SEND user call */
82void tcp_uc_send(tcp_conn_t *conn, void *data, size_t size, xflags_t flags)
83{
84 size_t buf_free;
85 size_t xfer_size;
86
87 log_msg(LVL_DEBUG, "tcp_uc_send()");
88
89 while (size > 0) {
90 buf_free = conn->snd_buf_size - conn->snd_buf_used;
91 while (buf_free == 0)
92 tcp_tqueue_new_data(conn);
93
94 xfer_size = min(size, buf_free);
95
96 /* Copy data to buffer */
97 memcpy(conn->snd_buf + conn->snd_buf_used, data, xfer_size);
98 data += xfer_size;
99 conn->snd_buf_used += xfer_size;
100 size -= xfer_size;
101 }
102
103 tcp_tqueue_new_data(conn);
104}
105
106/** RECEIVE user call */
107void tcp_uc_receive(tcp_conn_t *conn, void *buf, size_t size, size_t *rcvd,
108 xflags_t *xflags)
109{
110 size_t xfer_size;
111
112 log_msg(LVL_DEBUG, "tcp_uc_receive()");
113
114 /*
115 * XXX Handle all states for all user calls properly, return
116 * errors as appropriate.
117 */
118 if (conn->cstate == st_closed)
119 return;
120
121
122 fibril_mutex_lock(&conn->rcv_buf_lock);
123
124 /* Wait for data to become available */
125 while (conn->rcv_buf_used == 0 && !conn->rcv_buf_fin) {
126 log_msg(LVL_DEBUG, "tcp_uc_receive() - wait for data");
127 fibril_condvar_wait(&conn->rcv_buf_cv, &conn->rcv_buf_lock);
128 }
129
130 if (conn->rcv_buf_used == 0) {
131 /* End of data, peer closed connection. */
132 /* XXX How should RECEIVE signal end of data? */
133 assert(conn->rcv_buf_fin);
134 *rcvd = 0;
135 *xflags = 0;
136 return;
137 }
138
139 /* Copy data from receive buffer to user buffer */
140 xfer_size = min(size, conn->rcv_buf_used);
141 memcpy(buf, conn->rcv_buf, xfer_size);
142 *rcvd = xfer_size;
143
144 /* Remove data from receive buffer */
145 memmove(conn->rcv_buf, conn->rcv_buf + xfer_size, conn->rcv_buf_used -
146 xfer_size);
147 conn->rcv_buf_used -= xfer_size;
148 conn->rcv_wnd += xfer_size;
149
150 fibril_mutex_unlock(&conn->rcv_buf_lock);
151
152 /* TODO */
153 *xflags = 0;
154
155 /* Send new size of receive window */
156 tcp_tqueue_ctrl_seg(conn, CTL_ACK);
157
158 log_msg(LVL_DEBUG, "tcp_uc_receive() - returning %zu bytes",
159 xfer_size);
160}
161
162/** CLOSE user call */
163void tcp_uc_close(tcp_conn_t *conn)
164{
165 log_msg(LVL_DEBUG, "tcp_uc_close()");
166
167 conn->snd_buf_fin = true;
168 tcp_tqueue_new_data(conn);
169}
170
171/** ABORT user call */
172void tcp_uc_abort(tcp_conn_t *conn)
173{
174 log_msg(LVL_DEBUG, "tcp_uc_abort()");
175}
176
177/** STATUS user call */
178void tcp_uc_status(tcp_conn_t *conn, tcp_conn_status_t *cstatus)
179{
180 log_msg(LVL_DEBUG, "tcp_uc_status()");
181}
182
183
184/*
185 * Arriving segments
186 */
187
188/** Segment arrived */
189void tcp_as_segment_arrived(tcp_sockpair_t *sp, tcp_segment_t *seg)
190{
191 tcp_conn_t *conn;
192
193 log_msg(LVL_DEBUG, "tcp_as_segment_arrived()");
194
195 conn = tcp_conn_find(sp);
196 if (conn != NULL && conn->cstate != st_closed) {
197 tcp_conn_segment_arrived(conn, seg);
198 } else {
199 tcp_unexpected_segment(sp, seg);
200 }
201}
202
203/*
204 * Timeouts
205 */
206
207/** User timeout */
208void tcp_to_user(void)
209{
210 log_msg(LVL_DEBUG, "tcp_to_user()");
211}
212
213/** Retransmission timeout */
214void tcp_to_retransmit(void)
215{
216 log_msg(LVL_DEBUG, "tcp_to_retransmit()");
217}
218
219/**
220 * @}
221 */
Note: See TracBrowser for help on using the repository browser.