29
29
/** @addtogroup tcp
34
* TCP module implementation.
34
* TCP module implementation.
38
38
#include <assert.h>
40
40
#include <fibril_synch.h>
41
41
#include <malloc.h>
42
/* TODO remove stdio */
46
46
#include <ipc/services.h>
49
#include <net_messages.h>
50
#include <net_modules.h>
49
#include <ipc/socket.h>
51
#include <net/socket_codes.h>
52
#include <net/ip_protocols.h>
56
#include <net/modules.h>
51
58
#include <adt/dynamic_fifo.h>
52
#include <packet/packet_client.h>
59
#include <packet_client.h>
53
60
#include <packet_remote.h>
54
61
#include <net_checksum.h>
58
62
#include <ip_client.h>
59
63
#include <ip_interface.h>
60
#include <ip_protocols.h>
61
64
#include <icmp_client.h>
62
#include <icmp_interface.h>
65
#include <icmp_remote.h>
63
66
#include <net_interface.h>
64
#include <socket_codes.h>
65
#include <socket_errno.h>
66
#include <tcp_codes.h>
67
67
#include <socket_core.h>
68
#include <socket_messages.h>
69
68
#include <tl_common.h>
70
#include <tl_messages.h>
72
#include <tl_interface.h>
69
#include <tl_remote.h>
75
73
#include "tcp_header.h"
76
#include "tcp_module.h"
80
#define NAME "TCP protocol"
82
/** The TCP window default value.
84
#define NET_DEFAULT_TCP_WINDOW 10240
86
/** Initial timeout for new connections.
75
/** TCP module name. */
78
/** The TCP window default value. */
79
#define NET_DEFAULT_TCP_WINDOW 10240
81
/** Initial timeout for new connections. */
88
82
#define NET_DEFAULT_TCP_INITIAL_TIMEOUT 3000000L
90
/** Default timeout for closing.
92
#define NET_DEFAULT_TCP_TIME_WAIT_TIMEOUT 2000L
94
/** The initial outgoing sequence number.
96
#define TCP_INITIAL_SEQUENCE_NUMBER 2999
98
/** Maximum TCP fragment size.
100
#define MAX_TCP_FRAGMENT_SIZE 65535
102
/** Free ports pool start.
104
#define TCP_FREE_PORTS_START 1025
106
/** Free ports pool end.
84
/** Default timeout for closing. */
85
#define NET_DEFAULT_TCP_TIME_WAIT_TIMEOUT 2000L
87
/** The initial outgoing sequence number. */
88
#define TCP_INITIAL_SEQUENCE_NUMBER 2999
90
/** Maximum TCP fragment size. */
91
#define MAX_TCP_FRAGMENT_SIZE 65535
93
/** Free ports pool start. */
94
#define TCP_FREE_PORTS_START 1025
96
/** Free ports pool end. */
108
97
#define TCP_FREE_PORTS_END 65535
110
/** Timeout for connection initialization, SYN sent.
112
#define TCP_SYN_SENT_TIMEOUT 1000000L
99
/** Timeout for connection initialization, SYN sent. */
100
#define TCP_SYN_SENT_TIMEOUT 1000000L
114
/** The maximum number of timeouts in a row before singaling connection lost.
102
/** The maximum number of timeouts in a row before singaling connection lost. */
116
103
#define TCP_MAX_TIMEOUTS 8
118
/** The number of acknowledgements before retransmit.
105
/** The number of acknowledgements before retransmit. */
120
106
#define TCP_FAST_RETRANSMIT_COUNT 3
122
/** Returns a value indicating whether the value is in the interval respecting the possible overflow.
123
* The high end and/or the value may overflow, be lower than the low value.
124
* @param[in] lower The last value before the interval.
125
* @param[in] value The value to be checked.
126
* @param[in] higher_equal The last value in the interval.
108
/** Returns a value indicating whether the value is in the interval respecting
109
* the possible overflow.
111
* The high end and/or the value may overflow, be lower than the low value.
113
* @param[in] lower The last value before the interval.
114
* @param[in] value The value to be checked.
115
* @param[in] higher_equal The last value in the interval.
128
#define IS_IN_INTERVAL_OVERFLOW(lower, value, higher_equal) ((((lower) < (value)) && (((value) <= (higher_equal)) || ((higher_equal) < (lower)))) || (((value) <= (higher_equal)) && ((higher_equal) < (lower))))
117
#define IS_IN_INTERVAL_OVERFLOW(lower, value, higher_equal) \
118
((((lower) < (value)) && (((value) <= (higher_equal)) || \
119
((higher_equal) < (lower)))) || (((value) <= (higher_equal)) && \
120
((higher_equal) < (lower))))
130
122
/** Type definition of the TCP timeout.
131
123
* @see tcp_timeout
133
typedef struct tcp_timeout tcp_timeout_t;
135
/** Type definition of the TCP timeout pointer.
138
typedef tcp_timeout_t * tcp_timeout_ref;
125
typedef struct tcp_timeout tcp_timeout_t;
140
127
/** TCP reply timeout data.
141
128
* Used as a timeouting fibril argument.
142
129
* @see tcp_timeout()
145
/** TCP global data are going to be read only.
132
/** TCP global data are going to be read only. */
147
133
int globals_read_only;
153
socket_cores_ref local_sockets;
154
/** Socket identifier.
138
/** Local sockets. */
139
socket_cores_t *local_sockets;
141
/** Socket identifier. */
159
145
tcp_socket_state_t state;
160
/** Sent packet sequence number.
147
/** Sent packet sequence number. */
162
148
int sequence_number;
163
/** Timeout in microseconds.
150
/** Timeout in microseconds. */
165
151
suseconds_t timeout;
169
/** Port map key length.
156
/** Port map key length. */
171
157
size_t key_length;
174
/** Releases the packet and returns the result.
175
* @param[in] packet The packet queue to be released.
176
* @param[in] result The result to be returned.
177
* @return The result parameter.
179
int tcp_release_and_return(packet_t packet, int result);
181
void tcp_prepare_operation_header(socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, int synchronize, int finalize);
182
int tcp_prepare_timeout(int (*timeout_function)(void * tcp_timeout_t), socket_core_ref socket, tcp_socket_data_ref socket_data, size_t sequence_number, tcp_socket_state_t state, suseconds_t timeout, int globals_read_only);
183
void tcp_free_socket_data(socket_core_ref socket);
184
int tcp_timeout(void * data);
185
int tcp_release_after_timeout(void * data);
186
int tcp_process_packet(device_id_t device_id, packet_t packet, services_t error);
187
int tcp_connect_core(socket_core_ref socket, socket_cores_ref local_sockets, struct sockaddr * addr, socklen_t addrlen);
188
int tcp_queue_prepare_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length);
189
int tcp_queue_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length);
190
packet_t tcp_get_packets_to_send(socket_core_ref socket, tcp_socket_data_ref socket_data);
191
void tcp_send_packets(device_id_t device_id, packet_t packet);
192
void tcp_process_acknowledgement(socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header);
193
packet_t tcp_send_prepare_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length, size_t sequence_number);
194
packet_t tcp_prepare_copy(socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length, size_t sequence_number);
195
void tcp_retransmit_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, size_t sequence_number);
196
int tcp_create_notification_packet(packet_t * packet, socket_core_ref socket, tcp_socket_data_ref socket_data, int synchronize, int finalize);
197
void tcp_refresh_socket_data(tcp_socket_data_ref socket_data);
198
void tcp_initialize_socket_data(tcp_socket_data_ref socket_data);
199
int tcp_process_listen(socket_core_ref listening_socket, tcp_socket_data_ref listening_socket_data, tcp_header_ref header, packet_t packet, struct sockaddr * src, struct sockaddr * dest, size_t addrlen);
200
int tcp_process_syn_sent(socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet);
201
int tcp_process_syn_received(socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet);
202
int tcp_process_established(socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet, int fragments, size_t total_length);
203
int tcp_queue_received_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, int fragments, size_t total_length);
205
int tcp_received_msg(device_id_t device_id, packet_t packet, services_t receiver, services_t error);
206
int tcp_process_client_messages(ipc_callid_t callid, ipc_call_t call);
207
int tcp_listen_message(socket_cores_ref local_sockets, int socket_id, int backlog);
208
int tcp_connect_message(socket_cores_ref local_sockets, int socket_id, struct sockaddr * addr, socklen_t addrlen);
209
int tcp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, int flags, size_t * addrlen);
210
int tcp_send_message(socket_cores_ref local_sockets, int socket_id, int fragments, size_t * data_fragment_size, int flags);
211
int tcp_accept_message(socket_cores_ref local_sockets, int socket_id, int new_socket_id, size_t * data_fragment_size, size_t * addrlen);
212
int tcp_close_message(socket_cores_ref local_sockets, int socket_id);
216
tcp_globals_t tcp_globals;
218
int tcp_initialize(async_client_conn_t client_connection){
221
assert(client_connection);
222
fibril_rwlock_initialize(&tcp_globals.lock);
223
fibril_rwlock_write_lock(&tcp_globals.lock);
224
tcp_globals.icmp_phone = icmp_connect_module(SERVICE_ICMP, ICMP_CONNECT_TIMEOUT);
225
tcp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_TCP, SERVICE_TCP, client_connection, tcp_received_msg);
226
if(tcp_globals.ip_phone < 0){
227
return tcp_globals.ip_phone;
229
ERROR_PROPAGATE(socket_ports_initialize(&tcp_globals.sockets));
230
if(ERROR_OCCURRED(packet_dimensions_initialize(&tcp_globals.dimensions))){
231
socket_ports_destroy(&tcp_globals.sockets);
234
tcp_globals.last_used_port = TCP_FREE_PORTS_START - 1;
235
fibril_rwlock_write_unlock(&tcp_globals.lock);
239
int tcp_received_msg(device_id_t device_id, packet_t packet, services_t receiver, services_t error){
242
if(receiver != SERVICE_TCP){
160
static int tcp_release_and_return(packet_t *, int);
161
static void tcp_prepare_operation_header(socket_core_t *, tcp_socket_data_t *,
162
tcp_header_t *, int synchronize, int);
163
static int tcp_prepare_timeout(int (*)(void *), socket_core_t *,
164
tcp_socket_data_t *, size_t, tcp_socket_state_t, suseconds_t, int);
165
static void tcp_free_socket_data(socket_core_t *);
167
static int tcp_timeout(void *);
169
static int tcp_release_after_timeout(void *);
171
static int tcp_process_packet(device_id_t, packet_t *, services_t);
172
static int tcp_connect_core(socket_core_t *, socket_cores_t *,
173
struct sockaddr *, socklen_t);
174
static int tcp_queue_prepare_packet(socket_core_t *, tcp_socket_data_t *,
176
static int tcp_queue_packet(socket_core_t *, tcp_socket_data_t *, packet_t *,
178
static packet_t *tcp_get_packets_to_send(socket_core_t *, tcp_socket_data_t *);
179
static void tcp_send_packets(device_id_t, packet_t *);
181
static void tcp_process_acknowledgement(socket_core_t *, tcp_socket_data_t *,
183
static packet_t *tcp_send_prepare_packet(socket_core_t *, tcp_socket_data_t *,
184
packet_t *, size_t, size_t);
185
static packet_t *tcp_prepare_copy(socket_core_t *, tcp_socket_data_t *,
186
packet_t *, size_t, size_t);
187
/* static */ void tcp_retransmit_packet(socket_core_t *, tcp_socket_data_t *,
189
static int tcp_create_notification_packet(packet_t **, socket_core_t *,
190
tcp_socket_data_t *, int, int);
191
static void tcp_refresh_socket_data(tcp_socket_data_t *);
193
static void tcp_initialize_socket_data(tcp_socket_data_t *);
195
static int tcp_process_listen(socket_core_t *, tcp_socket_data_t *,
196
tcp_header_t *, packet_t *, struct sockaddr *, struct sockaddr *, size_t);
197
static int tcp_process_syn_sent(socket_core_t *, tcp_socket_data_t *,
198
tcp_header_t *, packet_t *);
199
static int tcp_process_syn_received(socket_core_t *, tcp_socket_data_t *,
200
tcp_header_t *, packet_t *);
201
static int tcp_process_established(socket_core_t *, tcp_socket_data_t *,
202
tcp_header_t *, packet_t *, int, size_t);
203
static int tcp_queue_received_packet(socket_core_t *, tcp_socket_data_t *,
204
packet_t *, int, size_t);
205
static void tcp_queue_received_end_of_data(socket_core_t *socket);
207
static int tcp_received_msg(device_id_t, packet_t *, services_t, services_t);
208
static int tcp_process_client_messages(ipc_callid_t, ipc_call_t);
210
static int tcp_listen_message(socket_cores_t *, int, int);
211
static int tcp_connect_message(socket_cores_t *, int, struct sockaddr *,
213
static int tcp_recvfrom_message(socket_cores_t *, int, int, size_t *);
214
static int tcp_send_message(socket_cores_t *, int, int, size_t *, int);
215
static int tcp_accept_message(socket_cores_t *, int, int, size_t *, size_t *);
216
static int tcp_close_message(socket_cores_t *, int);
218
/** TCP global data. */
219
tcp_globals_t tcp_globals;
221
int tcp_received_msg(device_id_t device_id, packet_t *packet,
222
services_t receiver, services_t error)
226
if (receiver != SERVICE_TCP)
245
229
fibril_rwlock_write_lock(&tcp_globals.lock);
246
if(ERROR_OCCURRED(tcp_process_packet(device_id, packet, error))){
230
rc = tcp_process_packet(device_id, packet, error);
247
232
fibril_rwlock_write_unlock(&tcp_globals.lock);
249
printf("receive %d \n", ERROR_CODE);
234
printf("receive %d \n", rc);
254
int tcp_process_packet(device_id_t device_id, packet_t packet, services_t error){
239
int tcp_process_packet(device_id_t device_id, packet_t *packet, services_t error)
260
tcp_header_ref header;
261
socket_core_ref socket;
262
tcp_socket_data_ref socket_data;
263
packet_t next_packet;
244
tcp_header_t *header;
245
socket_core_t *socket;
246
tcp_socket_data_t *socket_data;
247
packet_t *next_packet;
264
248
size_t total_length;
265
249
uint32_t checksum;
267
251
icmp_type_t type;
268
252
icmp_code_t code;
269
struct sockaddr * src;
270
struct sockaddr * dest;
253
struct sockaddr *src;
254
struct sockaddr *dest;
278
result = icmp_client_process_packet(packet, &type, &code, NULL, NULL);
280
return tcp_release_and_return(packet, result);
282
length = (size_t) result;
283
if(ERROR_OCCURRED(packet_trim(packet, length, 0))){
284
return tcp_release_and_return(packet, ERROR_CODE);
288
return tcp_release_and_return(packet, ENOTSUP);
263
result = icmp_client_process_packet(packet, &type, &code, NULL,
266
return tcp_release_and_return(packet, result);
268
length = (size_t) result;
269
rc = packet_trim(packet, length, 0);
271
return tcp_release_and_return(packet, rc);
274
return tcp_release_and_return(packet, ENOTSUP);
292
// TODO process received ipopts?
277
/* TODO process received ipopts? */
293
278
result = ip_client_process_packet(packet, NULL, NULL, NULL, NULL, NULL);
294
// printf("ip len %d\n", result);
296
280
return tcp_release_and_return(packet, result);
298
282
offset = (size_t) result;
300
284
length = packet_get_data_length(packet);
301
// printf("packet len %d\n", length);
303
286
return tcp_release_and_return(packet, EINVAL);
305
if(length < TCP_HEADER_SIZE + offset){
306
return tcp_release_and_return(packet, NO_DATA);
309
// trim all but TCP header
310
if(ERROR_OCCURRED(packet_trim(packet, offset, 0))){
311
return tcp_release_and_return(packet, ERROR_CODE);
315
header = (tcp_header_ref) packet_get_data(packet);
317
return tcp_release_and_return(packet, NO_DATA);
319
// printf("header len %d, port %d \n", TCP_HEADER_LENGTH(header), ntohs(header->destination_port));
288
if (length < TCP_HEADER_SIZE + offset)
289
return tcp_release_and_return(packet, NO_DATA);
291
/* Trim all but TCP header */
292
rc = packet_trim(packet, offset, 0);
294
return tcp_release_and_return(packet, rc);
297
header = (tcp_header_t *) packet_get_data(packet);
299
return tcp_release_and_return(packet, NO_DATA);
302
printf("header len %d, port %d \n", TCP_HEADER_LENGTH(header),
303
ntohs(header->destination_port));
321
305
result = packet_get_addr(packet, (uint8_t **) &src, (uint8_t **) &dest);
323
307
return tcp_release_and_return(packet, result);
325
309
addrlen = (size_t) result;
327
if(ERROR_OCCURRED(tl_set_address_port(src, addrlen, ntohs(header->source_port)))){
328
return tcp_release_and_return(packet, ERROR_CODE);
311
rc = tl_set_address_port(src, addrlen, ntohs(header->source_port));
313
return tcp_release_and_return(packet, rc);
315
/* Find the destination socket */
316
socket = socket_port_find(&tcp_globals.sockets,
317
ntohs(header->destination_port), (uint8_t *) src, addrlen);
319
/* Find the listening destination socket */
320
socket = socket_port_find(&tcp_globals.sockets,
321
ntohs(header->destination_port),
322
(uint8_t *) SOCKET_MAP_KEY_LISTENING, 0);
331
// find the destination socket
332
socket = socket_port_find(&tcp_globals.sockets, ntohs(header->destination_port), (const char *) src, addrlen);
334
// printf("listening?\n");
335
// find the listening destination socket
336
socket = socket_port_find(&tcp_globals.sockets, ntohs(header->destination_port), SOCKET_MAP_KEY_LISTENING, 0);
338
if(tl_prepare_icmp_packet(tcp_globals.net_phone, tcp_globals.icmp_phone, packet, error) == EOK){
339
icmp_destination_unreachable_msg(tcp_globals.icmp_phone, ICMP_PORT_UNREACH, 0, packet);
341
return EADDRNOTAVAIL;
326
if (tl_prepare_icmp_packet(tcp_globals.net_phone,
327
tcp_globals.icmp_phone, packet, error) == EOK) {
328
icmp_destination_unreachable_msg(tcp_globals.icmp_phone,
329
ICMP_PORT_UNREACH, 0, packet);
331
return EADDRNOTAVAIL;
344
334
printf("socket id %d\n", socket->socket_id);
345
socket_data = (tcp_socket_data_ref) socket->specific_data;
335
socket_data = (tcp_socket_data_t *) socket->specific_data;
346
336
assert(socket_data);
348
// some data received, clear the timeout counter
338
/* Some data received, clear the timeout counter */
349
339
socket_data->timeout_count = 0;
351
// count the received packet fragments
341
/* Count the received packet fragments */
352
342
next_packet = packet;
355
345
total_length = 0;
358
348
length = packet_get_data_length(next_packet);
360
350
return tcp_release_and_return(packet, NO_DATA);
362
352
total_length += length;
363
// add partial checksum if set
365
checksum = compute_checksum(checksum, packet_get_data(packet), packet_get_data_length(packet));
354
/* Add partial checksum if set */
356
checksum = compute_checksum(checksum,
357
packet_get_data(packet),
358
packet_get_data_length(packet));
367
}while((next_packet = pq_next(next_packet)));
368
// printf("fragments %d of %d bytes\n", fragments, total_length);
370
// printf("lock?\n");
361
} while ((next_packet = pq_next(next_packet)));
371
363
fibril_rwlock_write_lock(socket_data->local_lock);
372
// printf("locked\n");
374
if(socket_data->state == TCP_SOCKET_LISTEN){
375
if(socket_data->pseudo_header){
376
free(socket_data->pseudo_header);
377
socket_data->pseudo_header = NULL;
378
socket_data->headerlen = 0;
380
if(ERROR_OCCURRED(ip_client_get_pseudo_header(IPPROTO_TCP, src, addrlen, dest, addrlen, total_length, &socket_data->pseudo_header, &socket_data->headerlen))){
381
fibril_rwlock_write_unlock(socket_data->local_lock);
382
return tcp_release_and_return(packet, ERROR_CODE);
384
}else if(ERROR_OCCURRED(ip_client_set_pseudo_header_data_length(socket_data->pseudo_header, socket_data->headerlen, total_length))){
385
fibril_rwlock_write_unlock(socket_data->local_lock);
386
return tcp_release_and_return(packet, ERROR_CODE);
388
checksum = compute_checksum(checksum, socket_data->pseudo_header, socket_data->headerlen);
389
if(flip_checksum(compact_checksum(checksum)) != IP_CHECKSUM_ZERO){
390
printf("checksum err %x -> %x\n", header->checksum, flip_checksum(compact_checksum(checksum)));
391
fibril_rwlock_write_unlock(socket_data->local_lock);
392
if(! ERROR_OCCURRED(tl_prepare_icmp_packet(tcp_globals.net_phone, tcp_globals.icmp_phone, packet, error))){
393
// checksum error ICMP
394
icmp_parameter_problem_msg(tcp_globals.icmp_phone, ICMP_PARAM_POINTER, ((size_t) ((void *) &header->checksum)) - ((size_t) ((void *) header)), packet);
400
fibril_rwlock_read_unlock(&tcp_globals.lock);
402
// TODO error reporting/handling
403
// printf("st %d\n", socket_data->state);
404
switch(socket_data->state){
405
case TCP_SOCKET_LISTEN:
406
ERROR_CODE = tcp_process_listen(socket, socket_data, header, packet, src, dest, addrlen);
408
case TCP_SOCKET_SYN_RECEIVED:
409
ERROR_CODE = tcp_process_syn_received(socket, socket_data, header, packet);
411
case TCP_SOCKET_SYN_SENT:
412
ERROR_CODE = tcp_process_syn_sent(socket, socket_data, header, packet);
414
case TCP_SOCKET_FIN_WAIT_1:
415
// ack changing the state to FIN_WAIT_2 gets processed later
416
case TCP_SOCKET_FIN_WAIT_2:
417
// fin changing state to LAST_ACK gets processed later
418
case TCP_SOCKET_LAST_ACK:
419
// ack releasing the socket get processed later
420
case TCP_SOCKET_CLOSING:
421
// ack releasing the socket gets processed later
422
case TCP_SOCKET_ESTABLISHED:
423
ERROR_CODE = tcp_process_established(socket, socket_data, header, packet, fragments, total_length);
426
pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
429
if(ERROR_CODE != EOK){
430
printf("process %d\n", ERROR_CODE);
431
fibril_rwlock_write_unlock(socket_data->local_lock);
366
goto has_error_service;
368
if (socket_data->state == TCP_SOCKET_LISTEN) {
369
if (socket_data->pseudo_header) {
370
free(socket_data->pseudo_header);
371
socket_data->pseudo_header = NULL;
372
socket_data->headerlen = 0;
375
rc = ip_client_get_pseudo_header(IPPROTO_TCP, src, addrlen,
376
dest, addrlen, total_length, &socket_data->pseudo_header,
377
&socket_data->headerlen);
379
fibril_rwlock_write_unlock(socket_data->local_lock);
380
return tcp_release_and_return(packet, rc);
383
rc = ip_client_set_pseudo_header_data_length(
384
socket_data->pseudo_header, socket_data->headerlen,
387
fibril_rwlock_write_unlock(socket_data->local_lock);
388
return tcp_release_and_return(packet, rc);
392
checksum = compute_checksum(checksum, socket_data->pseudo_header,
393
socket_data->headerlen);
394
if (flip_checksum(compact_checksum(checksum)) != IP_CHECKSUM_ZERO) {
395
printf("checksum err %x -> %x\n", header->checksum,
396
flip_checksum(compact_checksum(checksum)));
397
fibril_rwlock_write_unlock(socket_data->local_lock);
399
rc = tl_prepare_icmp_packet(tcp_globals.net_phone,
400
tcp_globals.icmp_phone, packet, error);
402
/* Checksum error ICMP */
403
icmp_parameter_problem_msg(tcp_globals.icmp_phone,
405
((size_t) ((void *) &header->checksum)) -
406
((size_t) ((void *) header)), packet);
413
fibril_rwlock_write_unlock(&tcp_globals.lock);
415
/* TODO error reporting/handling */
416
switch (socket_data->state) {
417
case TCP_SOCKET_LISTEN:
418
rc = tcp_process_listen(socket, socket_data, header, packet,
421
case TCP_SOCKET_SYN_RECEIVED:
422
rc = tcp_process_syn_received(socket, socket_data, header,
425
case TCP_SOCKET_SYN_SENT:
426
rc = tcp_process_syn_sent(socket, socket_data, header, packet);
428
case TCP_SOCKET_FIN_WAIT_1:
429
/* ack changing the state to FIN_WAIT_2 gets processed later */
430
case TCP_SOCKET_FIN_WAIT_2:
431
/* fin changing state to LAST_ACK gets processed later */
432
case TCP_SOCKET_LAST_ACK:
433
/* ack releasing the socket get processed later */
434
case TCP_SOCKET_CLOSING:
435
/* ack releasing the socket gets processed later */
436
case TCP_SOCKET_ESTABLISHED:
437
rc = tcp_process_established(socket, socket_data, header,
438
packet, fragments, total_length);
441
pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
445
fibril_rwlock_write_unlock(socket_data->local_lock);
446
printf("process %d\n", rc);
436
int tcp_process_established(socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet, int fragments, size_t total_length){
439
packet_t next_packet;
452
int tcp_process_established(socket_core_t *socket, tcp_socket_data_t *
453
socket_data, tcp_header_t *header, packet_t *packet, int fragments,
456
packet_t *next_packet;
457
packet_t *tmp_packet;
441
458
uint32_t old_incoming;
443
460
uint32_t sequence_number;
446
463
uint32_t new_sequence_number;
449
468
assert(socket_data);
454
475
new_sequence_number = ntohl(header->sequence_number);
455
476
old_incoming = socket_data->next_incoming;
457
if(header->finalize){
458
socket_data->fin_incoming = new_sequence_number;
478
if (header->finalize) {
479
socket_data->fin_incoming = new_sequence_number +
480
total_length - TCP_HEADER_LENGTH(header);
461
// printf("pe %d < %d <= %d\n", new_sequence_number, socket_data->next_incoming, new_sequence_number + total_length);
462
// trim begining if containing expected data
463
if(IS_IN_INTERVAL_OVERFLOW(new_sequence_number, socket_data->next_incoming, new_sequence_number + total_length)){
464
// get the acknowledged offset
465
if(socket_data->next_incoming < new_sequence_number){
466
offset = new_sequence_number - socket_data->next_incoming;
468
offset = socket_data->next_incoming - new_sequence_number;
483
/* Trim begining if containing expected data */
484
if (IS_IN_INTERVAL_OVERFLOW(new_sequence_number,
485
socket_data->next_incoming, new_sequence_number + total_length)) {
487
/* Get the acknowledged offset */
488
if (socket_data->next_incoming < new_sequence_number) {
489
offset = new_sequence_number -
490
socket_data->next_incoming;
492
offset = socket_data->next_incoming -
470
// printf("offset %d\n", offset);
471
496
new_sequence_number += offset;
472
497
total_length -= offset;
473
498
length = packet_get_data_length(packet);
474
// trim the acknowledged data
475
while(length <= offset){
476
// release the acknowledged packets
500
/* Trim the acknowledged data */
501
while (length <= offset) {
502
/* Release the acknowledged packets */
477
503
next_packet = pq_next(packet);
478
pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
504
pq_release_remote(tcp_globals.net_phone,
505
packet_get_id(packet));
479
506
packet = next_packet;
480
507
offset -= length;
481
508
length = packet_get_data_length(packet);
484
&& (ERROR_OCCURRED(packet_trim(packet, offset, 0)))){
485
return tcp_release_and_return(packet, ERROR_CODE);
512
rc = packet_trim(packet, offset, 0);
514
return tcp_release_and_return(packet, rc);
487
517
assert(new_sequence_number == socket_data->next_incoming);
490
// release if overflowing the window
491
// if(IS_IN_INTERVAL_OVERFLOW(socket_data->next_incoming + socket_data->window, new_sequence_number, new_sequence_number + total_length)){
492
// return tcp_release_and_return(packet, EOVERFLOW);
520
/* Release if overflowing the window */
522
if (IS_IN_INTERVAL_OVERFLOW(socket_data->next_incoming +
523
socket_data->window, new_sequence_number, new_sequence_number +
525
return tcp_release_and_return(packet, EOVERFLOW);
496
528
// trim end if overflowing the window
497
if(IS_IN_INTERVAL_OVERFLOW(new_sequence_number, socket_data->next_incoming + socket_data->window, new_sequence_number + total_length)){
529
if (IS_IN_INTERVAL_OVERFLOW(new_sequence_number,
530
socket_data->next_incoming + socket_data->window,
531
new_sequence_number + total_length)) {
498
532
// get the allowed data length
499
if(socket_data->next_incoming + socket_data->window < new_sequence_number){
500
offset = new_sequence_number - socket_data->next_incoming + socket_data->window;
502
offset = socket_data->next_incoming + socket_data->window - new_sequence_number;
533
if (socket_data->next_incoming + socket_data->window <
534
new_sequence_number) {
535
offset = new_sequence_number -
536
socket_data->next_incoming + socket_data->window;
538
offset = socket_data->next_incoming +
539
socket_data->window - new_sequence_number;
504
541
next_packet = packet;
505
542
// trim the overflowing data
506
while(next_packet && (offset > 0)){
543
while (next_packet && (offset > 0)) {
507
544
length = packet_get_data_length(packet);
508
if(length <= offset){
545
if (length <= offset)
509
546
next_packet = pq_next(next_packet);
510
}else if(ERROR_OCCURRED(packet_trim(next_packet, 0, length - offset))){
511
return tcp_release_and_return(packet, ERROR_CODE);
548
rc = packet_trim(next_packet, 0,
551
return tcp_release_and_return(packet,
513
554
offset -= length;
514
555
total_length -= length - offset;
516
557
// release the overflowing packets
517
558
next_packet = pq_next(next_packet);
519
560
tmp_packet = next_packet;
520
561
next_packet = pq_next(next_packet);
521
562
pq_insert_after(tmp_packet, next_packet);
522
pq_release_remote(tcp_globals.net_phone, packet_get_id(tmp_packet));
563
pq_release_remote(tcp_globals.net_phone,
564
packet_get_id(tmp_packet));
524
assert(new_sequence_number + total_length == socket_data->next_incoming + socket_data->window);
566
assert(new_sequence_number + total_length ==
567
socket_data->next_incoming + socket_data->window);
527
// the expected one arrived?
528
if(new_sequence_number == socket_data->next_incoming){
570
/* The expected one arrived? */
571
if (new_sequence_number == socket_data->next_incoming) {
529
572
printf("expected\n");
530
// process acknowledgement
573
/* Process acknowledgement */
531
574
tcp_process_acknowledgement(socket, socket_data, header);
576
/* Remove the header */
534
577
total_length -= TCP_HEADER_LENGTH(header);
535
if(ERROR_OCCURRED(packet_trim(packet, TCP_HEADER_LENGTH(header), 0))){
536
return tcp_release_and_return(packet, ERROR_CODE);
578
rc = packet_trim(packet, TCP_HEADER_LENGTH(header), 0);
580
return tcp_release_and_return(packet, rc);
540
ERROR_PROPAGATE(tcp_queue_received_packet(socket, socket_data, packet, fragments, total_length));
583
rc = tcp_queue_received_packet(socket, socket_data,
584
packet, fragments, total_length);
542
588
total_length = 1;
544
591
socket_data->next_incoming = old_incoming + total_length;
545
592
packet = socket_data->incoming;
547
if(ERROR_OCCURRED(pq_get_order(socket_data->incoming, &order, NULL))){
548
// remove the corrupted packet
594
rc = pq_get_order(socket_data->incoming, &order, NULL);
596
/* Remove the corrupted packet */
549
597
next_packet = pq_detach(packet);
550
if(packet == socket_data->incoming){
598
if (packet == socket_data->incoming)
551
599
socket_data->incoming = next_packet;
553
pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
600
pq_release_remote(tcp_globals.net_phone,
601
packet_get_id(packet));
554
602
packet = next_packet;
557
606
sequence_number = (uint32_t) order;
558
if(IS_IN_INTERVAL_OVERFLOW(sequence_number, old_incoming, socket_data->next_incoming)){
607
if (IS_IN_INTERVAL_OVERFLOW(sequence_number,
608
old_incoming, socket_data->next_incoming)) {
609
/* Move to the next */
560
610
packet = pq_next(packet);
562
}else if(IS_IN_INTERVAL_OVERFLOW(old_incoming, sequence_number, socket_data->next_incoming)){
612
} else if (IS_IN_INTERVAL_OVERFLOW(old_incoming,
613
sequence_number, socket_data->next_incoming)) {
614
/* Detach the packet */
564
615
next_packet = pq_detach(packet);
565
if(packet == socket_data->incoming){
616
if (packet == socket_data->incoming)
566
617
socket_data->incoming = next_packet;
618
/* Get data length */
569
619
length = packet_get_data_length(packet);
570
620
new_sequence_number = sequence_number + length;
572
// remove the empty packet
573
pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
574
packet = next_packet;
578
if(sequence_number == socket_data->next_incoming){
579
// queue received data
580
ERROR_PROPAGATE(tcp_queue_received_packet(socket, socket_data, packet, 1, packet_get_data_length(packet)));
581
socket_data->next_incoming = new_sequence_number;
582
packet = next_packet;
584
// at least partly following data?
585
}else if(IS_IN_INTERVAL_OVERFLOW(sequence_number, socket_data->next_incoming, new_sequence_number)){
586
if(socket_data->next_incoming < new_sequence_number){
587
length = new_sequence_number - socket_data->next_incoming;
589
length = socket_data->next_incoming - new_sequence_number;
622
/* Remove the empty packet */
623
pq_release_remote(tcp_globals.net_phone,
624
packet_get_id(packet));
625
packet = next_packet;
628
/* Exactly following */
629
if (sequence_number ==
630
socket_data->next_incoming) {
631
/* Queue received data */
632
rc = tcp_queue_received_packet(socket,
633
socket_data, packet, 1,
634
packet_get_data_length(packet));
637
socket_data->next_incoming =
639
packet = next_packet;
641
/* At least partly following data? */
643
if (IS_IN_INTERVAL_OVERFLOW(sequence_number,
644
socket_data->next_incoming, new_sequence_number)) {
645
if (socket_data->next_incoming <
646
new_sequence_number) {
647
length = new_sequence_number -
648
socket_data->next_incoming;
651
socket_data->next_incoming -
591
if(! ERROR_OCCURRED(packet_trim(packet, length, 0))){
592
// queue received data
593
ERROR_PROPAGATE(tcp_queue_received_packet(socket, socket_data, packet, 1, packet_get_data_length(packet)));
594
socket_data->next_incoming = new_sequence_number;
654
rc = packet_trim(packet,length, 0);
656
/* Queue received data */
657
rc = tcp_queue_received_packet(
658
socket, socket_data, packet,
659
1, packet_get_data_length(
663
socket_data->next_incoming =
595
665
packet = next_packet;
599
// remove the duplicit or corrupted packet
600
pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
669
/* Remove the duplicit or corrupted packet */
670
pq_release_remote(tcp_globals.net_phone,
671
packet_get_id(packet));
601
672
packet = next_packet;
607
}else if(IS_IN_INTERVAL(socket_data->next_incoming, new_sequence_number, socket_data->next_incoming + socket_data->window)){
678
} else if (IS_IN_INTERVAL(socket_data->next_incoming,
680
socket_data->next_incoming + socket_data->window)) {
608
681
printf("in window\n");
609
// process acknowledgement
682
/* Process acknowledgement */
610
683
tcp_process_acknowledgement(socket, socket_data, header);
685
/* Remove the header */
613
686
total_length -= TCP_HEADER_LENGTH(header);
614
if(ERROR_OCCURRED(packet_trim(packet, TCP_HEADER_LENGTH(header), 0))){
615
return tcp_release_and_return(packet, ERROR_CODE);
687
rc = packet_trim(packet, TCP_HEADER_LENGTH(header), 0);
689
return tcp_release_and_return(packet, rc);
618
691
next_packet = pq_detach(packet);
619
692
length = packet_get_data_length(packet);
620
if(ERROR_OCCURRED(pq_add(&socket_data->incoming, packet, new_sequence_number, length))){
621
// remove the corrupted packets
622
pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
623
pq_release_remote(tcp_globals.net_phone, packet_get_id(next_packet));
693
rc = pq_add(&socket_data->incoming, packet, new_sequence_number,
696
/* Remove the corrupted packets */
697
pq_release_remote(tcp_globals.net_phone,
698
packet_get_id(packet));
699
pq_release_remote(tcp_globals.net_phone,
700
packet_get_id(next_packet));
702
while (next_packet) {
626
703
new_sequence_number += length;
627
704
tmp_packet = pq_detach(next_packet);
628
705
length = packet_get_data_length(next_packet);
629
if(ERROR_OCCURRED(pq_set_order(next_packet, new_sequence_number, length))
630
|| ERROR_OCCURRED(pq_insert_after(packet, next_packet))){
631
pq_release_remote(tcp_globals.net_phone, packet_get_id(next_packet));
707
rc = pq_set_order(next_packet,
708
new_sequence_number, length);
710
pq_release_remote(tcp_globals.net_phone,
711
packet_get_id(next_packet));
713
rc = pq_insert_after(packet, next_packet);
715
pq_release_remote(tcp_globals.net_phone,
716
packet_get_id(next_packet));
633
718
next_packet = tmp_packet;
637
722
printf("unexpected\n");
638
// release duplicite or restricted
723
/* Release duplicite or restricted */
639
724
pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
642
// change state according to the acknowledging incoming fin
643
if(IS_IN_INTERVAL_OVERFLOW(old_incoming, socket_data->fin_incoming, socket_data->next_incoming)){
644
switch(socket_data->state){
645
case TCP_SOCKET_FIN_WAIT_1:
646
case TCP_SOCKET_FIN_WAIT_2:
647
case TCP_SOCKET_CLOSING:
648
socket_data->state = TCP_SOCKET_CLOSING;
650
//case TCP_ESTABLISHED:
652
socket_data->state = TCP_SOCKET_CLOSE_WAIT;
728
/* If next in sequence is an incoming FIN */
729
if (socket_data->next_incoming == socket_data->fin_incoming) {
730
/* Advance sequence number */
731
socket_data->next_incoming += 1;
734
switch (socket_data->state) {
735
case TCP_SOCKET_FIN_WAIT_1:
736
case TCP_SOCKET_FIN_WAIT_2:
737
case TCP_SOCKET_CLOSING:
738
socket_data->state = TCP_SOCKET_CLOSING;
740
case TCP_SOCKET_ESTABLISHED:
741
/* Queue end-of-data marker on the socket. */
742
tcp_queue_received_end_of_data(socket);
743
socket_data->state = TCP_SOCKET_CLOSE_WAIT;
746
socket_data->state = TCP_SOCKET_CLOSE_WAIT;
657
751
packet = tcp_get_packets_to_send(socket, socket_data);
659
// create the notification packet
660
ERROR_PROPAGATE(tcp_create_notification_packet(&packet, socket, socket_data, 0, 0));
661
ERROR_PROPAGATE(tcp_queue_prepare_packet(socket, socket_data, packet, 1));
662
packet = tcp_send_prepare_packet(socket, socket_data, packet, 1, socket_data->last_outgoing + 1);
752
if (!packet && (socket_data->next_incoming != old_incoming || forced_ack)) {
753
/* Create the notification packet */
754
rc = tcp_create_notification_packet(&packet, socket,
758
rc = tcp_queue_prepare_packet(socket, socket_data, packet, 1);
761
packet = tcp_send_prepare_packet(socket, socket_data, packet, 1,
762
socket_data->last_outgoing + 1);
664
765
fibril_rwlock_write_unlock(socket_data->local_lock);
767
/* Send the packet */
666
768
tcp_send_packets(socket_data->device_id, packet);
670
int tcp_queue_received_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, int fragments, size_t total_length){
673
packet_dimension_ref packet_dimension;
773
int tcp_queue_received_packet(socket_core_t *socket,
774
tcp_socket_data_t *socket_data, packet_t *packet, int fragments,
777
packet_dimension_t *packet_dimension;
676
781
assert(socket_data);
759
// printf("syn %d\n", header->synchronize);
760
if(header->synchronize){
761
socket_data = (tcp_socket_data_ref) malloc(sizeof(*socket_data));
763
return tcp_release_and_return(packet, ENOMEM);
765
tcp_initialize_socket_data(socket_data);
766
socket_data->local_lock = listening_socket_data->local_lock;
767
socket_data->local_sockets = listening_socket_data->local_sockets;
768
socket_data->listening_socket_id = listening_socket->socket_id;
770
socket_data->next_incoming = ntohl(header->sequence_number);
771
socket_data->treshold = socket_data->next_incoming + ntohs(header->window);
773
socket_data->addrlen = addrlen;
774
socket_data->addr = malloc(socket_data->addrlen);
775
if(! socket_data->addr){
777
return tcp_release_and_return(packet, ENOMEM);
779
memcpy(socket_data->addr, src, socket_data->addrlen);
781
socket_data->dest_port = ntohs(header->source_port);
782
if(ERROR_OCCURRED(tl_set_address_port(socket_data->addr, socket_data->addrlen, socket_data->dest_port))){
783
free(socket_data->addr);
785
pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
789
// printf("addr %p\n", socket_data->addr, socket_data->addrlen);
792
if(ERROR_OCCURRED(socket_create(socket_data->local_sockets, listening_socket->phone, socket_data, &socket_id))){
793
free(socket_data->addr);
795
return tcp_release_and_return(packet, ERROR_CODE);
798
printf("new_sock %d\n", socket_id);
799
socket_data->pseudo_header = listening_socket_data->pseudo_header;
800
socket_data->headerlen = listening_socket_data->headerlen;
801
listening_socket_data->pseudo_header = NULL;
802
listening_socket_data->headerlen = 0;
804
fibril_rwlock_write_unlock(socket_data->local_lock);
805
// printf("list lg\n");
806
fibril_rwlock_write_lock(&tcp_globals.lock);
807
// printf("list locked\n");
808
// find the destination socket
809
listening_socket = socket_port_find(&tcp_globals.sockets, listening_port, SOCKET_MAP_KEY_LISTENING, 0);
810
if((! listening_socket) || (listening_socket->socket_id != listening_socket_id)){
811
fibril_rwlock_write_unlock(&tcp_globals.lock);
812
// a shadow may remain until app hangs up
813
return tcp_release_and_return(packet, EOK/*ENOTSOCK*/);
815
// printf("port %d\n", listening_socket->port);
816
listening_socket_data = (tcp_socket_data_ref) listening_socket->specific_data;
817
assert(listening_socket_data);
819
// printf("list ll\n");
820
fibril_rwlock_write_lock(listening_socket_data->local_lock);
821
// printf("list locked\n");
823
socket = socket_cores_find(listening_socket_data->local_sockets, socket_id);
825
// where is the socket?!?
826
fibril_rwlock_write_unlock(&tcp_globals.lock);
829
socket_data = (tcp_socket_data_ref) socket->specific_data;
832
// uint8_t * data = socket_data->addr;
833
// printf("addr %d of %x %x %x %x-%x %x %x %x-%x %x %x %x-%x %x %x %x\n", socket_data->addrlen, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15]);
835
ERROR_CODE = socket_port_add(&tcp_globals.sockets, listening_port, socket, (const char *) socket_data->addr, socket_data->addrlen);
836
assert(socket == socket_port_find(&tcp_globals.sockets, listening_port, (const char *) socket_data->addr, socket_data->addrlen));
837
//ERROR_CODE = socket_bind_free_port(&tcp_globals.sockets, socket, TCP_FREE_PORTS_START, TCP_FREE_PORTS_END, tcp_globals.last_used_port);
838
//tcp_globals.last_used_port = socket->port;
839
// printf("bound %d\n", socket->port);
840
fibril_rwlock_write_unlock(&tcp_globals.lock);
841
if(ERROR_CODE != EOK){
842
socket_destroy(tcp_globals.net_phone, socket->socket_id, socket_data->local_sockets, &tcp_globals.sockets, tcp_free_socket_data);
843
return tcp_release_and_return(packet, ERROR_CODE);
846
socket_data->state = TCP_SOCKET_LISTEN;
847
socket_data->next_incoming = ntohl(header->sequence_number) + 1;
848
// release additional packets
849
next_packet = pq_detach(packet);
851
pq_release_remote(tcp_globals.net_phone, packet_get_id(next_packet));
853
// trim if longer than the header
854
if((packet_get_data_length(packet) > sizeof(*header))
855
&& ERROR_OCCURRED(packet_trim(packet, 0, packet_get_data_length(packet) - sizeof(*header)))){
856
socket_destroy(tcp_globals.net_phone, socket->socket_id, socket_data->local_sockets, &tcp_globals.sockets, tcp_free_socket_data);
857
return tcp_release_and_return(packet, ERROR_CODE);
859
tcp_prepare_operation_header(socket, socket_data, header, 1, 0);
860
if(ERROR_OCCURRED(tcp_queue_packet(socket, socket_data, packet, 1))){
861
socket_destroy(tcp_globals.net_phone, socket->socket_id, socket_data->local_sockets, &tcp_globals.sockets, tcp_free_socket_data);
864
packet = tcp_get_packets_to_send(socket, socket_data);
865
// printf("send %d\n", packet_get_id(packet));
867
socket_destroy(tcp_globals.net_phone, socket->socket_id, socket_data->local_sockets, &tcp_globals.sockets, tcp_free_socket_data);
870
socket_data->state = TCP_SOCKET_SYN_RECEIVED;
871
// printf("unlock\n");
872
fibril_rwlock_write_unlock(socket_data->local_lock);
874
tcp_send_packets(socket_data->device_id, packet);
905
if (!header->synchronize)
906
return tcp_release_and_return(packet, EINVAL);
908
socket_data = (tcp_socket_data_t *) malloc(sizeof(*socket_data));
910
return tcp_release_and_return(packet, ENOMEM);
912
tcp_initialize_socket_data(socket_data);
913
socket_data->local_lock = listening_socket_data->local_lock;
914
socket_data->local_sockets = listening_socket_data->local_sockets;
915
socket_data->listening_socket_id = listening_socket->socket_id;
916
socket_data->next_incoming = ntohl(header->sequence_number);
917
socket_data->treshold = socket_data->next_incoming +
918
ntohs(header->window);
919
socket_data->addrlen = addrlen;
920
socket_data->addr = malloc(socket_data->addrlen);
921
if (!socket_data->addr) {
923
return tcp_release_and_return(packet, ENOMEM);
926
memcpy(socket_data->addr, src, socket_data->addrlen);
927
socket_data->dest_port = ntohs(header->source_port);
928
rc = tl_set_address_port(socket_data->addr, socket_data->addrlen,
929
socket_data->dest_port);
931
free(socket_data->addr);
933
return tcp_release_and_return(packet, rc);
936
/* Create a socket */
938
rc = socket_create(socket_data->local_sockets, listening_socket->phone,
939
socket_data, &socket_id);
941
free(socket_data->addr);
943
return tcp_release_and_return(packet, rc);
946
printf("new_sock %d\n", socket_id);
947
socket_data->pseudo_header = listening_socket_data->pseudo_header;
948
socket_data->headerlen = listening_socket_data->headerlen;
949
listening_socket_data->pseudo_header = NULL;
950
listening_socket_data->headerlen = 0;
952
fibril_rwlock_write_unlock(socket_data->local_lock);
953
fibril_rwlock_write_lock(&tcp_globals.lock);
955
/* Find the destination socket */
956
listening_socket = socket_port_find(&tcp_globals.sockets,
957
listening_port, (uint8_t *) SOCKET_MAP_KEY_LISTENING, 0);
958
if (!listening_socket ||
959
(listening_socket->socket_id != listening_socket_id)) {
960
fibril_rwlock_write_unlock(&tcp_globals.lock);
961
/* A shadow may remain until app hangs up */
962
return tcp_release_and_return(packet, EOK /*ENOTSOCK*/);
964
listening_socket_data =
965
(tcp_socket_data_t *) listening_socket->specific_data;
966
assert(listening_socket_data);
968
fibril_rwlock_write_lock(listening_socket_data->local_lock);
970
socket = socket_cores_find(listening_socket_data->local_sockets,
973
/* Where is the socket?!? */
974
fibril_rwlock_write_unlock(&tcp_globals.lock);
977
socket_data = (tcp_socket_data_t *) socket->specific_data;
980
rc = socket_port_add(&tcp_globals.sockets, listening_port, socket,
981
(uint8_t *) socket_data->addr, socket_data->addrlen);
982
assert(socket == socket_port_find(&tcp_globals.sockets, listening_port,
983
(uint8_t *) socket_data->addr, socket_data->addrlen));
985
// rc = socket_bind_free_port(&tcp_globals.sockets, socket,
986
// TCP_FREE_PORTS_START, TCP_FREE_PORTS_END,
987
// tcp_globals.last_used_port);
988
// tcp_globals.last_used_port = socket->port;
989
fibril_rwlock_write_unlock(&tcp_globals.lock);
991
socket_destroy(tcp_globals.net_phone, socket->socket_id,
992
socket_data->local_sockets, &tcp_globals.sockets,
993
tcp_free_socket_data);
994
return tcp_release_and_return(packet, rc);
997
socket_data->state = TCP_SOCKET_LISTEN;
998
socket_data->next_incoming = ntohl(header->sequence_number) + 1;
1000
/* Release additional packets */
1001
next_packet = pq_detach(packet);
1003
pq_release_remote(tcp_globals.net_phone,
1004
packet_get_id(next_packet));
1007
/* Trim if longer than the header */
1008
if (packet_get_data_length(packet) > sizeof(*header)) {
1009
rc = packet_trim(packet, 0,
1010
packet_get_data_length(packet) - sizeof(*header));
1012
socket_destroy(tcp_globals.net_phone, socket->socket_id,
1013
socket_data->local_sockets, &tcp_globals.sockets,
1014
tcp_free_socket_data);
1015
return tcp_release_and_return(packet, rc);
879
return tcp_release_and_return(packet, EINVAL);
1019
tcp_prepare_operation_header(socket, socket_data, header, 1, 0);
1021
rc = tcp_queue_packet(socket, socket_data, packet, 1);
1023
socket_destroy(tcp_globals.net_phone, socket->socket_id,
1024
socket_data->local_sockets, &tcp_globals.sockets,
1025
tcp_free_socket_data);
1029
packet = tcp_get_packets_to_send(socket, socket_data);
1031
socket_destroy(tcp_globals.net_phone, socket->socket_id,
1032
socket_data->local_sockets, &tcp_globals.sockets,
1033
tcp_free_socket_data);
1037
socket_data->state = TCP_SOCKET_SYN_RECEIVED;
1038
fibril_rwlock_write_unlock(socket_data->local_lock);
1040
/* Send the packet */
1041
tcp_send_packets(socket_data->device_id, packet);
882
int tcp_process_syn_received(socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet){
885
socket_core_ref listening_socket;
886
tcp_socket_data_ref listening_socket_data;
1046
int tcp_process_syn_received(socket_core_t *socket,
1047
tcp_socket_data_t *socket_data, tcp_header_t *header, packet_t *packet)
1049
socket_core_t *listening_socket;
1050
tcp_socket_data_t *listening_socket_data;
889
1054
assert(socket_data);
1082
1292
socket_cores_initialize(&local_sockets);
1083
1293
fibril_rwlock_initialize(&lock);
1085
while(keep_on_going){
1295
while (keep_on_going) {
1297
/* Answer the call */
1088
1298
answer_call(callid, res, &answer, answer_count);
1091
1300
refresh_answer(&answer, &answer_count);
1093
// get the next call
1301
/* Get the next call */
1094
1302
callid = async_get_call(&call);
1097
switch(IPC_GET_METHOD(call)){
1098
case IPC_M_PHONE_HUNGUP:
1099
keep_on_going = false;
1103
socket_data = (tcp_socket_data_ref) malloc(sizeof(*socket_data));
1107
tcp_initialize_socket_data(socket_data);
1108
socket_data->local_lock = &lock;
1109
socket_data->local_sockets = &local_sockets;
1110
fibril_rwlock_write_lock(&lock);
1111
socket_id = SOCKET_GET_SOCKET_ID(call);
1112
res = socket_create(&local_sockets, app_phone, socket_data, &socket_id);
1113
SOCKET_SET_SOCKET_ID(answer, socket_id);
1114
fibril_rwlock_write_unlock(&lock);
1116
if (tl_get_ip_packet_dimension(tcp_globals.ip_phone, &tcp_globals.dimensions, DEVICE_INVALID_ID, &packet_dimension) == EOK){
1117
SOCKET_SET_DATA_FRAGMENT_SIZE(answer, ((packet_dimension->content < socket_data->data_fragment_size) ? packet_dimension->content : socket_data->data_fragment_size));
1119
// SOCKET_SET_DATA_FRAGMENT_SIZE(answer, MAX_TCP_FRAGMENT_SIZE);
1120
SOCKET_SET_HEADER_SIZE(answer, TCP_HEADER_SIZE);
1127
case NET_SOCKET_BIND:
1128
res = data_receive((void **) &addr, &addrlen);
1130
fibril_rwlock_write_lock(&tcp_globals.lock);
1131
fibril_rwlock_write_lock(&lock);
1132
res = socket_bind(&local_sockets, &tcp_globals.sockets, SOCKET_GET_SOCKET_ID(call), addr, addrlen, TCP_FREE_PORTS_START, TCP_FREE_PORTS_END, tcp_globals.last_used_port);
1134
socket = socket_cores_find(&local_sockets, SOCKET_GET_SOCKET_ID(call));
1136
socket_data = (tcp_socket_data_ref) socket->specific_data;
1137
assert(socket_data);
1138
socket_data->state = TCP_SOCKET_LISTEN;
1141
fibril_rwlock_write_unlock(&lock);
1142
fibril_rwlock_write_unlock(&tcp_globals.lock);
1146
case NET_SOCKET_LISTEN:
1147
fibril_rwlock_read_lock(&tcp_globals.lock);
1148
// fibril_rwlock_write_lock(&tcp_globals.lock);
1149
fibril_rwlock_write_lock(&lock);
1150
res = tcp_listen_message(&local_sockets, SOCKET_GET_SOCKET_ID(call), SOCKET_GET_BACKLOG(call));
1151
fibril_rwlock_write_unlock(&lock);
1152
// fibril_rwlock_write_unlock(&tcp_globals.lock);
1153
fibril_rwlock_read_unlock(&tcp_globals.lock);
1155
case NET_SOCKET_CONNECT:
1156
res = data_receive((void **) &addr, &addrlen);
1158
// the global lock may be released in the tcp_connect_message() function
1159
fibril_rwlock_write_lock(&tcp_globals.lock);
1160
fibril_rwlock_write_lock(&lock);
1161
res = tcp_connect_message(&local_sockets, SOCKET_GET_SOCKET_ID(call), addr, addrlen);
1163
fibril_rwlock_write_unlock(&lock);
1164
fibril_rwlock_write_unlock(&tcp_globals.lock);
1169
case NET_SOCKET_ACCEPT:
1170
fibril_rwlock_read_lock(&tcp_globals.lock);
1171
fibril_rwlock_write_lock(&lock);
1172
res = tcp_accept_message(&local_sockets, SOCKET_GET_SOCKET_ID(call), SOCKET_GET_NEW_SOCKET_ID(call), &size, &addrlen);
1173
SOCKET_SET_DATA_FRAGMENT_SIZE(answer, size);
1174
fibril_rwlock_write_unlock(&lock);
1175
fibril_rwlock_read_unlock(&tcp_globals.lock);
1177
SOCKET_SET_SOCKET_ID(answer, res);
1178
SOCKET_SET_ADDRESS_LENGTH(answer, addrlen);
1182
case NET_SOCKET_SEND:
1183
fibril_rwlock_read_lock(&tcp_globals.lock);
1184
fibril_rwlock_write_lock(&lock);
1185
res = tcp_send_message(&local_sockets, SOCKET_GET_SOCKET_ID(call), SOCKET_GET_DATA_FRAGMENTS(call), &size, SOCKET_GET_FLAGS(call));
1186
SOCKET_SET_DATA_FRAGMENT_SIZE(answer, size);
1188
fibril_rwlock_write_unlock(&lock);
1189
fibril_rwlock_read_unlock(&tcp_globals.lock);
1194
case NET_SOCKET_SENDTO:
1195
res = data_receive((void **) &addr, &addrlen);
1197
fibril_rwlock_read_lock(&tcp_globals.lock);
1198
fibril_rwlock_write_lock(&lock);
1199
res = tcp_send_message(&local_sockets, SOCKET_GET_SOCKET_ID(call), SOCKET_GET_DATA_FRAGMENTS(call), &size, SOCKET_GET_FLAGS(call));
1200
SOCKET_SET_DATA_FRAGMENT_SIZE(answer, size);
1202
fibril_rwlock_write_unlock(&lock);
1203
fibril_rwlock_read_unlock(&tcp_globals.lock);
1210
case NET_SOCKET_RECV:
1211
fibril_rwlock_read_lock(&tcp_globals.lock);
1212
fibril_rwlock_write_lock(&lock);
1213
res = tcp_recvfrom_message(&local_sockets, SOCKET_GET_SOCKET_ID(call), SOCKET_GET_FLAGS(call), NULL);
1214
fibril_rwlock_write_unlock(&lock);
1215
fibril_rwlock_read_unlock(&tcp_globals.lock);
1217
SOCKET_SET_READ_DATA_LENGTH(answer, res);
1222
case NET_SOCKET_RECVFROM:
1223
fibril_rwlock_read_lock(&tcp_globals.lock);
1224
fibril_rwlock_write_lock(&lock);
1225
res = tcp_recvfrom_message(&local_sockets, SOCKET_GET_SOCKET_ID(call), SOCKET_GET_FLAGS(call), &addrlen);
1226
fibril_rwlock_write_unlock(&lock);
1227
fibril_rwlock_read_unlock(&tcp_globals.lock);
1229
SOCKET_SET_READ_DATA_LENGTH(answer, res);
1230
SOCKET_SET_ADDRESS_LENGTH(answer, addrlen);
1235
case NET_SOCKET_CLOSE:
1236
fibril_rwlock_write_lock(&tcp_globals.lock);
1237
fibril_rwlock_write_lock(&lock);
1238
res = tcp_close_message(&local_sockets, SOCKET_GET_SOCKET_ID(call));
1240
fibril_rwlock_write_unlock(&lock);
1241
fibril_rwlock_write_unlock(&tcp_globals.lock);
1244
case NET_SOCKET_GETSOCKOPT:
1245
case NET_SOCKET_SETSOCKOPT:
1304
/* Process the call */
1305
switch (IPC_GET_IMETHOD(call)) {
1306
case IPC_M_PHONE_HUNGUP:
1307
keep_on_going = false;
1313
(tcp_socket_data_t *) malloc(sizeof(*socket_data));
1319
tcp_initialize_socket_data(socket_data);
1320
socket_data->local_lock = &lock;
1321
socket_data->local_sockets = &local_sockets;
1322
fibril_rwlock_write_lock(&lock);
1323
socket_id = SOCKET_GET_SOCKET_ID(call);
1324
res = socket_create(&local_sockets, app_phone,
1325
socket_data, &socket_id);
1326
SOCKET_SET_SOCKET_ID(answer, socket_id);
1327
fibril_rwlock_write_unlock(&lock);
1332
if (tl_get_ip_packet_dimension(tcp_globals.ip_phone,
1333
&tcp_globals.dimensions, DEVICE_INVALID_ID,
1334
&packet_dimension) == EOK) {
1335
SOCKET_SET_DATA_FRAGMENT_SIZE(answer,
1336
((packet_dimension->content <
1337
socket_data->data_fragment_size) ?
1338
packet_dimension->content :
1339
socket_data->data_fragment_size));
1341
// SOCKET_SET_DATA_FRAGMENT_SIZE(answer, MAX_TCP_FRAGMENT_SIZE);
1342
SOCKET_SET_HEADER_SIZE(answer, TCP_HEADER_SIZE);
1346
case NET_SOCKET_BIND:
1347
res = async_data_write_accept((void **) &addr, false,
1351
fibril_rwlock_write_lock(&tcp_globals.lock);
1352
fibril_rwlock_write_lock(&lock);
1353
res = socket_bind(&local_sockets, &tcp_globals.sockets,
1354
SOCKET_GET_SOCKET_ID(call), addr, addrlen,
1355
TCP_FREE_PORTS_START, TCP_FREE_PORTS_END,
1356
tcp_globals.last_used_port);
1358
socket = socket_cores_find(&local_sockets,
1359
SOCKET_GET_SOCKET_ID(call));
1361
socket_data = (tcp_socket_data_t *)
1362
socket->specific_data;
1363
assert(socket_data);
1364
socket_data->state = TCP_SOCKET_LISTEN;
1367
fibril_rwlock_write_unlock(&lock);
1368
fibril_rwlock_write_unlock(&tcp_globals.lock);
1372
case NET_SOCKET_LISTEN:
1373
fibril_rwlock_read_lock(&tcp_globals.lock);
1374
// fibril_rwlock_write_lock(&tcp_globals.lock);
1375
fibril_rwlock_write_lock(&lock);
1376
res = tcp_listen_message(&local_sockets,
1377
SOCKET_GET_SOCKET_ID(call),
1378
SOCKET_GET_BACKLOG(call));
1379
fibril_rwlock_write_unlock(&lock);
1380
// fibril_rwlock_write_unlock(&tcp_globals.lock);
1381
fibril_rwlock_read_unlock(&tcp_globals.lock);
1384
case NET_SOCKET_CONNECT:
1385
res = async_data_write_accept((void **) &addr, false,
1390
* The global lock may be released in the
1391
* tcp_connect_message() function.
1393
fibril_rwlock_write_lock(&tcp_globals.lock);
1394
fibril_rwlock_write_lock(&lock);
1395
res = tcp_connect_message(&local_sockets,
1396
SOCKET_GET_SOCKET_ID(call), addr, addrlen);
1398
fibril_rwlock_write_unlock(&lock);
1399
fibril_rwlock_write_unlock(&tcp_globals.lock);
1404
case NET_SOCKET_ACCEPT:
1405
fibril_rwlock_read_lock(&tcp_globals.lock);
1406
fibril_rwlock_write_lock(&lock);
1407
res = tcp_accept_message(&local_sockets,
1408
SOCKET_GET_SOCKET_ID(call),
1409
SOCKET_GET_NEW_SOCKET_ID(call), &size, &addrlen);
1410
SOCKET_SET_DATA_FRAGMENT_SIZE(answer, size);
1411
fibril_rwlock_write_unlock(&lock);
1412
fibril_rwlock_read_unlock(&tcp_globals.lock);
1414
SOCKET_SET_SOCKET_ID(answer, res);
1415
SOCKET_SET_ADDRESS_LENGTH(answer, addrlen);
1420
case NET_SOCKET_SEND:
1421
fibril_rwlock_read_lock(&tcp_globals.lock);
1422
fibril_rwlock_write_lock(&lock);
1423
res = tcp_send_message(&local_sockets,
1424
SOCKET_GET_SOCKET_ID(call),
1425
SOCKET_GET_DATA_FRAGMENTS(call), &size,
1426
SOCKET_GET_FLAGS(call));
1427
SOCKET_SET_DATA_FRAGMENT_SIZE(answer, size);
1429
fibril_rwlock_write_unlock(&lock);
1430
fibril_rwlock_read_unlock(&tcp_globals.lock);
1436
case NET_SOCKET_SENDTO:
1437
res = async_data_write_accept((void **) &addr, false,
1441
fibril_rwlock_read_lock(&tcp_globals.lock);
1442
fibril_rwlock_write_lock(&lock);
1443
res = tcp_send_message(&local_sockets,
1444
SOCKET_GET_SOCKET_ID(call),
1445
SOCKET_GET_DATA_FRAGMENTS(call), &size,
1446
SOCKET_GET_FLAGS(call));
1447
SOCKET_SET_DATA_FRAGMENT_SIZE(answer, size);
1449
fibril_rwlock_write_unlock(&lock);
1450
fibril_rwlock_read_unlock(&tcp_globals.lock);
1457
case NET_SOCKET_RECV:
1458
fibril_rwlock_read_lock(&tcp_globals.lock);
1459
fibril_rwlock_write_lock(&lock);
1460
res = tcp_recvfrom_message(&local_sockets,
1461
SOCKET_GET_SOCKET_ID(call), SOCKET_GET_FLAGS(call),
1463
fibril_rwlock_write_unlock(&lock);
1464
fibril_rwlock_read_unlock(&tcp_globals.lock);
1466
SOCKET_SET_READ_DATA_LENGTH(answer, res);
1472
case NET_SOCKET_RECVFROM:
1473
fibril_rwlock_read_lock(&tcp_globals.lock);
1474
fibril_rwlock_write_lock(&lock);
1475
res = tcp_recvfrom_message(&local_sockets,
1476
SOCKET_GET_SOCKET_ID(call), SOCKET_GET_FLAGS(call),
1478
fibril_rwlock_write_unlock(&lock);
1479
fibril_rwlock_read_unlock(&tcp_globals.lock);
1481
SOCKET_SET_READ_DATA_LENGTH(answer, res);
1482
SOCKET_SET_ADDRESS_LENGTH(answer, addrlen);
1488
case NET_SOCKET_CLOSE:
1489
fibril_rwlock_write_lock(&tcp_globals.lock);
1490
fibril_rwlock_write_lock(&lock);
1491
res = tcp_close_message(&local_sockets,
1492
SOCKET_GET_SOCKET_ID(call));
1494
fibril_rwlock_write_unlock(&lock);
1495
fibril_rwlock_write_unlock(&tcp_globals.lock);
1499
case NET_SOCKET_GETSOCKOPT:
1500
case NET_SOCKET_SETSOCKOPT:
1252
// release the application phone
1253
ipc_hangup(app_phone);
1507
/* Release the application phone */
1508
async_hangup(app_phone);
1255
1510
printf("release\n");
1256
// release all local sockets
1257
socket_cores_release(tcp_globals.net_phone, &local_sockets, &tcp_globals.sockets, tcp_free_socket_data);
1511
/* Release all local sockets */
1512
socket_cores_release(tcp_globals.net_phone, &local_sockets,
1513
&tcp_globals.sockets, tcp_free_socket_data);
1262
int tcp_timeout(void * data){
1263
tcp_timeout_ref timeout = data;
1518
int tcp_timeout(void *data)
1520
tcp_timeout_t *timeout = data;
1264
1521
int keep_write_lock = false;
1265
socket_core_ref socket;
1266
tcp_socket_data_ref socket_data;
1522
socket_core_t *socket;
1523
tcp_socket_data_t *socket_data;
1268
1525
assert(timeout);
1270
// sleep the given timeout
1527
/* Sleep the given timeout */
1271
1528
async_usleep(timeout->timeout);
1273
if(timeout->globals_read_only){
1529
/* Lock the globals */
1530
if (timeout->globals_read_only)
1274
1531
fibril_rwlock_read_lock(&tcp_globals.lock);
1276
1533
fibril_rwlock_write_lock(&tcp_globals.lock);
1278
// find the pending operation socket
1279
socket = socket_port_find(&tcp_globals.sockets, timeout->port, timeout->key, timeout->key_length);
1280
if(socket && (socket->socket_id == timeout->socket_id)){
1281
socket_data = (tcp_socket_data_ref) socket->specific_data;
1282
assert(socket_data);
1283
if(socket_data->local_sockets == timeout->local_sockets){
1284
fibril_rwlock_write_lock(socket_data->local_lock);
1285
if(timeout->sequence_number){
1286
// increase the timeout counter;
1287
++ socket_data->timeout_count;
1288
if(socket_data->timeout_count == TCP_MAX_TIMEOUTS){
1289
// TODO release as connection lost
1290
//tcp_refresh_socket_data(socket_data);
1291
fibril_rwlock_write_unlock(socket_data->local_lock);
1294
// tcp_retransmit_packet(socket, socket_data, timeout->sequence_number);
1295
fibril_rwlock_write_unlock(socket_data->local_lock);
1298
fibril_mutex_lock(&socket_data->operation.mutex);
1299
// set the timeout operation result if state not changed
1300
if(socket_data->state == timeout->state){
1301
socket_data->operation.result = ETIMEOUT;
1302
// notify the main fibril
1303
fibril_condvar_signal(&socket_data->operation.condvar);
1304
// keep the global write lock
1305
keep_write_lock = true;
1307
// operation is ok, do nothing
1308
// unlocking from now on, so the unlock order does not matter...
1309
fibril_rwlock_write_unlock(socket_data->local_lock);
1311
fibril_mutex_unlock(&socket_data->operation.mutex);
1315
// unlock only if no socket
1316
if(timeout->globals_read_only){
1535
/* Find the pending operation socket */
1536
socket = socket_port_find(&tcp_globals.sockets, timeout->port,
1537
timeout->key, timeout->key_length);
1538
if (!socket || (socket->socket_id != timeout->socket_id))
1541
socket_data = (tcp_socket_data_t *) socket->specific_data;
1542
assert(socket_data);
1543
if (socket_data->local_sockets != timeout->local_sockets)
1546
fibril_rwlock_write_lock(socket_data->local_lock);
1547
if (timeout->sequence_number) {
1548
/* Increase the timeout counter */
1549
socket_data->timeout_count++;
1550
if (socket_data->timeout_count == TCP_MAX_TIMEOUTS) {
1551
/* TODO release as connection lost */
1552
//tcp_refresh_socket_data(socket_data);
1553
fibril_rwlock_write_unlock(socket_data->local_lock);
1556
// tcp_retransmit_packet(socket,
1557
// socket_data, timeout->sequence_number);
1558
fibril_rwlock_write_unlock(socket_data->local_lock);
1561
fibril_mutex_lock(&socket_data->operation.mutex);
1562
/* Set the timeout operation result if state not changed */
1563
if (socket_data->state == timeout->state) {
1564
socket_data->operation.result = ETIMEOUT;
1566
/* Notify the main fibril */
1567
fibril_condvar_signal(&socket_data->operation.condvar);
1569
/* Keep the global write lock */
1570
keep_write_lock = true;
1573
* Operation is ok, do nothing.
1574
* Unlocking from now on, so the unlocking
1575
* order does not matter.
1577
fibril_rwlock_write_unlock(socket_data->local_lock);
1579
fibril_mutex_unlock(&socket_data->operation.mutex);
1583
/* Unlock only if no socket */
1584
if (timeout->globals_read_only)
1317
1585
fibril_rwlock_read_unlock(&tcp_globals.lock);
1318
}else if(! keep_write_lock){
1319
// release if not desired
1586
else if (!keep_write_lock)
1587
/* Release if not desired */
1320
1588
fibril_rwlock_write_unlock(&tcp_globals.lock);
1322
// release the timeout structure
1590
/* Release the timeout structure */
1327
int tcp_release_after_timeout(void * data){
1328
tcp_timeout_ref timeout = data;
1329
socket_core_ref socket;
1330
tcp_socket_data_ref socket_data;
1331
fibril_rwlock_t * local_lock;
1595
int tcp_release_after_timeout(void *data)
1597
tcp_timeout_t *timeout = data;
1598
socket_core_t *socket;
1599
tcp_socket_data_t *socket_data;
1600
fibril_rwlock_t *local_lock;
1333
1602
assert(timeout);
1335
// sleep the given timeout
1604
/* Sleep the given timeout */
1336
1605
async_usleep(timeout->timeout);
1607
/* Lock the globals */
1338
1608
fibril_rwlock_write_lock(&tcp_globals.lock);
1339
// find the pending operation socket
1340
socket = socket_port_find(&tcp_globals.sockets, timeout->port, timeout->key, timeout->key_length);
1341
if(socket && (socket->socket_id == timeout->socket_id)){
1342
socket_data = (tcp_socket_data_ref) socket->specific_data;
1610
/* Find the pending operation socket */
1611
socket = socket_port_find(&tcp_globals.sockets, timeout->port,
1612
timeout->key, timeout->key_length);
1614
if (socket && (socket->socket_id == timeout->socket_id)) {
1615
socket_data = (tcp_socket_data_t *) socket->specific_data;
1343
1616
assert(socket_data);
1344
if(socket_data->local_sockets == timeout->local_sockets){
1617
if (socket_data->local_sockets == timeout->local_sockets) {
1345
1618
local_lock = socket_data->local_lock;
1346
1619
fibril_rwlock_write_lock(local_lock);
1347
socket_destroy(tcp_globals.net_phone, timeout->socket_id, timeout->local_sockets, &tcp_globals.sockets, tcp_free_socket_data);
1620
socket_destroy(tcp_globals.net_phone,
1621
timeout->socket_id, timeout->local_sockets,
1622
&tcp_globals.sockets, tcp_free_socket_data);
1348
1623
fibril_rwlock_write_unlock(local_lock);
1351
// unlock the globals
1627
/* Unlock the globals */
1352
1628
fibril_rwlock_write_unlock(&tcp_globals.lock);
1353
// release the timeout structure
1630
/* Release the timeout structure */
1358
void tcp_retransmit_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, size_t sequence_number){
1636
void tcp_retransmit_packet(socket_core_t *socket, tcp_socket_data_t *
1637
socket_data, size_t sequence_number)
1361
1641
size_t data_length;
1363
1643
assert(socket);
1364
1644
assert(socket_data);
1365
1645
assert(socket->specific_data == socket_data);
1368
1648
packet = pq_find(socket_data->outgoing, sequence_number);
1369
1649
printf("retransmit %d\n", packet_get_id(packet));
1371
1651
pq_get_order(packet, NULL, &data_length);
1372
copy = tcp_prepare_copy(socket, socket_data, packet, data_length, sequence_number);
1652
copy = tcp_prepare_copy(socket, socket_data, packet,
1653
data_length, sequence_number);
1373
1654
fibril_rwlock_write_unlock(socket_data->local_lock);
1374
// printf("r send %d\n", packet_get_id(packet));
1655
// printf("r send %d\n", packet_get_id(packet));
1376
1657
tcp_send_packets(socket_data->device_id, copy);
1379
1659
fibril_rwlock_write_unlock(socket_data->local_lock);
1383
int tcp_listen_message(socket_cores_ref local_sockets, int socket_id, int backlog){
1384
socket_core_ref socket;
1385
tcp_socket_data_ref socket_data;
1663
int tcp_listen_message(socket_cores_t *local_sockets, int socket_id,
1666
socket_core_t *socket;
1667
tcp_socket_data_t *socket_data;
1387
1669
assert(local_sockets);
1674
/* Find the socket */
1393
1675
socket = socket_cores_find(local_sockets, socket_id);
1395
1677
return ENOTSOCK;
1397
// get the socket specific data
1398
socket_data = (tcp_socket_data_ref) socket->specific_data;
1679
/* Get the socket specific data */
1680
socket_data = (tcp_socket_data_t *) socket->specific_data;
1399
1681
assert(socket_data);
1683
/* Set the backlog */
1401
1684
socket_data->backlog = backlog;
1405
int tcp_connect_message(socket_cores_ref local_sockets, int socket_id, struct sockaddr * addr, socklen_t addrlen){
1408
socket_core_ref socket;
1689
int tcp_connect_message(socket_cores_t *local_sockets, int socket_id,
1690
struct sockaddr *addr, socklen_t addrlen)
1692
socket_core_t *socket;
1410
1695
assert(local_sockets);
1412
1697
assert(addrlen > 0);
1699
/* Find the socket */
1415
1700
socket = socket_cores_find(local_sockets, socket_id);
1417
1702
return ENOTSOCK;
1419
if(ERROR_OCCURRED(tcp_connect_core(socket, local_sockets, addr, addrlen))){
1704
rc = tcp_connect_core(socket, local_sockets, addr, addrlen);
1420
1706
tcp_free_socket_data(socket);
1422
if(socket->port > 0){
1423
socket_ports_exclude(&tcp_globals.sockets, socket->port);
1707
/* Unbind if bound */
1708
if (socket->port > 0) {
1709
socket_ports_exclude(&tcp_globals.sockets,
1710
socket->port, free);
1424
1711
socket->port = 0;
1430
int tcp_connect_core(socket_core_ref socket, socket_cores_ref local_sockets, struct sockaddr * addr, socklen_t addrlen){
1433
tcp_socket_data_ref socket_data;
1717
int tcp_connect_core(socket_core_t *socket, socket_cores_t *local_sockets,
1718
struct sockaddr *addr, socklen_t addrlen)
1720
tcp_socket_data_t *socket_data;
1436
1724
assert(socket);
1438
1726
assert(addrlen > 0);
1440
// get the socket specific data
1441
socket_data = (tcp_socket_data_ref) socket->specific_data;
1728
/* Get the socket specific data */
1729
socket_data = (tcp_socket_data_t *) socket->specific_data;
1442
1730
assert(socket_data);
1443
1731
assert(socket->specific_data == socket_data);
1444
if((socket_data->state != TCP_SOCKET_INITIAL)
1445
&& ((socket_data->state != TCP_SOCKET_LISTEN) || (socket->port <= 0))){
1732
if ((socket_data->state != TCP_SOCKET_INITIAL) &&
1733
((socket_data->state != TCP_SOCKET_LISTEN) ||
1734
(socket->port <= 0)))
1448
// get the destination port
1449
ERROR_PROPAGATE(tl_get_address_port(addr, addrlen, &socket_data->dest_port));
1450
if(socket->port <= 0){
1451
// try to find a free port
1452
ERROR_PROPAGATE(socket_bind_free_port(&tcp_globals.sockets, socket, TCP_FREE_PORTS_START, TCP_FREE_PORTS_END, tcp_globals.last_used_port));
1453
// set the next port as the search starting port number
1737
/* Get the destination port */
1738
rc = tl_get_address_port(addr, addrlen, &socket_data->dest_port);
1742
if (socket->port <= 0) {
1743
/* Try to find a free port */
1744
rc = socket_bind_free_port(&tcp_globals.sockets, socket,
1745
TCP_FREE_PORTS_START, TCP_FREE_PORTS_END,
1746
tcp_globals.last_used_port);
1749
/* Set the next port as the search starting port number */
1454
1750
tcp_globals.last_used_port = socket->port;
1456
ERROR_PROPAGATE(ip_get_route_req(tcp_globals.ip_phone, IPPROTO_TCP, addr, addrlen, &socket_data->device_id, &socket_data->pseudo_header, &socket_data->headerlen));
1458
// create the notification packet
1459
ERROR_PROPAGATE(tcp_create_notification_packet(&packet, socket, socket_data, 1, 0));
1461
// unlock the globals and wait for an operation
1753
rc = ip_get_route_req(tcp_globals.ip_phone, IPPROTO_TCP,
1754
addr, addrlen, &socket_data->device_id,
1755
&socket_data->pseudo_header, &socket_data->headerlen);
1759
/* Create the notification packet */
1760
rc = tcp_create_notification_packet(&packet, socket, socket_data, 1, 0);
1764
/* Unlock the globals and wait for an operation */
1462
1765
fibril_rwlock_write_unlock(&tcp_globals.lock);
1464
1767
socket_data->addr = addr;
1465
1768
socket_data->addrlen = addrlen;
1467
if(ERROR_OCCURRED(tcp_queue_packet(socket, socket_data, packet, 1))
1468
|| ERROR_OCCURRED(tcp_prepare_timeout(tcp_timeout, socket, socket_data, 0, TCP_SOCKET_INITIAL, NET_DEFAULT_TCP_INITIAL_TIMEOUT, false))){
1770
/* Send the packet */
1772
if (((rc = tcp_queue_packet(socket, socket_data, packet, 1)) != EOK) ||
1773
((rc = tcp_prepare_timeout(tcp_timeout, socket, socket_data, 0,
1774
TCP_SOCKET_INITIAL, NET_DEFAULT_TCP_INITIAL_TIMEOUT, false)) !=
1469
1776
socket_data->addr = NULL;
1470
1777
socket_data->addrlen = 0;
1471
1778
fibril_rwlock_write_lock(&tcp_globals.lock);
1473
1780
packet = tcp_get_packets_to_send(socket, socket_data);
1475
1782
fibril_mutex_lock(&socket_data->operation.mutex);
1476
1783
fibril_rwlock_write_unlock(socket_data->local_lock);
1785
socket_data->state = TCP_SOCKET_SYN_SENT;
1787
/* Send the packet */
1478
1788
printf("connecting %d\n", packet_get_id(packet));
1479
1789
tcp_send_packets(socket_data->device_id, packet);
1481
fibril_condvar_wait(&socket_data->operation.condvar, &socket_data->operation.mutex);
1482
ERROR_CODE = socket_data->operation.result;
1483
if(ERROR_CODE != EOK){
1791
/* Wait for a reply */
1792
fibril_condvar_wait(&socket_data->operation.condvar,
1793
&socket_data->operation.mutex);
1794
rc = socket_data->operation.result;
1484
1796
socket_data->addr = NULL;
1485
1797
socket_data->addrlen = 0;
1488
1800
socket_data->addr = NULL;
1489
1801
socket_data->addrlen = 0;
1494
1806
fibril_mutex_unlock(&socket_data->operation.mutex);
1496
// return the result
1500
int tcp_queue_prepare_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length){
1503
tcp_header_ref header;
1810
int tcp_queue_prepare_packet(socket_core_t *socket,
1811
tcp_socket_data_t *socket_data, packet_t *packet, size_t data_length)
1813
tcp_header_t *header;
1505
1816
assert(socket);
1506
1817
assert(socket_data);
1507
1818
assert(socket->specific_data == socket_data);
1510
header = (tcp_header_ref) packet_get_data(packet);
1820
/* Get TCP header */
1821
header = (tcp_header_t *) packet_get_data(packet);
1512
1823
return NO_DATA;
1514
1825
header->destination_port = htons(socket_data->dest_port);
1515
1826
header->source_port = htons(socket->port);
1516
1827
header->sequence_number = htonl(socket_data->next_outgoing);
1517
if(ERROR_OCCURRED(packet_set_addr(packet, NULL, (uint8_t *) socket_data->addr, socket_data->addrlen))){
1829
rc = packet_set_addr(packet, NULL, (uint8_t *) socket_data->addr,
1830
socket_data->addrlen);
1518
1832
return tcp_release_and_return(packet, EINVAL);
1520
// remember the outgoing FIN
1521
if(header->finalize){
1834
/* Remember the outgoing FIN */
1835
if (header->finalize)
1522
1836
socket_data->fin_outgoing = socket_data->next_outgoing;
1527
int tcp_queue_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length){
1841
int tcp_queue_packet(socket_core_t *socket, tcp_socket_data_t *socket_data,
1842
packet_t *packet, size_t data_length)
1530
1846
assert(socket);
1531
1847
assert(socket_data);
1532
1848
assert(socket->specific_data == socket_data);
1534
ERROR_PROPAGATE(tcp_queue_prepare_packet(socket, socket_data, packet, data_length));
1536
if(ERROR_OCCURRED(pq_add(&socket_data->outgoing, packet, socket_data->next_outgoing, data_length))){
1537
return tcp_release_and_return(packet, ERROR_CODE);
1850
rc = tcp_queue_prepare_packet(socket, socket_data, packet, data_length);
1854
rc = pq_add(&socket_data->outgoing, packet, socket_data->next_outgoing,
1857
return tcp_release_and_return(packet, rc);
1539
1859
socket_data->next_outgoing += data_length;
1543
packet_t tcp_get_packets_to_send(socket_core_ref socket, tcp_socket_data_ref socket_data){
1548
packet_t sending = NULL;
1549
packet_t previous = NULL;
1863
packet_t *tcp_get_packets_to_send(socket_core_t *socket, tcp_socket_data_t *
1868
packet_t *sending = NULL;
1869
packet_t *previous = NULL;
1550
1870
size_t data_length;
1552
1873
assert(socket);
1553
1874
assert(socket_data);
1554
1875
assert(socket->specific_data == socket_data);
1556
1877
packet = pq_find(socket_data->outgoing, socket_data->last_outgoing + 1);
1558
1879
pq_get_order(packet, NULL, &data_length);
1559
// send only if fits into the window
1560
// respecting the possible overflow
1561
if(IS_IN_INTERVAL_OVERFLOW((uint32_t) socket_data->last_outgoing, (uint32_t)(socket_data->last_outgoing + data_length), (uint32_t)(socket_data->expected + socket_data->treshold))){
1562
copy = tcp_prepare_copy(socket, socket_data, packet, data_length, socket_data->last_outgoing + 1);
1882
* Send only if fits into the window, respecting the possible
1885
if (!IS_IN_INTERVAL_OVERFLOW(
1886
(uint32_t) socket_data->last_outgoing,
1887
(uint32_t) (socket_data->last_outgoing + data_length),
1888
(uint32_t) (socket_data->expected + socket_data->treshold)))
1891
copy = tcp_prepare_copy(socket, socket_data, packet,
1892
data_length, socket_data->last_outgoing + 1);
1899
rc = pq_insert_after(previous, copy);
1901
pq_release_remote(tcp_globals.net_phone,
1902
packet_get_id(copy));
1564
1903
return sending;
1569
if(ERROR_OCCURRED(pq_insert_after(previous, copy))){
1570
pq_release_remote(tcp_globals.net_phone, packet_get_id(copy));
1575
packet = pq_next(packet);
1576
// overflow occurred ?
1577
if((! packet) && (socket_data->last_outgoing > socket_data->next_outgoing)){
1578
printf("gpts overflow\n");
1579
// continue from the beginning
1580
packet = socket_data->outgoing;
1582
socket_data->last_outgoing += data_length;
1908
packet = pq_next(packet);
1910
/* Overflow occurred? */
1912
(socket_data->last_outgoing > socket_data->next_outgoing)) {
1913
printf("gpts overflow\n");
1914
/* Continue from the beginning */
1915
packet = socket_data->outgoing;
1917
socket_data->last_outgoing += data_length;
1587
1920
return sending;
1590
packet_t tcp_send_prepare_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length, size_t sequence_number){
1593
tcp_header_ref header;
1923
packet_t *tcp_send_prepare_packet(socket_core_t *socket, tcp_socket_data_t *
1924
socket_data, packet_t *packet, size_t data_length, size_t sequence_number)
1926
tcp_header_t *header;
1594
1927
uint32_t checksum;
1596
1930
assert(socket);
1597
1931
assert(socket_data);
1598
1932
assert(socket->specific_data == socket_data);
1600
// adjust the pseudo header
1601
if(ERROR_OCCURRED(ip_client_set_pseudo_header_data_length(socket_data->pseudo_header, socket_data->headerlen, packet_get_data_length(packet)))){
1934
/* Adjust the pseudo header */
1935
rc = ip_client_set_pseudo_header_data_length(socket_data->pseudo_header,
1936
socket_data->headerlen, packet_get_data_length(packet));
1602
1938
pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
1607
header = (tcp_header_ref) packet_get_data(packet);
1942
/* Get the header */
1943
header = (tcp_header_t *) packet_get_data(packet);
1609
1945
pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
1612
1948
assert(ntohl(header->sequence_number) == sequence_number);
1614
// adjust the header
1615
if(socket_data->next_incoming){
1616
header->acknowledgement_number = htonl(socket_data->next_incoming);
1950
/* Adjust the header */
1951
if (socket_data->next_incoming) {
1952
header->acknowledgement_number =
1953
htonl(socket_data->next_incoming);
1617
1954
header->acknowledge = 1;
1619
1956
header->window = htons(socket_data->window);
1622
1959
header->checksum = 0;
1623
checksum = compute_checksum(0, socket_data->pseudo_header, socket_data->headerlen);
1624
checksum = compute_checksum(checksum, (uint8_t *) packet_get_data(packet), packet_get_data_length(packet));
1960
checksum = compute_checksum(0, socket_data->pseudo_header,
1961
socket_data->headerlen);
1962
checksum = compute_checksum(checksum,
1963
(uint8_t *) packet_get_data(packet),
1964
packet_get_data_length(packet));
1625
1965
header->checksum = htons(flip_checksum(compact_checksum(checksum)));
1626
// prepare the packet
1627
if(ERROR_OCCURRED(ip_client_prepare_packet(packet, IPPROTO_TCP, 0, 0, 0, 0))
1628
// prepare the timeout
1629
|| ERROR_OCCURRED(tcp_prepare_timeout(tcp_timeout, socket, socket_data, sequence_number, socket_data->state, socket_data->timeout, true))){
1630
pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
1967
/* Prepare the packet */
1968
rc = ip_client_prepare_packet(packet, IPPROTO_TCP, 0, 0, 0, 0);
1970
pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
1974
rc = tcp_prepare_timeout(tcp_timeout, socket, socket_data,
1975
sequence_number, socket_data->state, socket_data->timeout, true);
1977
pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
1636
packet_t tcp_prepare_copy(socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length, size_t sequence_number){
1984
packet_t *tcp_prepare_copy(socket_core_t *socket, tcp_socket_data_t *
1985
socket_data, packet_t *packet, size_t data_length, size_t sequence_number)
1639
1989
assert(socket);
1640
1990
assert(socket_data);
1641
1991
assert(socket->specific_data == socket_data);
1643
// make a copy of the packet
1993
/* Make a copy of the packet */
1644
1994
copy = packet_get_copy(tcp_globals.net_phone, packet);
1649
return tcp_send_prepare_packet(socket, socket_data, copy, data_length, sequence_number);
1998
return tcp_send_prepare_packet(socket, socket_data, copy, data_length,
1652
void tcp_send_packets(device_id_t device_id, packet_t packet){
2002
void tcp_send_packets(device_id_t device_id, packet_t *packet)
1656
2007
next = pq_detach(packet);
1657
ip_send_msg(tcp_globals.ip_phone, device_id, packet, SERVICE_TCP, 0);
2008
ip_send_msg(tcp_globals.ip_phone, device_id, packet,
1662
void tcp_prepare_operation_header(socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, int synchronize, int finalize){
2014
void tcp_prepare_operation_header(socket_core_t *socket,
2015
tcp_socket_data_t *socket_data, tcp_header_t *header, int synchronize,
1663
2018
assert(socket);
1664
2019
assert(socket_data);
1665
2020
assert(socket->specific_data == socket_data);
1695
2055
operation_timeout->sequence_number = sequence_number;
1696
2056
operation_timeout->state = state;
1699
operation_timeout->key = ((char *) operation_timeout) + sizeof(*operation_timeout);
2059
operation_timeout->key = ((uint8_t *) operation_timeout) +
2060
sizeof(*operation_timeout);
1700
2061
operation_timeout->key_length = socket->key_length;
1701
2062
memcpy(operation_timeout->key, socket->key, socket->key_length);
1702
2063
operation_timeout->key[operation_timeout->key_length] = '\0';
1704
// prepare the timeouting thread
2065
/* Prepare the timeouting thread */
1705
2066
fibril = fibril_create(timeout_function, operation_timeout);
1707
2068
free(operation_timeout);
1710
// fibril_mutex_lock(&socket_data->operation.mutex);
1711
// start the timeouting fibril
2072
// fibril_mutex_lock(&socket_data->operation.mutex);
2073
/* Start the timeout fibril */
1712
2074
fibril_add_ready(fibril);
1713
2075
//socket_data->state = state;
1717
int tcp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, int flags, size_t * addrlen){
1720
socket_core_ref socket;
1721
tcp_socket_data_ref socket_data;
2079
int tcp_recvfrom_message(socket_cores_t *local_sockets, int socket_id,
2080
int flags, size_t *addrlen)
2082
socket_core_t *socket;
2083
tcp_socket_data_t *socket_data;
1726
2089
assert(local_sockets);
2091
/* Find the socket */
1729
2092
socket = socket_cores_find(local_sockets, socket_id);
1731
2094
return ENOTSOCK;
1733
// get the socket specific data
1734
if(! socket->specific_data){
2096
/* Get the socket specific data */
2097
if (!socket->specific_data)
1735
2098
return NO_DATA;
1737
socket_data = (tcp_socket_data_ref) socket->specific_data;
1740
if((socket_data->state != TCP_SOCKET_ESTABLISHED) && (socket_data->state != TCP_SOCKET_CLOSE_WAIT)){
2100
socket_data = (tcp_socket_data_t *) socket->specific_data;
2103
if ((socket_data->state != TCP_SOCKET_ESTABLISHED) &&
2104
(socket_data->state != TCP_SOCKET_CLOSE_WAIT))
1741
2105
return ENOTCONN;
1744
// send the source address if desired
1746
ERROR_PROPAGATE(data_reply(socket_data->addr, socket_data->addrlen));
2107
/* Send the source address if desired */
2109
rc = data_reply(socket_data->addr, socket_data->addrlen);
1747
2112
*addrlen = socket_data->addrlen;
1750
// get the next received packet
2115
/* Get the next received packet */
1751
2116
packet_id = dyn_fifo_value(&socket->received);
1753
2118
return NO_DATA;
1755
ERROR_PROPAGATE(packet_translate_remote(tcp_globals.net_phone, &packet, packet_id));
1757
// reply the packets
1758
ERROR_PROPAGATE(socket_reply_packets(packet, &length));
1760
// release the packet
2120
rc = packet_translate_remote(tcp_globals.net_phone, &packet, packet_id);
2124
/* Reply the packets */
2125
rc = socket_reply_packets(packet, &length);
2129
/* Release the packet */
1761
2130
dyn_fifo_pop(&socket->received);
1762
2131
pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
1763
// return the total length
2133
/* Return the total length */
1764
2134
return (int) length;
1767
int tcp_send_message(socket_cores_ref local_sockets, int socket_id, int fragments, size_t * data_fragment_size, int flags){
1770
socket_core_ref socket;
1771
tcp_socket_data_ref socket_data;
1772
packet_dimension_ref packet_dimension;
2137
int tcp_send_message(socket_cores_t *local_sockets, int socket_id,
2138
int fragments, size_t *data_fragment_size, int flags)
2140
socket_core_t *socket;
2141
tcp_socket_data_t *socket_data;
2142
packet_dimension_t *packet_dimension;
1774
2144
size_t total_length;
1775
tcp_header_ref header;
2145
tcp_header_t *header;
1779
2150
assert(local_sockets);
1780
2151
assert(data_fragment_size);
2153
/* Find the socket */
1783
2154
socket = socket_cores_find(local_sockets, socket_id);
1785
2156
return ENOTSOCK;
1787
// get the socket specific data
1788
if(! socket->specific_data){
2158
/* Get the socket specific data */
2159
if (!socket->specific_data)
1789
2160
return NO_DATA;
1791
socket_data = (tcp_socket_data_ref) socket->specific_data;
1794
if((socket_data->state != TCP_SOCKET_ESTABLISHED) && (socket_data->state != TCP_SOCKET_CLOSE_WAIT)){
2162
socket_data = (tcp_socket_data_t *) socket->specific_data;
2165
if ((socket_data->state != TCP_SOCKET_ESTABLISHED) &&
2166
(socket_data->state != TCP_SOCKET_CLOSE_WAIT))
1795
2167
return ENOTCONN;
1798
ERROR_PROPAGATE(tl_get_ip_packet_dimension(tcp_globals.ip_phone, &tcp_globals.dimensions, socket_data->device_id, &packet_dimension));
1800
*data_fragment_size = ((packet_dimension->content < socket_data->data_fragment_size) ? packet_dimension->content : socket_data->data_fragment_size);
1802
for(index = 0; index < fragments; ++ index){
1803
// read the data fragment
1804
result = tl_socket_read_packet_data(tcp_globals.net_phone, &packet, TCP_HEADER_SIZE, packet_dimension, socket_data->addr, socket_data->addrlen);
2169
rc = tl_get_ip_packet_dimension(tcp_globals.ip_phone,
2170
&tcp_globals.dimensions, socket_data->device_id, &packet_dimension);
2174
*data_fragment_size =
2175
((packet_dimension->content < socket_data->data_fragment_size) ?
2176
packet_dimension->content : socket_data->data_fragment_size);
2178
for (index = 0; index < fragments; index++) {
2179
/* Read the data fragment */
2180
result = tl_socket_read_packet_data(tcp_globals.net_phone,
2181
&packet, TCP_HEADER_SIZE, packet_dimension,
2182
socket_data->addr, socket_data->addrlen);
1808
2186
total_length = (size_t) result;
1809
// prefix the tcp header
2188
/* Prefix the TCP header */
1810
2189
header = PACKET_PREFIX(packet, tcp_header_t);
1812
2191
return tcp_release_and_return(packet, ENOMEM);
1814
2193
tcp_prepare_operation_header(socket, socket_data, header, 0, 0);
1815
ERROR_PROPAGATE(tcp_queue_packet(socket, socket_data, packet, 0));
2194
rc = tcp_queue_packet(socket, socket_data, packet, total_length);
1819
2200
packet = tcp_get_packets_to_send(socket, socket_data);
1820
2201
fibril_rwlock_write_unlock(socket_data->local_lock);
1821
2202
fibril_rwlock_read_unlock(&tcp_globals.lock);
2205
/* Send the packet */
1824
2206
tcp_send_packets(socket_data->device_id, packet);
1830
int tcp_close_message(socket_cores_ref local_sockets, int socket_id){
1833
socket_core_ref socket;
1834
tcp_socket_data_ref socket_data;
2213
tcp_close_message(socket_cores_t *local_sockets, int socket_id)
2215
socket_core_t *socket;
2216
tcp_socket_data_t *socket_data;
2220
/* Find the socket */
1838
2221
socket = socket_cores_find(local_sockets, socket_id);
1840
2223
return ENOTSOCK;
1842
// get the socket specific data
1843
socket_data = (tcp_socket_data_ref) socket->specific_data;
2225
/* Get the socket specific data */
2226
socket_data = (tcp_socket_data_t *) socket->specific_data;
1844
2227
assert(socket_data);
1847
switch(socket_data->state){
1848
case TCP_SOCKET_ESTABLISHED:
1849
socket_data->state = TCP_SOCKET_FIN_WAIT_1;
1851
case TCP_SOCKET_CLOSE_WAIT:
1852
socket_data->state = TCP_SOCKET_LAST_ACK;
1854
// case TCP_SOCKET_LISTEN:
1857
if(! ERROR_OCCURRED(socket_destroy(tcp_globals.net_phone, socket_id, local_sockets, &tcp_globals.sockets, tcp_free_socket_data))){
1858
fibril_rwlock_write_unlock(socket_data->local_lock);
1859
fibril_rwlock_write_unlock(&tcp_globals.lock);
2230
switch (socket_data->state) {
2231
case TCP_SOCKET_ESTABLISHED:
2232
socket_data->state = TCP_SOCKET_FIN_WAIT_1;
2235
case TCP_SOCKET_CLOSE_WAIT:
2236
socket_data->state = TCP_SOCKET_LAST_ACK;
2239
// case TCP_SOCKET_LISTEN:
2243
rc = socket_destroy(tcp_globals.net_phone, socket_id,
2244
local_sockets, &tcp_globals.sockets,
2245
tcp_free_socket_data);
2247
fibril_rwlock_write_unlock(socket_data->local_lock);
2248
fibril_rwlock_write_unlock(&tcp_globals.lock);
1864
// TODO should I wait to complete?
1866
// create the notification packet
1867
ERROR_PROPAGATE(tcp_create_notification_packet(&packet, socket, socket_data, 0, 1));
1870
ERROR_PROPAGATE(tcp_queue_packet(socket, socket_data, packet, 1));
2255
* TODO should I wait to complete?
2258
/* Create the notification packet */
2259
rc = tcp_create_notification_packet(&packet, socket, socket_data, 0, 1);
2263
/* Send the packet */
2264
rc = tcp_queue_packet(socket, socket_data, packet, 1);
1873
2269
packet = tcp_get_packets_to_send(socket, socket_data);
1874
2270
fibril_rwlock_write_unlock(socket_data->local_lock);
1875
2271
fibril_rwlock_write_unlock(&tcp_globals.lock);
2274
/* Send the packet */
1878
2275
tcp_send_packets(socket_data->device_id, packet);
1883
int tcp_create_notification_packet(packet_t * packet, socket_core_ref socket, tcp_socket_data_ref socket_data, int synchronize, int finalize){
1886
packet_dimension_ref packet_dimension;
1887
tcp_header_ref header;
2281
int tcp_create_notification_packet(packet_t **packet, socket_core_t *socket,
2282
tcp_socket_data_t *socket_data, int synchronize, int finalize)
2284
packet_dimension_t *packet_dimension;
2285
tcp_header_t *header;
1889
2288
assert(packet);
1891
// get the device packet dimension
1892
ERROR_PROPAGATE(tl_get_ip_packet_dimension(tcp_globals.ip_phone, &tcp_globals.dimensions, socket_data->device_id, &packet_dimension));
1894
*packet = packet_get_4_remote(tcp_globals.net_phone, TCP_HEADER_SIZE, packet_dimension->addr_len, packet_dimension->prefix, packet_dimension->suffix);
2290
/* Get the device packet dimension */
2291
rc = tl_get_ip_packet_dimension(tcp_globals.ip_phone,
2292
&tcp_globals.dimensions, socket_data->device_id, &packet_dimension);
2296
/* Get a new packet */
2297
*packet = packet_get_4_remote(tcp_globals.net_phone, TCP_HEADER_SIZE,
2298
packet_dimension->addr_len, packet_dimension->prefix,
2299
packet_dimension->suffix);
1898
// allocate space in the packet
2304
/* Allocate space in the packet */
1899
2305
header = PACKET_SUFFIX(*packet, tcp_header_t);
1901
2307
tcp_release_and_return(*packet, ENOMEM);
1904
tcp_prepare_operation_header(socket, socket_data, header, synchronize, finalize);
2309
tcp_prepare_operation_header(socket, socket_data, header, synchronize,
1908
int tcp_accept_message(socket_cores_ref local_sockets, int socket_id, int new_socket_id, size_t * data_fragment_size, size_t * addrlen){
1911
socket_core_ref accepted;
1912
socket_core_ref socket;
1913
tcp_socket_data_ref socket_data;
1914
packet_dimension_ref packet_dimension;
2315
int tcp_accept_message(socket_cores_t *local_sockets, int socket_id,
2316
int new_socket_id, size_t *data_fragment_size, size_t *addrlen)
2318
socket_core_t *accepted;
2319
socket_core_t *socket;
2320
tcp_socket_data_t *socket_data;
2321
packet_dimension_t *packet_dimension;
1916
2324
assert(local_sockets);
1917
2325
assert(data_fragment_size);
1918
2326
assert(addrlen);
2328
/* Find the socket */
1921
2329
socket = socket_cores_find(local_sockets, socket_id);
1923
2331
return ENOTSOCK;
1925
// get the socket specific data
1926
socket_data = (tcp_socket_data_ref) socket->specific_data;
2333
/* Get the socket specific data */
2334
socket_data = (tcp_socket_data_t *) socket->specific_data;
1927
2335
assert(socket_data);
1930
if(socket_data->state != TCP_SOCKET_LISTEN){
2338
if (socket_data->state != TCP_SOCKET_LISTEN)
1935
2342
socket_id = dyn_fifo_value(&socket->accepted);
1937
2344
return ENOTSOCK;
1939
2345
socket_id *= -1;
1941
2347
accepted = socket_cores_find(local_sockets, socket_id);
1943
2349
return ENOTSOCK;
1945
// get the socket specific data
1946
socket_data = (tcp_socket_data_ref) accepted->specific_data;
2351
/* Get the socket specific data */
2352
socket_data = (tcp_socket_data_t *) accepted->specific_data;
1947
2353
assert(socket_data);
1948
// TODO can it be in another state?
1949
if(socket_data->state == TCP_SOCKET_ESTABLISHED){
1950
ERROR_PROPAGATE(data_reply(socket_data->addr, socket_data->addrlen));
1951
ERROR_PROPAGATE(tl_get_ip_packet_dimension(tcp_globals.ip_phone, &tcp_globals.dimensions, socket_data->device_id, &packet_dimension));
2354
/* TODO can it be in another state? */
2355
if (socket_data->state == TCP_SOCKET_ESTABLISHED) {
2356
rc = data_reply(socket_data->addr,
2357
socket_data->addrlen);
2360
rc = tl_get_ip_packet_dimension(tcp_globals.ip_phone,
2361
&tcp_globals.dimensions, socket_data->device_id,
1952
2365
*addrlen = socket_data->addrlen;
1953
*data_fragment_size = ((packet_dimension->content < socket_data->data_fragment_size) ? packet_dimension->content : socket_data->data_fragment_size);
1954
if(new_socket_id > 0){
1955
ERROR_PROPAGATE(socket_cores_update(local_sockets, accepted->socket_id, new_socket_id));
2367
*data_fragment_size =
2368
((packet_dimension->content <
2369
socket_data->data_fragment_size) ?
2370
packet_dimension->content :
2371
socket_data->data_fragment_size);
2373
if (new_socket_id > 0) {
2374
rc = socket_cores_update(local_sockets,
2375
accepted->socket_id, new_socket_id);
1956
2378
accepted->socket_id = new_socket_id;
1959
2381
dyn_fifo_pop(&socket->accepted);
1960
}while(socket_data->state != TCP_SOCKET_ESTABLISHED);
2382
} while (socket_data->state != TCP_SOCKET_ESTABLISHED);
1961
2384
printf("ret accept %d\n", accepted->socket_id);
1962
2385
return accepted->socket_id;
1965
void tcp_free_socket_data(socket_core_ref socket){
1966
tcp_socket_data_ref socket_data;
2388
void tcp_free_socket_data(socket_core_t *socket)
2390
tcp_socket_data_t *socket_data;
1968
2392
assert(socket);
1970
2394
printf("destroy_socket %d\n", socket->socket_id);
1972
// get the socket specific data
1973
socket_data = (tcp_socket_data_ref) socket->specific_data;
2396
/* Get the socket specific data */
2397
socket_data = (tcp_socket_data_t *) socket->specific_data;
1974
2398
assert(socket_data);
1975
//free the pseudo header
1976
if(socket_data->pseudo_header){
1977
if(socket_data->headerlen){
2400
/* Free the pseudo header */
2401
if (socket_data->pseudo_header) {
2402
if (socket_data->headerlen) {
1978
2403
printf("d pseudo\n");
1979
2404
free(socket_data->pseudo_header);
1980
2405
socket_data->headerlen = 0;
1982
2407
socket_data->pseudo_header = NULL;
1984
2410
socket_data->headerlen = 0;
1986
if(socket_data->addr){
1987
if(socket_data->addrlen){
2412
/* Free the address */
2413
if (socket_data->addr) {
2414
if (socket_data->addrlen) {
1988
2415
printf("d addr\n");
1989
2416
free(socket_data->addr);
1990
2417
socket_data->addrlen = 0;