source: mainline/uspace/srv/net/tl/tcp/state.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: 5.1 KB
RevLine 
[c5808b41]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/**
[032bbe7]34 * @file TCP entry points (close to those defined in the RFC)
[c5808b41]35 */
36
[d9ce049]37#include <fibril_synch.h>
[c5808b41]38#include <io/log.h>
[32105348]39#include <macros.h>
40#include <mem.h>
[c5808b41]41#include "conn.h"
42#include "state.h"
43#include "tcp_type.h"
[32105348]44#include "tqueue.h"
[c5808b41]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{
[32105348]84 size_t buf_free;
85 size_t xfer_size;
86
[c5808b41]87 log_msg(LVL_DEBUG, "tcp_uc_send()");
[32105348]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);
[c5808b41]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{
[d9ce049]110 size_t xfer_size;
111
[c5808b41]112 log_msg(LVL_DEBUG, "tcp_uc_receive()");
[d9ce049]113
114 fibril_mutex_lock(&conn->rcv_buf_lock);
115
116 /* Wait for data to become available */
[8c7a054]117 while (conn->rcv_buf_used == 0 && !conn->rcv_buf_fin) {
[d9ce049]118 log_msg(LVL_DEBUG, "tcp_uc_receive() - wait for data");
119 fibril_condvar_wait(&conn->rcv_buf_cv, &conn->rcv_buf_lock);
120 }
121
[8c7a054]122 if (conn->rcv_buf_used == 0) {
123 /* End of data, peer closed connection. */
124 /* XXX How should RECEIVE signal end of data? */
125 assert(conn->rcv_buf_fin);
126 *rcvd = 0;
127 *xflags = 0;
128 return;
129 }
130
[d9ce049]131 /* Copy data from receive buffer to user buffer */
132 xfer_size = min(size, conn->rcv_buf_used);
133 memcpy(buf, conn->rcv_buf, xfer_size);
134 *rcvd = xfer_size;
135
136 /* Remove data from receive buffer */
137 memmove(conn->rcv_buf, conn->rcv_buf + xfer_size, conn->rcv_buf_used -
138 xfer_size);
139 conn->rcv_buf_used -= xfer_size;
140 conn->rcv_wnd += xfer_size;
141
142 fibril_mutex_unlock(&conn->rcv_buf_lock);
143
144 /* TODO */
145 *xflags = 0;
146
147 /* Send new size of receive window */
148 tcp_tqueue_ctrl_seg(conn, CTL_ACK);
149
150 log_msg(LVL_DEBUG, "tcp_uc_receive() - returning %zu bytes",
151 xfer_size);
[c5808b41]152}
153
154/** CLOSE user call */
155void tcp_uc_close(tcp_conn_t *conn)
156{
157 log_msg(LVL_DEBUG, "tcp_uc_close()");
[8c7a054]158
159 conn->snd_buf_fin = true;
160 tcp_tqueue_new_data(conn);
[c5808b41]161}
162
163/** ABORT user call */
164void tcp_uc_abort(tcp_conn_t *conn)
165{
166 log_msg(LVL_DEBUG, "tcp_uc_abort()");
167}
168
169/** STATUS user call */
170void tcp_uc_status(tcp_conn_t *conn, tcp_conn_status_t *cstatus)
171{
172 log_msg(LVL_DEBUG, "tcp_uc_status()");
173}
174
175
176/*
177 * Arriving segments
178 */
179
180/** Segment arrived */
181void tcp_as_segment_arrived(tcp_sockpair_t *sp, tcp_segment_t *seg)
182{
183 tcp_conn_t *conn;
184
185 log_msg(LVL_DEBUG, "tcp_as_segment_arrived()");
186
187 conn = tcp_conn_find(sp);
188 if (conn != NULL) {
189 tcp_conn_segment_arrived(conn, seg);
190 } else {
191 tcp_unexpected_segment(sp, seg);
192 }
193}
194
195/*
196 * Timeouts
197 */
198
199/** User timeout */
200void tcp_to_user(void)
201{
202 log_msg(LVL_DEBUG, "tcp_to_user()");
203}
204
205/** Retransmission timeout */
206void tcp_to_retransmit(void)
207{
208 log_msg(LVL_DEBUG, "tcp_to_retransmit()");
209}
210
211/** Time-wait timeout */
212void tcp_to_time_wait(void)
213{
214 log_msg(LVL_DEBUG, "tcp_to_time_wait()");
215}
216
217/**
218 * @}
219 */
Note: See TracBrowser for help on using the repository browser.