~jakub/helenos/ia64-revival

« back to all changes in this revision

Viewing changes to uspace/srv/net/tl/tcp/tcp.c

  • Committer: Jakub Jermar
  • Date: 2011-04-13 14:45:41 UTC
  • mfrom: (527.1.397 main-clone)
  • Revision ID: jakub@jermar.eu-20110413144541-x0j3r1zxqhsljx1o
MergeĀ mainlineĀ changes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
 */
28
28
 
29
29
/** @addtogroup tcp
30
 
 *  @{
 
30
 * @{
31
31
 */
32
32
 
33
33
/** @file
34
 
 *  TCP module implementation.
35
 
 *  @see tcp.h
 
34
 * TCP module implementation.
 
35
 * @see tcp.h
36
36
 */
37
37
 
38
38
#include <assert.h>
39
39
#include <async.h>
40
40
#include <fibril_synch.h>
41
41
#include <malloc.h>
42
 
//TODO remove stdio
 
42
/* TODO remove stdio */
43
43
#include <stdio.h>
 
44
#include <errno.h>
44
45
 
45
 
#include <ipc/ipc.h>
46
46
#include <ipc/services.h>
47
 
 
48
 
#include <net_err.h>
49
 
#include <net_messages.h>
50
 
#include <net_modules.h>
 
47
#include <ipc/net.h>
 
48
#include <ipc/tl.h>
 
49
#include <ipc/socket.h>
 
50
 
 
51
#include <net/socket_codes.h>
 
52
#include <net/ip_protocols.h>
 
53
#include <net/in.h>
 
54
#include <net/in6.h>
 
55
#include <net/inet.h>
 
56
#include <net/modules.h>
 
57
 
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>
55
 
#include <in.h>
56
 
#include <in6.h>
57
 
#include <inet.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>
71
 
#include <tl_local.h>
72
 
#include <tl_interface.h>
 
69
#include <tl_remote.h>
 
70
#include <tl_skel.h>
73
71
 
74
72
#include "tcp.h"
75
73
#include "tcp_header.h"
76
 
#include "tcp_module.h"
77
 
 
78
 
/** TCP module name.
79
 
 */
80
 
#define NAME    "TCP protocol"
81
 
 
82
 
/** The TCP window default value.
83
 
 */
84
 
#define NET_DEFAULT_TCP_WINDOW  10240
85
 
 
86
 
/** Initial timeout for new connections.
87
 
 */
 
74
 
 
75
/** TCP module name. */
 
76
#define NAME  "tcp"
 
77
 
 
78
/** The TCP window default value. */
 
79
#define NET_DEFAULT_TCP_WINDOW          10240
 
80
 
 
81
/** Initial timeout for new connections. */
88
82
#define NET_DEFAULT_TCP_INITIAL_TIMEOUT 3000000L
89
83
 
90
 
/** Default timeout for closing.
91
 
 */
92
 
#define NET_DEFAULT_TCP_TIME_WAIT_TIMEOUT       2000L
93
 
 
94
 
/** The initial outgoing sequence number.
95
 
 */
96
 
#define TCP_INITIAL_SEQUENCE_NUMBER             2999
97
 
 
98
 
/** Maximum TCP fragment size.
99
 
 */
100
 
#define MAX_TCP_FRAGMENT_SIZE   65535
101
 
 
102
 
/** Free ports pool start.
103
 
 */
104
 
#define TCP_FREE_PORTS_START    1025
105
 
 
106
 
/** Free ports pool end.
107
 
 */
 
84
/** Default timeout for closing. */
 
85
#define NET_DEFAULT_TCP_TIME_WAIT_TIMEOUT 2000L
 
86
 
 
87
/** The initial outgoing sequence number. */
 
88
#define TCP_INITIAL_SEQUENCE_NUMBER     2999
 
89
 
 
90
/** Maximum TCP fragment size. */
 
91
#define MAX_TCP_FRAGMENT_SIZE           65535
 
92
 
 
93
/** Free ports pool start. */
 
94
#define TCP_FREE_PORTS_START            1025
 
95
 
 
96
/** Free ports pool end. */
108
97
#define TCP_FREE_PORTS_END              65535
109
98
 
110
 
/** Timeout for connection initialization, SYN sent.
111
 
 */
112
 
#define TCP_SYN_SENT_TIMEOUT    1000000L
 
99
/** Timeout for connection initialization, SYN sent. */
 
100
#define TCP_SYN_SENT_TIMEOUT            1000000L
113
101
 
114
 
/** The maximum number of timeouts in a row before singaling connection lost.
115
 
 */
 
102
/** The maximum number of timeouts in a row before singaling connection lost. */
116
103
#define TCP_MAX_TIMEOUTS                8
117
104
 
118
 
/** The number of acknowledgements before retransmit.
119
 
 */
 
105
/** The number of acknowledgements before retransmit. */
120
106
#define TCP_FAST_RETRANSMIT_COUNT       3
121
107
 
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.
 
110
 *
 
111
 * The high end and/or the value may overflow, be lower than the low value.
 
112
 *
 
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.
127
116
 */
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))))
129
121
 
130
122
/** Type definition of the TCP timeout.
131
123
 *  @see tcp_timeout
132
124
 */
133
 
typedef struct tcp_timeout      tcp_timeout_t;
134
 
 
135
 
/** Type definition of the TCP timeout pointer.
136
 
 *  @see tcp_timeout
137
 
 */
138
 
typedef tcp_timeout_t * tcp_timeout_ref;
 
125
typedef struct tcp_timeout tcp_timeout_t;
139
126
 
140
127
/** TCP reply timeout data.
141
128
 *  Used as a timeouting fibril argument.
142
129
 *  @see tcp_timeout()
143
130
 */
144
 
struct tcp_timeout{
145
 
        /** TCP global data are going to be read only.
146
 
         */
 
131
struct tcp_timeout {
 
132
        /** TCP global data are going to be read only. */
147
133
        int globals_read_only;
148
 
        /** Socket port.
149
 
         */
 
134
 
 
135
        /** Socket port. */
150
136
        int port;
151
 
        /** Local sockets.
152
 
         */
153
 
        socket_cores_ref local_sockets;
154
 
        /** Socket identifier.
155
 
         */
 
137
 
 
138
        /** Local sockets. */
 
139
        socket_cores_t *local_sockets;
 
140
 
 
141
        /** Socket identifier. */
156
142
        int socket_id;
157
 
        /** Socket state.
158
 
         */
 
143
 
 
144
        /** Socket state. */
159
145
        tcp_socket_state_t state;
160
 
        /** Sent packet sequence number.
161
 
         */
 
146
 
 
147
        /** Sent packet sequence number. */
162
148
        int sequence_number;
163
 
        /** Timeout in microseconds.
164
 
         */
 
149
 
 
150
        /** Timeout in microseconds. */
165
151
        suseconds_t timeout;
166
 
        /** Port map key.
167
 
         */
168
 
        char * key;
169
 
        /** Port map key length.
170
 
         */
 
152
 
 
153
        /** Port map key. */
 
154
        uint8_t *key;
 
155
 
 
156
        /** Port map key length. */
171
157
        size_t key_length;
172
158
};
173
159
 
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.
178
 
 */
179
 
int tcp_release_and_return(packet_t packet, int result);
180
 
 
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);
204
 
 
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);
213
 
 
214
 
/** TCP global data.
215
 
 */
216
 
tcp_globals_t   tcp_globals;
217
 
 
218
 
int tcp_initialize(async_client_conn_t client_connection){
219
 
        ERROR_DECLARE;
220
 
 
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;
228
 
        }
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);
232
 
                return ERROR_CODE;
233
 
        }
234
 
        tcp_globals.last_used_port = TCP_FREE_PORTS_START - 1;
235
 
        fibril_rwlock_write_unlock(&tcp_globals.lock);
236
 
        return EOK;
237
 
}
238
 
 
239
 
int tcp_received_msg(device_id_t device_id, packet_t packet, services_t receiver, services_t error){
240
 
        ERROR_DECLARE;
241
 
 
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 *);
 
166
 
 
167
static int tcp_timeout(void *);
 
168
 
 
169
static int tcp_release_after_timeout(void *);
 
170
 
 
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 *,
 
175
    packet_t *, size_t);
 
176
static int tcp_queue_packet(socket_core_t *, tcp_socket_data_t *, packet_t *,
 
177
    size_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 *);
 
180
 
 
181
static void tcp_process_acknowledgement(socket_core_t *, tcp_socket_data_t *,
 
182
    tcp_header_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 *,
 
188
    size_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 *);
 
192
 
 
193
static void tcp_initialize_socket_data(tcp_socket_data_t *);
 
194
 
 
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);
 
206
 
 
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);
 
209
 
 
210
static int tcp_listen_message(socket_cores_t *, int, int);
 
211
static int tcp_connect_message(socket_cores_t *, int, struct sockaddr *,
 
212
    socklen_t);
 
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);
 
217
 
 
218
/** TCP global data. */
 
219
tcp_globals_t tcp_globals;
 
220
 
 
221
int tcp_received_msg(device_id_t device_id, packet_t *packet,
 
222
    services_t receiver, services_t error)
 
223
{
 
224
        int rc;
 
225
 
 
226
        if (receiver != SERVICE_TCP)
243
227
                return EREFUSED;
244
 
        }
 
228
 
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);
 
231
        if (rc != EOK)
247
232
                fibril_rwlock_write_unlock(&tcp_globals.lock);
248
 
        }
249
 
        printf("receive %d \n", ERROR_CODE);
250
 
 
251
 
        return ERROR_CODE;
 
233
 
 
234
        printf("receive %d \n", rc);
 
235
 
 
236
        return rc;
252
237
}
253
238
 
254
 
int tcp_process_packet(device_id_t device_id, packet_t packet, services_t error){
255
 
        ERROR_DECLARE;
256
 
 
 
239
int tcp_process_packet(device_id_t device_id, packet_t *packet, services_t error)
 
240
{
257
241
        size_t length;
258
242
        size_t offset;
259
243
        int result;
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;
266
250
        int fragments;
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;
271
255
        size_t addrlen;
272
 
 
273
 
        printf("p1 \n");
274
 
        if(error){
275
 
                switch(error){
276
 
                        case SERVICE_ICMP:
277
 
                                // process error
278
 
                                result = icmp_client_process_packet(packet, &type, &code, NULL, NULL);
279
 
                                if(result < 0){
280
 
                                        return tcp_release_and_return(packet, result);
281
 
                                }
282
 
                                length = (size_t) result;
283
 
                                if(ERROR_OCCURRED(packet_trim(packet, length, 0))){
284
 
                                        return tcp_release_and_return(packet, ERROR_CODE);
285
 
                                }
286
 
                                break;
287
 
                        default:
288
 
                                return tcp_release_and_return(packet, ENOTSUP);
289
 
                }
 
256
        int rc;
 
257
 
 
258
        switch (error) {
 
259
        case SERVICE_NONE:
 
260
                break;
 
261
        case SERVICE_ICMP:
 
262
                /* Process error */
 
263
                result = icmp_client_process_packet(packet, &type, &code, NULL,
 
264
                    NULL);
 
265
                if (result < 0)
 
266
                        return tcp_release_and_return(packet, result);
 
267
 
 
268
                length = (size_t) result;
 
269
                rc = packet_trim(packet, length, 0);
 
270
                if (rc != EOK)
 
271
                        return tcp_release_and_return(packet, rc);
 
272
                break;
 
273
        default:
 
274
                return tcp_release_and_return(packet, ENOTSUP);
290
275
        }
291
276
 
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);
295
 
        if(result < 0){
 
279
        if (result < 0)
296
280
                return tcp_release_and_return(packet, result);
297
 
        }
 
281
 
298
282
        offset = (size_t) result;
299
283
 
300
284
        length = packet_get_data_length(packet);
301
 
//      printf("packet len %d\n", length);
302
 
        if(length <= 0){
 
285
        if (length <= 0)
303
286
                return tcp_release_and_return(packet, EINVAL);
304
 
        }
305
 
        if(length < TCP_HEADER_SIZE + offset){
306
 
                return tcp_release_and_return(packet, NO_DATA);
307
 
        }
308
 
 
309
 
        // trim all but TCP header
310
 
        if(ERROR_OCCURRED(packet_trim(packet, offset, 0))){
311
 
                return tcp_release_and_return(packet, ERROR_CODE);
312
 
        }
313
 
 
314
 
        // get tcp header
315
 
        header = (tcp_header_ref) packet_get_data(packet);
316
 
        if(! header){
317
 
                return tcp_release_and_return(packet, NO_DATA);
318
 
        }
319
 
//      printf("header len %d, port %d \n", TCP_HEADER_LENGTH(header), ntohs(header->destination_port));
320
 
 
 
287
 
 
288
        if (length < TCP_HEADER_SIZE + offset)
 
289
                return tcp_release_and_return(packet, NO_DATA);
 
290
 
 
291
        /* Trim all but TCP header */
 
292
        rc = packet_trim(packet, offset, 0);
 
293
        if (rc != EOK)
 
294
                return tcp_release_and_return(packet, rc);
 
295
 
 
296
        /* Get tcp header */
 
297
        header = (tcp_header_t *) packet_get_data(packet);
 
298
        if (!header)
 
299
                return tcp_release_and_return(packet, NO_DATA);
 
300
 
 
301
#if 0
 
302
        printf("header len %d, port %d \n", TCP_HEADER_LENGTH(header),
 
303
            ntohs(header->destination_port));
 
304
#endif
321
305
        result = packet_get_addr(packet, (uint8_t **) &src, (uint8_t **) &dest);
322
 
        if(result <= 0){
 
306
        if (result <= 0)
323
307
                return tcp_release_and_return(packet, result);
324
 
        }
 
308
 
325
309
        addrlen = (size_t) result;
326
310
 
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));
 
312
        if (rc != EOK)
 
313
                return tcp_release_and_return(packet, rc);
 
314
        
 
315
        /* Find the destination socket */
 
316
        socket = socket_port_find(&tcp_globals.sockets,
 
317
            ntohs(header->destination_port), (uint8_t *) src, addrlen);
 
318
        if (!socket) {
 
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);
329
323
        }
330
324
 
331
 
        // find the destination socket
332
 
        socket = socket_port_find(&tcp_globals.sockets, ntohs(header->destination_port), (const char *) src, addrlen);
333
 
        if(! socket){
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);
337
 
                if(! socket){
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);
340
 
                        }
341
 
                        return EADDRNOTAVAIL;
 
325
        if (!socket) {
 
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);
342
330
                }
 
331
                return EADDRNOTAVAIL;
343
332
        }
 
333
 
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);
347
337
 
348
 
        // some data received, clear the timeout counter
 
338
        /* Some data received, clear the timeout counter */
349
339
        socket_data->timeout_count = 0;
350
340
 
351
 
        // count the received packet fragments
 
341
        /* Count the received packet fragments */
352
342
        next_packet = packet;
353
343
        fragments = 0;
354
344
        checksum = 0;
355
345
        total_length = 0;
356
 
        do{
357
 
                ++ fragments;
 
346
        do {
 
347
                fragments++;
358
348
                length = packet_get_data_length(next_packet);
359
 
                if(length <= 0){
 
349
                if (length <= 0)
360
350
                        return tcp_release_and_return(packet, NO_DATA);
361
 
                }
 
351
 
362
352
                total_length += length;
363
 
                // add partial checksum if set
364
 
                if(! error){
365
 
                        checksum = compute_checksum(checksum, packet_get_data(packet), packet_get_data_length(packet));
 
353
 
 
354
                /* Add partial checksum if set */
 
355
                if (!error) {
 
356
                        checksum = compute_checksum(checksum,
 
357
                            packet_get_data(packet),
 
358
                            packet_get_data_length(packet));
366
359
                }
367
 
        }while((next_packet = pq_next(next_packet)));
368
 
//      printf("fragments %d of %d bytes\n", fragments, total_length);
369
 
 
370
 
//      printf("lock?\n");
 
360
 
 
361
        } while ((next_packet = pq_next(next_packet)));
 
362
 
371
363
        fibril_rwlock_write_lock(socket_data->local_lock);
372
 
//      printf("locked\n");
373
 
        if(! error){
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;
379
 
                        }
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);
383
 
                        }
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);
387
 
                }
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);
395
 
                        }
396
 
                        return EINVAL;
397
 
                }
398
 
        }
399
 
 
400
 
        fibril_rwlock_read_unlock(&tcp_globals.lock);
401
 
 
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);
407
 
                        break;
408
 
                case TCP_SOCKET_SYN_RECEIVED:
409
 
                        ERROR_CODE = tcp_process_syn_received(socket, socket_data, header, packet);
410
 
                        break;
411
 
                case TCP_SOCKET_SYN_SENT:
412
 
                        ERROR_CODE = tcp_process_syn_sent(socket, socket_data, header, packet);
413
 
                        break;
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);
424
 
                        break;
425
 
                default:
426
 
                        pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
427
 
        }
428
 
 
429
 
        if(ERROR_CODE != EOK){
430
 
                printf("process %d\n", ERROR_CODE);
431
 
                fibril_rwlock_write_unlock(socket_data->local_lock);
432
 
        }
 
364
 
 
365
        if (error)
 
366
                goto has_error_service;
 
367
        
 
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;
 
373
                }
 
374
 
 
375
                rc = ip_client_get_pseudo_header(IPPROTO_TCP, src, addrlen,
 
376
                    dest, addrlen, total_length, &socket_data->pseudo_header,
 
377
                    &socket_data->headerlen);
 
378
                if (rc != EOK) {
 
379
                        fibril_rwlock_write_unlock(socket_data->local_lock);
 
380
                        return tcp_release_and_return(packet, rc);
 
381
                }
 
382
        } else {
 
383
                rc = ip_client_set_pseudo_header_data_length(
 
384
                    socket_data->pseudo_header, socket_data->headerlen,
 
385
                    total_length);
 
386
                if (rc != EOK) {
 
387
                        fibril_rwlock_write_unlock(socket_data->local_lock);
 
388
                        return tcp_release_and_return(packet, rc);
 
389
                }
 
390
        }
 
391
        
 
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);
 
398
 
 
399
                rc = tl_prepare_icmp_packet(tcp_globals.net_phone,
 
400
                    tcp_globals.icmp_phone, packet, error);
 
401
                if (rc == EOK) {
 
402
                        /* Checksum error ICMP */
 
403
                        icmp_parameter_problem_msg(tcp_globals.icmp_phone,
 
404
                            ICMP_PARAM_POINTER,
 
405
                            ((size_t) ((void *) &header->checksum)) -
 
406
                            ((size_t) ((void *) header)), packet);
 
407
                }
 
408
 
 
409
                return EINVAL;
 
410
        }
 
411
 
 
412
has_error_service:
 
413
        fibril_rwlock_write_unlock(&tcp_globals.lock);
 
414
 
 
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,
 
419
                    src, dest, addrlen);
 
420
                break;
 
421
        case TCP_SOCKET_SYN_RECEIVED:
 
422
                rc = tcp_process_syn_received(socket, socket_data, header,
 
423
                    packet);
 
424
                break;
 
425
        case TCP_SOCKET_SYN_SENT:
 
426
                rc = tcp_process_syn_sent(socket, socket_data, header, packet);
 
427
                break;
 
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);
 
439
                break;
 
440
        default:
 
441
                pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
 
442
        }
 
443
 
 
444
        if (rc != EOK) {
 
445
                fibril_rwlock_write_unlock(socket_data->local_lock);
 
446
                printf("process %d\n", rc);
 
447
        }
 
448
 
433
449
        return EOK;
434
450
}
435
451
 
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){
437
 
        ERROR_DECLARE;
438
 
 
439
 
        packet_t next_packet;
440
 
        packet_t tmp_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,
 
454
    size_t total_length)
 
455
{
 
456
        packet_t *next_packet;
 
457
        packet_t *tmp_packet;
441
458
        uint32_t old_incoming;
442
459
        size_t order;
443
460
        uint32_t sequence_number;
444
461
        size_t length;
445
462
        size_t offset;
446
463
        uint32_t new_sequence_number;
 
464
        bool forced_ack;
 
465
        int rc;
447
466
 
448
467
        assert(socket);
449
468
        assert(socket_data);
451
470
        assert(header);
452
471
        assert(packet);
453
472
 
 
473
        forced_ack = false;
 
474
 
454
475
        new_sequence_number = ntohl(header->sequence_number);
455
476
        old_incoming = socket_data->next_incoming;
456
477
 
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);
459
481
        }
460
482
 
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;
467
 
                }else{
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)) {
 
486
 
 
487
                /* Get the acknowledged offset */
 
488
                if (socket_data->next_incoming < new_sequence_number) {
 
489
                        offset = new_sequence_number -
 
490
                            socket_data->next_incoming;
 
491
                } else {
 
492
                        offset = socket_data->next_incoming -
 
493
                            new_sequence_number;
469
494
                }
470
 
//              printf("offset %d\n", offset);
 
495
 
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
 
499
 
 
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);
482
509
                }
483
 
                if((offset > 0)
484
 
                        && (ERROR_OCCURRED(packet_trim(packet, offset, 0)))){
485
 
                        return tcp_release_and_return(packet, ERROR_CODE);
 
510
 
 
511
                if (offset > 0) {
 
512
                        rc = packet_trim(packet, offset, 0);
 
513
                        if (rc != EOK)
 
514
                                return tcp_release_and_return(packet, rc);
486
515
                }
 
516
 
487
517
                assert(new_sequence_number == socket_data->next_incoming);
488
518
        }
489
519
 
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);
493
 
//      }
494
 
 
 
520
        /* Release if overflowing the window */
495
521
/*
 
522
        if (IS_IN_INTERVAL_OVERFLOW(socket_data->next_incoming +
 
523
            socket_data->window, new_sequence_number, new_sequence_number +
 
524
            total_length)) {
 
525
                return tcp_release_and_return(packet, EOVERFLOW);
 
526
        }
 
527
 
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;
501
 
                }else{
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;
 
537
                } else {
 
538
                        offset = socket_data->next_incoming +
 
539
                            socket_data->window - new_sequence_number;
503
540
                }
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);
 
547
                        else {
 
548
                                rc = packet_trim(next_packet, 0,
 
549
                                    length - offset));
 
550
                                if (rc != EOK)
 
551
                                        return tcp_release_and_return(packet,
 
552
                                            rc);
512
553
                        }
513
554
                        offset -= length;
514
555
                        total_length -= length - offset;
515
556
                }
516
557
                // release the overflowing packets
517
558
                next_packet = pq_next(next_packet);
518
 
                if(next_packet){
 
559
                if (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));
523
565
                }
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);
525
568
        }
526
569
*/
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);
532
575
 
533
 
                // remove the 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);
537
 
                }
 
578
                rc = packet_trim(packet, TCP_HEADER_LENGTH(header), 0);
 
579
                if (rc != EOK)
 
580
                        return tcp_release_and_return(packet, rc);
538
581
 
539
 
                if(total_length){
540
 
                        ERROR_PROPAGATE(tcp_queue_received_packet(socket, socket_data, packet, fragments, total_length));
541
 
                }else{
 
582
                if (total_length) {
 
583
                        rc = tcp_queue_received_packet(socket, socket_data,
 
584
                            packet, fragments, total_length);
 
585
                        if (rc != EOK)
 
586
                                return rc;
 
587
                } else {
542
588
                        total_length = 1;
543
589
                }
 
590
 
544
591
                socket_data->next_incoming = old_incoming + total_length;
545
592
                packet = socket_data->incoming;
546
 
                while(packet){
547
 
                        if(ERROR_OCCURRED(pq_get_order(socket_data->incoming, &order, NULL))){
548
 
                                // remove the corrupted packet
 
593
                while (packet) {
 
594
                        rc = pq_get_order(socket_data->incoming, &order, NULL);
 
595
                        if (rc != EOK) {
 
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;
552
 
                                }
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;
555
603
                                continue;
556
604
                        }
 
605
 
557
606
                        sequence_number = (uint32_t) order;
558
 
                        if(IS_IN_INTERVAL_OVERFLOW(sequence_number, old_incoming, socket_data->next_incoming)){
559
 
                                // move to the next
 
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);
561
 
                        // coninual data?
562
 
                        }else if(IS_IN_INTERVAL_OVERFLOW(old_incoming, sequence_number, socket_data->next_incoming)){
563
 
                                // detach the packet
 
611
                                /* Coninual data? */
 
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;
567
 
                                }
568
 
                                // get data length
 
618
                                /* Get data length */
569
619
                                length = packet_get_data_length(packet);
570
620
                                new_sequence_number = sequence_number + length;
571
 
                                if(length <= 0){
572
 
                                        // remove the empty packet
573
 
                                        pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
574
 
                                        packet = next_packet;
575
 
                                        continue;
576
 
                                }
577
 
                                // exactly following
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;
583
 
                                        continue;
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;
588
 
                                        }else{
589
 
                                                length = socket_data->next_incoming - new_sequence_number;
 
621
                                if (length <= 0) {
 
622
                                        /* Remove the empty packet */
 
623
                                        pq_release_remote(tcp_globals.net_phone,
 
624
                                            packet_get_id(packet));
 
625
                                        packet = next_packet;
 
626
                                        continue;
 
627
                                }
 
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));
 
635
                                        if (rc != EOK)
 
636
                                                return rc;
 
637
                                        socket_data->next_incoming =
 
638
                                            new_sequence_number;
 
639
                                        packet = next_packet;
 
640
                                        continue;
 
641
                                        /* At least partly following data? */
 
642
                                }
 
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;
 
649
                                        } else {
 
650
                                                length =
 
651
                                                    socket_data->next_incoming -
 
652
                                                    new_sequence_number;
590
653
                                        }
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);
 
655
                                        if (rc == EOK) {
 
656
                                                /* Queue received data */
 
657
                                                rc = tcp_queue_received_packet(
 
658
                                                    socket, socket_data, packet,
 
659
                                                    1, packet_get_data_length(
 
660
                                                    packet));
 
661
                                                if (rc != EOK)
 
662
                                                        return rc;
 
663
                                                socket_data->next_incoming =
 
664
                                                    new_sequence_number;
595
665
                                                packet = next_packet;
596
666
                                                continue;
597
667
                                        }
598
668
                                }
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;
602
673
                                continue;
603
 
                        }else{
 
674
                        } else {
604
675
                                break;
605
676
                        }
606
677
                }
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,
 
679
            new_sequence_number,
 
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);
611
684
 
612
 
                // remove the 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);
616
 
                }
 
687
                rc = packet_trim(packet, TCP_HEADER_LENGTH(header), 0);
 
688
                if (rc != EOK)
 
689
                        return tcp_release_and_return(packet, rc);
617
690
 
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));
624
 
                }else{
625
 
                        while(next_packet){
 
693
                rc = pq_add(&socket_data->incoming, packet, new_sequence_number,
 
694
                    length);
 
695
                if (rc != EOK) {
 
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));
 
701
                } else {
 
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));
 
706
 
 
707
                                rc = pq_set_order(next_packet,
 
708
                                    new_sequence_number, length);
 
709
                                if (rc != EOK) {
 
710
                                        pq_release_remote(tcp_globals.net_phone,
 
711
                                            packet_get_id(next_packet));
 
712
                                }
 
713
                                rc = pq_insert_after(packet, next_packet);
 
714
                                if (rc != EOK) {
 
715
                                        pq_release_remote(tcp_globals.net_phone,
 
716
                                            packet_get_id(next_packet));
632
717
                                }
633
718
                                next_packet = tmp_packet;
634
719
                        }
635
720
                }
636
 
        }else{
 
721
        } else {
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));
 
725
                forced_ack = true;
640
726
        }
641
727
 
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;
649
 
                                break;
650
 
                        //case TCP_ESTABLISHED:
651
 
                        default:
652
 
                                socket_data->state = TCP_SOCKET_CLOSE_WAIT;
653
 
                                break;
 
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;
 
732
 
 
733
                /* Handle FIN */
 
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;
 
739
                        break;
 
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;
 
744
                        break;
 
745
                default:
 
746
                        socket_data->state = TCP_SOCKET_CLOSE_WAIT;
 
747
                        break;
654
748
                }
655
749
        }
656
750
 
657
751
        packet = tcp_get_packets_to_send(socket, socket_data);
658
 
        if(! packet){
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,
 
755
                    socket_data, 0, 0);
 
756
                if (rc != EOK)
 
757
                        return rc;
 
758
                rc = tcp_queue_prepare_packet(socket, socket_data, packet, 1);
 
759
                if (rc != EOK)
 
760
                        return rc;
 
761
                packet = tcp_send_prepare_packet(socket, socket_data, packet, 1,
 
762
                    socket_data->last_outgoing + 1);
663
763
        }
 
764
 
664
765
        fibril_rwlock_write_unlock(socket_data->local_lock);
665
 
        // send the packet
 
766
 
 
767
        /* Send the packet */
666
768
        tcp_send_packets(socket_data->device_id, packet);
 
769
 
667
770
        return EOK;
668
771
}
669
772
 
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){
671
 
        ERROR_DECLARE;
672
 
 
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,
 
775
    size_t total_length)
 
776
{
 
777
        packet_dimension_t *packet_dimension;
 
778
        int rc;
674
779
 
675
780
        assert(socket);
676
781
        assert(socket_data);
679
784
        assert(fragments >= 1);
680
785
        assert(socket_data->window > total_length);
681
786
 
682
 
        // queue the received packet
683
 
        if(ERROR_OCCURRED(dyn_fifo_push(&socket->received, packet_get_id(packet), SOCKET_MAX_RECEIVED_SIZE))
684
 
            || ERROR_OCCURRED(tl_get_ip_packet_dimension(tcp_globals.ip_phone, &tcp_globals.dimensions, socket_data->device_id, &packet_dimension))){
685
 
                return tcp_release_and_return(packet, ERROR_CODE);
686
 
        }
 
787
        /* Queue the received packet */
 
788
        rc = dyn_fifo_push(&socket->received, packet_get_id(packet),
 
789
            SOCKET_MAX_RECEIVED_SIZE);
 
790
        if (rc != EOK)
 
791
                return tcp_release_and_return(packet, rc);
 
792
        rc = tl_get_ip_packet_dimension(tcp_globals.ip_phone,
 
793
            &tcp_globals.dimensions, socket_data->device_id, &packet_dimension);
 
794
        if (rc != EOK)
 
795
                return tcp_release_and_return(packet, rc);
687
796
 
688
 
        // decrease the window size
 
797
        /* Decrease the window size */
689
798
        socket_data->window -= total_length;
690
799
 
691
 
        // notify the destination socket
692
 
        async_msg_5(socket->phone, NET_SOCKET_RECEIVED, (ipcarg_t) socket->socket_id, ((packet_dimension->content < socket_data->data_fragment_size) ? packet_dimension->content : socket_data->data_fragment_size), 0, 0, (ipcarg_t) fragments);
 
800
        /* Notify the destination socket */
 
801
        async_msg_5(socket->phone, NET_SOCKET_RECEIVED,
 
802
            (sysarg_t) socket->socket_id,
 
803
            ((packet_dimension->content < socket_data->data_fragment_size) ?
 
804
            packet_dimension->content : socket_data->data_fragment_size), 0, 0,
 
805
            (sysarg_t) fragments);
 
806
 
693
807
        return EOK;
694
808
}
695
809
 
696
 
int tcp_process_syn_sent(socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet){
697
 
        ERROR_DECLARE;
698
 
 
699
 
        packet_t next_packet;
 
810
/** Queue end-of-data marker on the socket.
 
811
 *
 
812
 * Next element in the sequence space is FIN. Queue end-of-data marker
 
813
 * on the socket.
 
814
 *
 
815
 * @param socket        Socket
 
816
 */
 
817
static void tcp_queue_received_end_of_data(socket_core_t *socket)
 
818
{
 
819
        assert(socket != NULL);
 
820
 
 
821
        /* Notify the destination socket */
 
822
        async_msg_5(socket->phone, NET_SOCKET_RECEIVED,
 
823
            (sysarg_t) socket->socket_id,
 
824
            0, 0, 0,
 
825
            (sysarg_t) 0 /* 0 fragments == no more data */);
 
826
}
 
827
 
 
828
int tcp_process_syn_sent(socket_core_t *socket, tcp_socket_data_t *
 
829
    socket_data, tcp_header_t *header, packet_t *packet)
 
830
{
 
831
        packet_t *next_packet;
 
832
        int rc;
700
833
 
701
834
        assert(socket);
702
835
        assert(socket_data);
704
837
        assert(header);
705
838
        assert(packet);
706
839
 
707
 
        if(header->synchronize){
708
 
                // process acknowledgement
709
 
                tcp_process_acknowledgement(socket, socket_data, header);
710
 
 
711
 
                socket_data->next_incoming = ntohl(header->sequence_number) + 1;
712
 
                // release additional packets
713
 
                next_packet = pq_detach(packet);
714
 
                if(next_packet){
715
 
                        pq_release_remote(tcp_globals.net_phone, packet_get_id(next_packet));
716
 
                }
717
 
                // trim if longer than the header
718
 
                if((packet_get_data_length(packet) > sizeof(*header))
719
 
                        && ERROR_OCCURRED(packet_trim(packet, 0, packet_get_data_length(packet) - sizeof(*header)))){
720
 
                        return tcp_release_and_return(packet, ERROR_CODE);
721
 
                }
722
 
                tcp_prepare_operation_header(socket, socket_data, header, 0, 0);
723
 
                fibril_mutex_lock(&socket_data->operation.mutex);
724
 
                socket_data->operation.result = tcp_queue_packet(socket, socket_data, packet, 1);
725
 
                if(socket_data->operation.result == EOK){
726
 
                        socket_data->state = TCP_SOCKET_ESTABLISHED;
727
 
                        packet = tcp_get_packets_to_send(socket, socket_data);
728
 
                        if(packet){
729
 
                                fibril_rwlock_write_unlock(socket_data->local_lock);
730
 
                                // send the packet
731
 
                                tcp_send_packets(socket_data->device_id, packet);
732
 
                                // signal the result
733
 
                                fibril_condvar_signal(&socket_data->operation.condvar);
734
 
                                fibril_mutex_unlock(&socket_data->operation.mutex);
735
 
                                return EOK;
736
 
                        }
737
 
                }
738
 
                fibril_mutex_unlock(&socket_data->operation.mutex);
739
 
        }
 
840
        if (!header->synchronize)
 
841
                return tcp_release_and_return(packet, EINVAL);
 
842
        
 
843
        /* Process acknowledgement */
 
844
        tcp_process_acknowledgement(socket, socket_data, header);
 
845
 
 
846
        socket_data->next_incoming = ntohl(header->sequence_number) + 1;
 
847
 
 
848
        /* Release additional packets */
 
849
        next_packet = pq_detach(packet);
 
850
        if (next_packet) {
 
851
                pq_release_remote(tcp_globals.net_phone,
 
852
                    packet_get_id(next_packet));
 
853
        }
 
854
 
 
855
        /* Trim if longer than the header */
 
856
        if (packet_get_data_length(packet) > sizeof(*header)) {
 
857
                rc = packet_trim(packet, 0,
 
858
                    packet_get_data_length(packet) - sizeof(*header));
 
859
                if (rc != EOK)
 
860
                        return tcp_release_and_return(packet, rc);
 
861
        }
 
862
 
 
863
        tcp_prepare_operation_header(socket, socket_data, header, 0, 0);
 
864
        fibril_mutex_lock(&socket_data->operation.mutex);
 
865
        socket_data->operation.result = tcp_queue_packet(socket, socket_data,
 
866
            packet, 1);
 
867
 
 
868
        if (socket_data->operation.result == EOK) {
 
869
                socket_data->state = TCP_SOCKET_ESTABLISHED;
 
870
                packet = tcp_get_packets_to_send(socket, socket_data);
 
871
                if (packet) {
 
872
                        fibril_rwlock_write_unlock( socket_data->local_lock);
 
873
                        /* Send the packet */
 
874
                        tcp_send_packets(socket_data->device_id, packet);
 
875
                        /* Signal the result */
 
876
                        fibril_condvar_signal( &socket_data->operation.condvar);
 
877
                        fibril_mutex_unlock( &socket_data->operation.mutex);
 
878
                        return EOK;
 
879
                }
 
880
        }
 
881
 
 
882
        fibril_mutex_unlock(&socket_data->operation.mutex);
740
883
        return tcp_release_and_return(packet, EINVAL);
741
884
}
742
885
 
743
 
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){
744
 
        ERROR_DECLARE;
745
 
 
746
 
        packet_t next_packet;
747
 
        socket_core_ref socket;
748
 
        tcp_socket_data_ref socket_data;
 
886
int tcp_process_listen(socket_core_t *listening_socket,
 
887
    tcp_socket_data_t *listening_socket_data, tcp_header_t *header,
 
888
    packet_t *packet, struct sockaddr *src, struct sockaddr *dest,
 
889
    size_t addrlen)
 
890
{
 
891
        packet_t *next_packet;
 
892
        socket_core_t *socket;
 
893
        tcp_socket_data_t *socket_data;
749
894
        int socket_id;
750
895
        int listening_socket_id = listening_socket->socket_id;
751
896
        int listening_port = listening_socket->port;
 
897
        int rc;
752
898
 
753
899
        assert(listening_socket);
754
900
        assert(listening_socket_data);
756
902
        assert(header);
757
903
        assert(packet);
758
904
 
759
 
//      printf("syn %d\n", header->synchronize);
760
 
        if(header->synchronize){
761
 
                socket_data = (tcp_socket_data_ref) malloc(sizeof(*socket_data));
762
 
                if(! socket_data){
763
 
                        return tcp_release_and_return(packet, ENOMEM);
764
 
                }else{
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;
769
 
 
770
 
                        socket_data->next_incoming = ntohl(header->sequence_number);
771
 
                        socket_data->treshold = socket_data->next_incoming + ntohs(header->window);
772
 
 
773
 
                        socket_data->addrlen = addrlen;
774
 
                        socket_data->addr = malloc(socket_data->addrlen);
775
 
                        if(! socket_data->addr){
776
 
                                free(socket_data);
777
 
                                return tcp_release_and_return(packet, ENOMEM);
778
 
                        }
779
 
                        memcpy(socket_data->addr, src, socket_data->addrlen);
780
 
 
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);
784
 
                                free(socket_data);
785
 
                                pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
786
 
                                return ERROR_CODE;
787
 
                        }
788
 
 
789
 
//                      printf("addr %p\n", socket_data->addr, socket_data->addrlen);
790
 
                        // create a socket
791
 
                        socket_id = -1;
792
 
                        if(ERROR_OCCURRED(socket_create(socket_data->local_sockets, listening_socket->phone, socket_data, &socket_id))){
793
 
                                free(socket_data->addr);
794
 
                                free(socket_data);
795
 
                                return tcp_release_and_return(packet, ERROR_CODE);
796
 
                        }
797
 
 
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;
803
 
 
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*/);
814
 
                        }
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);
818
 
 
819
 
//                      printf("list ll\n");
820
 
                        fibril_rwlock_write_lock(listening_socket_data->local_lock);
821
 
//                      printf("list locked\n");
822
 
 
823
 
                        socket = socket_cores_find(listening_socket_data->local_sockets, socket_id);
824
 
                        if(! socket){
825
 
                                // where is the socket?!?
826
 
                                fibril_rwlock_write_unlock(&tcp_globals.lock);
827
 
                                return ENOTSOCK;
828
 
                        }
829
 
                        socket_data = (tcp_socket_data_ref) socket->specific_data;
830
 
                        assert(socket_data);
831
 
 
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]);
834
 
 
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);
844
 
                        }
845
 
 
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);
850
 
                        if(next_packet){
851
 
                                pq_release_remote(tcp_globals.net_phone, packet_get_id(next_packet));
852
 
                        }
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);
858
 
                        }
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);
862
 
                                return ERROR_CODE;
863
 
                        }
864
 
                        packet = tcp_get_packets_to_send(socket, socket_data);
865
 
//                      printf("send %d\n", packet_get_id(packet));
866
 
                        if(! packet){
867
 
                                socket_destroy(tcp_globals.net_phone, socket->socket_id, socket_data->local_sockets, &tcp_globals.sockets, tcp_free_socket_data);
868
 
                                return EINVAL;
869
 
                        }else{
870
 
                                socket_data->state = TCP_SOCKET_SYN_RECEIVED;
871
 
//                              printf("unlock\n");
872
 
                                fibril_rwlock_write_unlock(socket_data->local_lock);
873
 
                                // send the packet
874
 
                                tcp_send_packets(socket_data->device_id, packet);
875
 
                                return EOK;
876
 
                        }
 
905
        if (!header->synchronize)
 
906
                return tcp_release_and_return(packet, EINVAL);
 
907
 
 
908
        socket_data = (tcp_socket_data_t *) malloc(sizeof(*socket_data));
 
909
        if (!socket_data)
 
910
                return tcp_release_and_return(packet, ENOMEM);
 
911
 
 
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) {
 
922
                free(socket_data);
 
923
                return tcp_release_and_return(packet, ENOMEM);
 
924
        }
 
925
 
 
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);
 
930
        if (rc != EOK) {
 
931
                free(socket_data->addr);
 
932
                free(socket_data);
 
933
                return tcp_release_and_return(packet, rc);
 
934
        }
 
935
 
 
936
        /* Create a socket */
 
937
        socket_id = -1;
 
938
        rc = socket_create(socket_data->local_sockets, listening_socket->phone,
 
939
            socket_data, &socket_id);
 
940
        if (rc != EOK) {
 
941
                free(socket_data->addr);
 
942
                free(socket_data);
 
943
                return tcp_release_and_return(packet, rc);
 
944
        }
 
945
 
 
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;
 
951
 
 
952
        fibril_rwlock_write_unlock(socket_data->local_lock);
 
953
        fibril_rwlock_write_lock(&tcp_globals.lock);
 
954
 
 
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*/);
 
963
        }
 
964
        listening_socket_data =
 
965
            (tcp_socket_data_t *) listening_socket->specific_data;
 
966
        assert(listening_socket_data);
 
967
 
 
968
        fibril_rwlock_write_lock(listening_socket_data->local_lock);
 
969
 
 
970
        socket = socket_cores_find(listening_socket_data->local_sockets,
 
971
            socket_id);
 
972
        if (!socket) {
 
973
                /* Where is the socket?!? */
 
974
                fibril_rwlock_write_unlock(&tcp_globals.lock);
 
975
                return ENOTSOCK;
 
976
        }
 
977
        socket_data = (tcp_socket_data_t *) socket->specific_data;
 
978
        assert(socket_data);
 
979
 
 
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));
 
984
 
 
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);
 
990
        if (rc != EOK) {
 
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);
 
995
        }
 
996
 
 
997
        socket_data->state = TCP_SOCKET_LISTEN;
 
998
        socket_data->next_incoming = ntohl(header->sequence_number) + 1;
 
999
 
 
1000
        /* Release additional packets */
 
1001
        next_packet = pq_detach(packet);
 
1002
        if (next_packet) {
 
1003
                pq_release_remote(tcp_globals.net_phone,
 
1004
                    packet_get_id(next_packet));
 
1005
        }
 
1006
 
 
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));
 
1011
                if (rc != EOK) {
 
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);
877
1016
                }
878
1017
        }
879
 
        return tcp_release_and_return(packet, EINVAL);
 
1018
 
 
1019
        tcp_prepare_operation_header(socket, socket_data, header, 1, 0);
 
1020
 
 
1021
        rc = tcp_queue_packet(socket, socket_data, packet, 1);
 
1022
        if (rc != EOK) {
 
1023
                socket_destroy(tcp_globals.net_phone, socket->socket_id,
 
1024
                    socket_data->local_sockets, &tcp_globals.sockets,
 
1025
                    tcp_free_socket_data);
 
1026
                return rc;
 
1027
        }
 
1028
 
 
1029
        packet = tcp_get_packets_to_send(socket, socket_data);
 
1030
        if (!packet) {
 
1031
                socket_destroy(tcp_globals.net_phone, socket->socket_id,
 
1032
                    socket_data->local_sockets, &tcp_globals.sockets,
 
1033
                    tcp_free_socket_data);
 
1034
                return EINVAL;
 
1035
        }
 
1036
 
 
1037
        socket_data->state = TCP_SOCKET_SYN_RECEIVED;
 
1038
        fibril_rwlock_write_unlock(socket_data->local_lock);
 
1039
 
 
1040
        /* Send the packet */
 
1041
        tcp_send_packets(socket_data->device_id, packet);
 
1042
 
 
1043
        return EOK;
880
1044
}
881
1045
 
882
 
int tcp_process_syn_received(socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet){
883
 
        ERROR_DECLARE;
884
 
 
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)
 
1048
{
 
1049
        socket_core_t *listening_socket;
 
1050
        tcp_socket_data_t *listening_socket_data;
 
1051
        int rc;
887
1052
 
888
1053
        assert(socket);
889
1054
        assert(socket_data);
891
1056
        assert(header);
892
1057
        assert(packet);
893
1058
 
894
 
        printf("syn_rec\n");
895
 
        if(header->acknowledge){
896
 
                // process acknowledgement
897
 
                tcp_process_acknowledgement(socket, socket_data, header);
898
 
 
899
 
                socket_data->next_incoming = ntohl(header->sequence_number);// + 1;
900
 
                pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
901
 
                socket_data->state = TCP_SOCKET_ESTABLISHED;
902
 
                listening_socket = socket_cores_find(socket_data->local_sockets, socket_data->listening_socket_id);
903
 
                if(listening_socket){
904
 
                        listening_socket_data = (tcp_socket_data_ref) listening_socket->specific_data;
905
 
                        assert(listening_socket_data);
906
 
 
907
 
                        // queue the received packet
908
 
                        if(! ERROR_OCCURRED(dyn_fifo_push(&listening_socket->accepted, (-1 * socket->socket_id), listening_socket_data->backlog))){
909
 
                                // notify the destination socket
910
 
                                async_msg_5(socket->phone, NET_SOCKET_ACCEPTED, (ipcarg_t) listening_socket->socket_id, socket_data->data_fragment_size, TCP_HEADER_SIZE, 0, (ipcarg_t) socket->socket_id);
911
 
                                fibril_rwlock_write_unlock(socket_data->local_lock);
912
 
                                return EOK;
913
 
                        }
914
 
                }
915
 
                // send FIN
916
 
                socket_data->state = TCP_SOCKET_FIN_WAIT_1;
917
 
 
918
 
                // create the notification packet
919
 
                ERROR_PROPAGATE(tcp_create_notification_packet(&packet, socket, socket_data, 0, 1));
920
 
 
921
 
                // send the packet
922
 
                ERROR_PROPAGATE(tcp_queue_packet(socket, socket_data, packet, 1));
923
 
 
924
 
                // flush packets
925
 
                packet = tcp_get_packets_to_send(socket, socket_data);
926
 
                fibril_rwlock_write_unlock(socket_data->local_lock);
927
 
                if(packet){
928
 
                        // send the packet
929
 
                        tcp_send_packets(socket_data->device_id, packet);
930
 
                }
931
 
                return EOK;
932
 
        }else{
 
1059
        if (!header->acknowledge)
933
1060
                return tcp_release_and_return(packet, EINVAL);
934
 
        }
935
 
        return EINVAL;
 
1061
 
 
1062
        /* Process acknowledgement */
 
1063
        tcp_process_acknowledgement(socket, socket_data, header);
 
1064
 
 
1065
        socket_data->next_incoming = ntohl(header->sequence_number); /* + 1; */
 
1066
        pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
 
1067
        socket_data->state = TCP_SOCKET_ESTABLISHED;
 
1068
        listening_socket = socket_cores_find(socket_data->local_sockets,
 
1069
            socket_data->listening_socket_id);
 
1070
        if (listening_socket) {
 
1071
                listening_socket_data =
 
1072
                    (tcp_socket_data_t *) listening_socket->specific_data;
 
1073
                assert(listening_socket_data);
 
1074
 
 
1075
                /* Queue the received packet */
 
1076
                rc = dyn_fifo_push(&listening_socket->accepted,
 
1077
                    (-1 * socket->socket_id), listening_socket_data->backlog);
 
1078
                if (rc == EOK) {
 
1079
                        /* Notify the destination socket */
 
1080
                        async_msg_5(socket->phone, NET_SOCKET_ACCEPTED,
 
1081
                            (sysarg_t) listening_socket->socket_id,
 
1082
                            socket_data->data_fragment_size, TCP_HEADER_SIZE,
 
1083
                            0, (sysarg_t) socket->socket_id);
 
1084
 
 
1085
                        fibril_rwlock_write_unlock(socket_data->local_lock);
 
1086
                        return EOK;
 
1087
                }
 
1088
        }
 
1089
        /* Send FIN */
 
1090
        socket_data->state = TCP_SOCKET_FIN_WAIT_1;
 
1091
 
 
1092
        /* Create the notification packet */
 
1093
        rc = tcp_create_notification_packet(&packet, socket, socket_data, 0, 1);
 
1094
        if (rc != EOK)
 
1095
                return rc;
 
1096
 
 
1097
        /* Send the packet */
 
1098
        rc = tcp_queue_packet(socket, socket_data, packet, 1);
 
1099
        if (rc != EOK)
 
1100
                return rc;
 
1101
 
 
1102
        /* Flush packets */
 
1103
        packet = tcp_get_packets_to_send(socket, socket_data);
 
1104
        fibril_rwlock_write_unlock(socket_data->local_lock);
 
1105
        if (packet) {
 
1106
                /* Send the packet */
 
1107
                tcp_send_packets(socket_data->device_id, packet);
 
1108
        }
 
1109
 
 
1110
        return EOK;
936
1111
}
937
1112
 
938
 
void tcp_process_acknowledgement(socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header){
 
1113
void tcp_process_acknowledgement(socket_core_t *socket,
 
1114
    tcp_socket_data_t *socket_data, tcp_header_t *header)
 
1115
{
939
1116
        size_t number;
940
1117
        size_t length;
941
 
        packet_t packet;
942
 
        packet_t next;
943
 
        packet_t acknowledged = NULL;
 
1118
        packet_t *packet;
 
1119
        packet_t *next;
 
1120
        packet_t *acknowledged = NULL;
944
1121
        uint32_t old;
945
1122
 
946
1123
        assert(socket);
948
1125
        assert(socket->specific_data == socket_data);
949
1126
        assert(header);
950
1127
 
951
 
        if(header->acknowledge){
952
 
                number = ntohl(header->acknowledgement_number);
953
 
                // if more data acknowledged
954
 
                if(number != socket_data->expected){
955
 
                        old = socket_data->expected;
956
 
                        if(IS_IN_INTERVAL_OVERFLOW(old, socket_data->fin_outgoing, number)){
957
 
                                switch(socket_data->state){
958
 
                                        case TCP_SOCKET_FIN_WAIT_1:
959
 
                                                socket_data->state = TCP_SOCKET_FIN_WAIT_2;
960
 
                                                break;
961
 
                                        case TCP_SOCKET_LAST_ACK:
962
 
                                        case TCP_SOCKET_CLOSING:
963
 
                                                // fin acknowledged - release the socket in another fibril
964
 
                                                tcp_prepare_timeout(tcp_release_after_timeout, socket, socket_data, 0, TCP_SOCKET_TIME_WAIT, NET_DEFAULT_TCP_TIME_WAIT_TIMEOUT, true);
965
 
                                                break;
966
 
                                        default:
967
 
                                                break;
968
 
                                }
969
 
                        }
970
 
                        // update the treshold if higher than set
971
 
                        if(number + ntohs(header->window) > socket_data->expected + socket_data->treshold){
972
 
                                socket_data->treshold = number + ntohs(header->window) - socket_data->expected;
973
 
                        }
974
 
                        // set new expected sequence number
975
 
                        socket_data->expected = number;
 
1128
        if (!header->acknowledge)
 
1129
                return;
 
1130
 
 
1131
        number = ntohl(header->acknowledgement_number);
 
1132
 
 
1133
        /* If more data acknowledged */
 
1134
        if (number != socket_data->expected) {
 
1135
                old = socket_data->expected;
 
1136
                if (IS_IN_INTERVAL_OVERFLOW(old, socket_data->fin_outgoing,
 
1137
                    number)) {
 
1138
                        switch (socket_data->state) {
 
1139
                        case TCP_SOCKET_FIN_WAIT_1:
 
1140
                                socket_data->state = TCP_SOCKET_FIN_WAIT_2;
 
1141
                                break;
 
1142
                        case TCP_SOCKET_LAST_ACK:
 
1143
                        case TCP_SOCKET_CLOSING:
 
1144
                                /*
 
1145
                                 * FIN acknowledged - release the socket in
 
1146
                                 * another fibril.
 
1147
                                 */
 
1148
                                tcp_prepare_timeout(tcp_release_after_timeout,
 
1149
                                    socket, socket_data, 0,
 
1150
                                    TCP_SOCKET_TIME_WAIT,
 
1151
                                    NET_DEFAULT_TCP_TIME_WAIT_TIMEOUT, true);
 
1152
                                break;
 
1153
                        default:
 
1154
                                break;
 
1155
                        }
 
1156
                }
 
1157
 
 
1158
                /* Update the treshold if higher than set */
 
1159
                if (number + ntohs(header->window) >
 
1160
                    socket_data->expected + socket_data->treshold) {
 
1161
                        socket_data->treshold = number + ntohs(header->window) -
 
1162
                            socket_data->expected;
 
1163
                }
 
1164
 
 
1165
                /* Set new expected sequence number */
 
1166
                socket_data->expected = number;
 
1167
                socket_data->expected_count = 1;
 
1168
                packet = socket_data->outgoing;
 
1169
                while (pq_get_order(packet, &number, &length) == EOK) {
 
1170
                        if (IS_IN_INTERVAL_OVERFLOW((uint32_t) old,
 
1171
                            (uint32_t) (number + length),
 
1172
                            (uint32_t) socket_data->expected)) {
 
1173
                                next = pq_detach(packet);
 
1174
                                if (packet == socket_data->outgoing)
 
1175
                                        socket_data->outgoing = next;
 
1176
 
 
1177
                                /* Add to acknowledged or release */
 
1178
                                if (pq_add(&acknowledged, packet, 0, 0) != EOK)
 
1179
                                        pq_release_remote(tcp_globals.net_phone,
 
1180
                                            packet_get_id(packet));
 
1181
                                packet = next;
 
1182
                        } else if (old < socket_data->expected)
 
1183
                                break;
 
1184
                }
 
1185
 
 
1186
                /* Release acknowledged */
 
1187
                if (acknowledged) {
 
1188
                        pq_release_remote(tcp_globals.net_phone,
 
1189
                            packet_get_id(acknowledged));
 
1190
                }
 
1191
                return;
 
1192
                /* If the same as the previous time */
 
1193
        }
 
1194
 
 
1195
        if (number == socket_data->expected) {
 
1196
                /* Increase the counter */
 
1197
                socket_data->expected_count++;
 
1198
                if (socket_data->expected_count == TCP_FAST_RETRANSMIT_COUNT) {
976
1199
                        socket_data->expected_count = 1;
977
 
                        packet = socket_data->outgoing;
978
 
                        while(pq_get_order(packet, &number, &length) == EOK){
979
 
                                if(IS_IN_INTERVAL_OVERFLOW((uint32_t) old, (uint32_t)(number + length), (uint32_t) socket_data->expected)){
980
 
                                        next = pq_detach(packet);
981
 
                                        if(packet == socket_data->outgoing){
982
 
                                                socket_data->outgoing = next;
983
 
                                        }
984
 
                                        // add to acknowledged or release
985
 
                                        if(pq_add(&acknowledged, packet, 0, 0) != EOK){
986
 
                                                pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
987
 
                                        }
988
 
                                        packet = next;
989
 
                                }else if(old < socket_data->expected){
990
 
                                        break;
991
 
                                }
992
 
                        }
993
 
                        // release acknowledged
994
 
                        if(acknowledged){
995
 
                                pq_release_remote(tcp_globals.net_phone, packet_get_id(acknowledged));
996
 
                        }
997
 
                        return;
998
 
                // if the same as the previous time
999
 
                }else if(number == socket_data->expected){
1000
 
                        // increase the counter
1001
 
                        ++ socket_data->expected_count;
1002
 
                        if(socket_data->expected_count == TCP_FAST_RETRANSMIT_COUNT){
1003
 
                                socket_data->expected_count = 1;
1004
 
                                // TODO retransmit lock
1005
 
                                //tcp_retransmit_packet(socket, socket_data, number);
1006
 
                        }
 
1200
                        /* TODO retransmit lock */
 
1201
                        //tcp_retransmit_packet(socket, socket_data, number);
1007
1202
                }
1008
1203
        }
1009
1204
}
1010
1205
 
1011
 
int tcp_message_standalone(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
1012
 
        ERROR_DECLARE;
1013
 
 
1014
 
        packet_t packet;
1015
 
 
 
1206
/** Per-connection initialization
 
1207
 *
 
1208
 */
 
1209
void tl_connection(void)
 
1210
{
 
1211
}
 
1212
 
 
1213
/** Processes the TCP message.
 
1214
 *
 
1215
 * @param[in] callid    The message identifier.
 
1216
 * @param[in] call      The message parameters.
 
1217
 * @param[out] answer   The message answer parameters.
 
1218
 * @param[out] answer_count The last parameter for the actual answer in the
 
1219
 *                      answer parameter.
 
1220
 * @return              EOK on success.
 
1221
 * @return              ENOTSUP if the message is not known.
 
1222
 *
 
1223
 * @see tcp_interface.h
 
1224
 * @see IS_NET_TCP_MESSAGE()
 
1225
 */
 
1226
int tl_message(ipc_callid_t callid, ipc_call_t *call,
 
1227
    ipc_call_t *answer, size_t *answer_count)
 
1228
{
1016
1229
        assert(call);
1017
1230
        assert(answer);
1018
1231
        assert(answer_count);
1019
1232
 
1020
1233
        *answer_count = 0;
1021
 
        switch(IPC_GET_METHOD(*call)){
1022
 
                case NET_TL_RECEIVED:
1023
 
                        //fibril_rwlock_read_lock(&tcp_globals.lock);
1024
 
                        if(! ERROR_OCCURRED(packet_translate_remote(tcp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){
1025
 
                                ERROR_CODE = tcp_received_msg(IPC_GET_DEVICE(call), packet, SERVICE_TCP, IPC_GET_ERROR(call));
1026
 
                        }
1027
 
                        //fibril_rwlock_read_unlock(&tcp_globals.lock);
1028
 
                        return ERROR_CODE;
1029
 
                case IPC_M_CONNECT_TO_ME:
1030
 
                        return tcp_process_client_messages(callid, * call);
 
1234
        switch (IPC_GET_IMETHOD(*call)) {
 
1235
        case IPC_M_CONNECT_TO_ME:
 
1236
                return tcp_process_client_messages(callid, *call);
1031
1237
        }
 
1238
 
1032
1239
        return ENOTSUP;
1033
1240
}
1034
1241
 
1035
 
void tcp_refresh_socket_data(tcp_socket_data_ref socket_data){
 
1242
void tcp_refresh_socket_data(tcp_socket_data_t *socket_data)
 
1243
{
1036
1244
        assert(socket_data);
1037
1245
 
1038
1246
        bzero(socket_data, sizeof(*socket_data));
1047
1255
        socket_data->expected = socket_data->next_outgoing;
1048
1256
}
1049
1257
 
1050
 
void tcp_initialize_socket_data(tcp_socket_data_ref socket_data){
 
1258
void tcp_initialize_socket_data(tcp_socket_data_t *socket_data)
 
1259
{
1051
1260
        assert(socket_data);
1052
1261
 
1053
1262
        tcp_refresh_socket_data(socket_data);
1056
1265
        socket_data->data_fragment_size = MAX_TCP_FRAGMENT_SIZE;
1057
1266
}
1058
1267
 
1059
 
int tcp_process_client_messages(ipc_callid_t callid, ipc_call_t call){
 
1268
int tcp_process_client_messages(ipc_callid_t callid, ipc_call_t call)
 
1269
{
1060
1270
        int res;
1061
1271
        bool keep_on_going = true;
1062
1272
        socket_cores_t local_sockets;
1063
 
        int app_phone = IPC_GET_PHONE(&call);
1064
 
        struct sockaddr * addr;
 
1273
        int app_phone = IPC_GET_PHONE(call);
 
1274
        struct sockaddr *addr;
1065
1275
        int socket_id;
1066
1276
        size_t addrlen;
1067
1277
        size_t size;
1068
1278
        fibril_rwlock_t lock;
1069
1279
        ipc_call_t answer;
1070
 
        int answer_count;
1071
 
        tcp_socket_data_ref socket_data;
1072
 
        socket_core_ref socket;
1073
 
        packet_dimension_ref packet_dimension;
 
1280
        size_t answer_count;
 
1281
        tcp_socket_data_t *socket_data;
 
1282
        socket_core_t *socket;
 
1283
        packet_dimension_t *packet_dimension;
1074
1284
 
1075
1285
        /*
1076
1286
         * Accept the connection
1082
1292
        socket_cores_initialize(&local_sockets);
1083
1293
        fibril_rwlock_initialize(&lock);
1084
1294
 
1085
 
        while(keep_on_going){
 
1295
        while (keep_on_going) {
1086
1296
 
1087
 
                // answer the call
 
1297
                /* Answer the call */
1088
1298
                answer_call(callid, res, &answer, answer_count);
1089
 
 
1090
 
                // refresh data
 
1299
                /* Refresh data */
1091
1300
                refresh_answer(&answer, &answer_count);
1092
 
 
1093
 
                // get the next call
 
1301
                /* Get the next call */
1094
1302
                callid = async_get_call(&call);
1095
1303
 
1096
 
                // process the call
1097
 
                switch(IPC_GET_METHOD(call)){
1098
 
                        case IPC_M_PHONE_HUNGUP:
1099
 
                                keep_on_going = false;
1100
 
                                res = EHANGUP;
1101
 
                                break;
1102
 
                        case NET_SOCKET:
1103
 
                                socket_data = (tcp_socket_data_ref) malloc(sizeof(*socket_data));
1104
 
                                if(! socket_data){
1105
 
                                        res = ENOMEM;
1106
 
                                }else{
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);
1115
 
                                        if(res == EOK){
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));
1118
 
                                                }
1119
 
//                                              SOCKET_SET_DATA_FRAGMENT_SIZE(answer, MAX_TCP_FRAGMENT_SIZE);
1120
 
                                                SOCKET_SET_HEADER_SIZE(answer, TCP_HEADER_SIZE);
1121
 
                                                answer_count = 3;
1122
 
                                        }else{
1123
 
                                                free(socket_data);
1124
 
                                        }
1125
 
                                }
1126
 
                                break;
1127
 
                        case NET_SOCKET_BIND:
1128
 
                                res = data_receive((void **) &addr, &addrlen);
1129
 
                                if(res == EOK){
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);
1133
 
                                        if(res == EOK){
1134
 
                                                socket = socket_cores_find(&local_sockets, SOCKET_GET_SOCKET_ID(call));
1135
 
                                                if(socket){
1136
 
                                                        socket_data = (tcp_socket_data_ref) socket->specific_data;
1137
 
                                                        assert(socket_data);
1138
 
                                                        socket_data->state = TCP_SOCKET_LISTEN;
1139
 
                                                }
1140
 
                                        }
1141
 
                                        fibril_rwlock_write_unlock(&lock);
1142
 
                                        fibril_rwlock_write_unlock(&tcp_globals.lock);
1143
 
                                        free(addr);
1144
 
                                }
1145
 
                                break;
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);
1154
 
                                break;
1155
 
                        case NET_SOCKET_CONNECT:
1156
 
                                res = data_receive((void **) &addr, &addrlen);
1157
 
                                if(res == EOK){
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);
1162
 
                                        if(res != EOK){
1163
 
                                                fibril_rwlock_write_unlock(&lock);
1164
 
                                                fibril_rwlock_write_unlock(&tcp_globals.lock);
1165
 
                                                free(addr);
1166
 
                                        }
1167
 
                                }
1168
 
                                break;
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);
1176
 
                                if(res > 0){
1177
 
                                        SOCKET_SET_SOCKET_ID(answer, res);
1178
 
                                        SOCKET_SET_ADDRESS_LENGTH(answer, addrlen);
1179
 
                                        answer_count = 3;
1180
 
                                }
1181
 
                                break;
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);
1187
 
                                if(res != EOK){
1188
 
                                        fibril_rwlock_write_unlock(&lock);
1189
 
                                        fibril_rwlock_read_unlock(&tcp_globals.lock);
1190
 
                                }else{
1191
 
                                        answer_count = 2;
1192
 
                                }
1193
 
                                break;
1194
 
                        case NET_SOCKET_SENDTO:
1195
 
                                res = data_receive((void **) &addr, &addrlen);
1196
 
                                if(res == EOK){
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);
1201
 
                                        if(res != EOK){
1202
 
                                                fibril_rwlock_write_unlock(&lock);
1203
 
                                                fibril_rwlock_read_unlock(&tcp_globals.lock);
1204
 
                                        }else{
1205
 
                                                answer_count = 2;
1206
 
                                        }
1207
 
                                        free(addr);
1208
 
                                }
1209
 
                                break;
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);
1216
 
                                if(res > 0){
1217
 
                                        SOCKET_SET_READ_DATA_LENGTH(answer, res);
1218
 
                                        answer_count = 1;
1219
 
                                        res = EOK;
1220
 
                                }
1221
 
                                break;
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);
1228
 
                                if(res > 0){
1229
 
                                        SOCKET_SET_READ_DATA_LENGTH(answer, res);
1230
 
                                        SOCKET_SET_ADDRESS_LENGTH(answer, addrlen);
1231
 
                                        answer_count = 3;
1232
 
                                        res = EOK;
1233
 
                                }
1234
 
                                break;
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));
1239
 
                                if(res != EOK){
1240
 
                                        fibril_rwlock_write_unlock(&lock);
1241
 
                                        fibril_rwlock_write_unlock(&tcp_globals.lock);
1242
 
                                }
1243
 
                                break;
1244
 
                        case NET_SOCKET_GETSOCKOPT:
1245
 
                        case NET_SOCKET_SETSOCKOPT:
1246
 
                        default:
1247
 
                                res = ENOTSUP;
1248
 
                                break;
 
1304
                /* Process the call */
 
1305
                switch (IPC_GET_IMETHOD(call)) {
 
1306
                case IPC_M_PHONE_HUNGUP:
 
1307
                        keep_on_going = false;
 
1308
                        res = EHANGUP;
 
1309
                        break;
 
1310
 
 
1311
                case NET_SOCKET:
 
1312
                        socket_data =
 
1313
                            (tcp_socket_data_t *) malloc(sizeof(*socket_data));
 
1314
                        if (!socket_data) {
 
1315
                                res = ENOMEM;
 
1316
                                break;
 
1317
                        }
 
1318
                        
 
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);
 
1328
                        if (res != EOK) {
 
1329
                                free(socket_data);
 
1330
                                break;
 
1331
                        }
 
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));
 
1340
                        }
 
1341
//                      SOCKET_SET_DATA_FRAGMENT_SIZE(answer, MAX_TCP_FRAGMENT_SIZE);
 
1342
                        SOCKET_SET_HEADER_SIZE(answer, TCP_HEADER_SIZE);
 
1343
                        answer_count = 3;
 
1344
                        break;
 
1345
 
 
1346
                case NET_SOCKET_BIND:
 
1347
                        res = async_data_write_accept((void **) &addr, false,
 
1348
                            0, 0, 0, &addrlen);
 
1349
                        if (res != EOK)
 
1350
                                break;
 
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);
 
1357
                        if (res == EOK) {
 
1358
                                socket = socket_cores_find(&local_sockets,
 
1359
                                    SOCKET_GET_SOCKET_ID(call));
 
1360
                                if (socket) {
 
1361
                                        socket_data = (tcp_socket_data_t *)
 
1362
                                            socket->specific_data;
 
1363
                                        assert(socket_data);
 
1364
                                        socket_data->state = TCP_SOCKET_LISTEN;
 
1365
                                }
 
1366
                        }
 
1367
                        fibril_rwlock_write_unlock(&lock);
 
1368
                        fibril_rwlock_write_unlock(&tcp_globals.lock);
 
1369
                        free(addr);
 
1370
                        break;
 
1371
 
 
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);
 
1382
                        break;
 
1383
 
 
1384
                case NET_SOCKET_CONNECT:
 
1385
                        res = async_data_write_accept((void **) &addr, false,
 
1386
                            0, 0, 0, &addrlen);
 
1387
                        if (res != EOK)
 
1388
                                break;
 
1389
                        /*
 
1390
                         * The global lock may be released in the
 
1391
                         * tcp_connect_message() function.
 
1392
                         */
 
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);
 
1397
                        if (res != EOK) {
 
1398
                                fibril_rwlock_write_unlock(&lock);
 
1399
                                fibril_rwlock_write_unlock(&tcp_globals.lock);
 
1400
                                free(addr);
 
1401
                        }
 
1402
                        break;
 
1403
 
 
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);
 
1413
                        if (res > 0) {
 
1414
                                SOCKET_SET_SOCKET_ID(answer, res);
 
1415
                                SOCKET_SET_ADDRESS_LENGTH(answer, addrlen);
 
1416
                                answer_count = 3;
 
1417
                        }
 
1418
                        break;
 
1419
 
 
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);
 
1428
                        if (res != EOK) {
 
1429
                                fibril_rwlock_write_unlock(&lock);
 
1430
                                fibril_rwlock_read_unlock(&tcp_globals.lock);
 
1431
                        } else {
 
1432
                                answer_count = 2;
 
1433
                        }
 
1434
                        break;
 
1435
 
 
1436
                case NET_SOCKET_SENDTO:
 
1437
                        res = async_data_write_accept((void **) &addr, false,
 
1438
                            0, 0, 0, &addrlen);
 
1439
                        if (res != EOK)
 
1440
                                break;
 
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);
 
1448
                        if (res != EOK) {
 
1449
                                fibril_rwlock_write_unlock(&lock);
 
1450
                                fibril_rwlock_read_unlock(&tcp_globals.lock);
 
1451
                        } else {
 
1452
                                answer_count = 2;
 
1453
                        }
 
1454
                        free(addr);
 
1455
                        break;
 
1456
 
 
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),
 
1462
                            NULL);
 
1463
                        fibril_rwlock_write_unlock(&lock);
 
1464
                        fibril_rwlock_read_unlock(&tcp_globals.lock);
 
1465
                        if (res > 0) {
 
1466
                                SOCKET_SET_READ_DATA_LENGTH(answer, res);
 
1467
                                answer_count = 1;
 
1468
                                res = EOK;
 
1469
                        }
 
1470
                        break;
 
1471
 
 
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),
 
1477
                            &addrlen);
 
1478
                        fibril_rwlock_write_unlock(&lock);
 
1479
                        fibril_rwlock_read_unlock(&tcp_globals.lock);
 
1480
                        if (res > 0) {
 
1481
                                SOCKET_SET_READ_DATA_LENGTH(answer, res);
 
1482
                                SOCKET_SET_ADDRESS_LENGTH(answer, addrlen);
 
1483
                                answer_count = 3;
 
1484
                                res = EOK;
 
1485
                        }
 
1486
                        break;
 
1487
 
 
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));
 
1493
                        if (res != EOK) {
 
1494
                                fibril_rwlock_write_unlock(&lock);
 
1495
                                fibril_rwlock_write_unlock(&tcp_globals.lock);
 
1496
                        }
 
1497
                        break;
 
1498
 
 
1499
                case NET_SOCKET_GETSOCKOPT:
 
1500
                case NET_SOCKET_SETSOCKOPT:
 
1501
                default:
 
1502
                        res = ENOTSUP;
 
1503
                        break;
1249
1504
                }
1250
1505
        }
1251
1506
 
1252
 
        // release the application phone
1253
 
        ipc_hangup(app_phone);
 
1507
        /* Release the application phone */
 
1508
        async_hangup(app_phone);
1254
1509
 
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);
1258
1514
 
1259
1515
        return EOK;
1260
1516
}
1261
1517
 
1262
 
int tcp_timeout(void * data){
1263
 
        tcp_timeout_ref timeout = data;
 
1518
int tcp_timeout(void *data)
 
1519
{
 
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;
1267
1524
 
1268
1525
        assert(timeout);
1269
1526
 
1270
 
        // sleep the given timeout
 
1527
        /* Sleep the given timeout */
1271
1528
        async_usleep(timeout->timeout);
1272
 
        // lock the globals
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);
1275
 
        }else{
 
1532
        else 
1276
1533
                fibril_rwlock_write_lock(&tcp_globals.lock);
1277
 
        }
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);
1292
 
                                }else{
1293
 
                                        // retransmit
1294
 
//                                      tcp_retransmit_packet(socket, socket_data, timeout->sequence_number);
1295
 
                                        fibril_rwlock_write_unlock(socket_data->local_lock);
1296
 
                                }
1297
 
                        }else{
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;
1306
 
                                }else{
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);
1310
 
                                }
1311
 
                                fibril_mutex_unlock(&socket_data->operation.mutex);
1312
 
                        }
1313
 
                }
1314
 
        }
1315
 
        // unlock only if no socket
1316
 
        if(timeout->globals_read_only){
 
1534
 
 
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))
 
1539
                goto out;
 
1540
        
 
1541
        socket_data = (tcp_socket_data_t *) socket->specific_data;
 
1542
        assert(socket_data);
 
1543
        if (socket_data->local_sockets != timeout->local_sockets)
 
1544
                goto out;
 
1545
        
 
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);
 
1554
                } else {
 
1555
                        /* Retransmit */
 
1556
//                      tcp_retransmit_packet(socket,
 
1557
//                          socket_data, timeout->sequence_number);
 
1558
                        fibril_rwlock_write_unlock(socket_data->local_lock);
 
1559
                }
 
1560
        } else {
 
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;
 
1565
 
 
1566
                        /* Notify the main fibril */
 
1567
                        fibril_condvar_signal(&socket_data->operation.condvar);
 
1568
 
 
1569
                        /* Keep the global write lock */
 
1570
                        keep_write_lock = true;
 
1571
                } else {
 
1572
                        /*
 
1573
                         * Operation is ok, do nothing.
 
1574
                         * Unlocking from now on, so the unlocking
 
1575
                         * order does not matter.
 
1576
                         */
 
1577
                        fibril_rwlock_write_unlock(socket_data->local_lock);
 
1578
                }
 
1579
                fibril_mutex_unlock(&socket_data->operation.mutex);
 
1580
        }
 
1581
 
 
1582
out:
 
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);
1321
 
        }
1322
 
        // release the timeout structure
 
1589
        
 
1590
        /* Release the timeout structure */
1323
1591
        free(timeout);
1324
1592
        return EOK;
1325
1593
}
1326
1594
 
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)
 
1596
{
 
1597
        tcp_timeout_t *timeout = data;
 
1598
        socket_core_t *socket;
 
1599
        tcp_socket_data_t *socket_data;
 
1600
        fibril_rwlock_t *local_lock;
1332
1601
 
1333
1602
        assert(timeout);
1334
1603
 
1335
 
        // sleep the given timeout
 
1604
        /* Sleep the given timeout */
1336
1605
        async_usleep(timeout->timeout);
1337
 
        // lock the globals
 
1606
 
 
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;
 
1609
 
 
1610
        /* Find the pending operation socket */
 
1611
        socket = socket_port_find(&tcp_globals.sockets, timeout->port,
 
1612
            timeout->key, timeout->key_length);
 
1613
 
 
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);
1349
1624
                }
1350
1625
        }
1351
 
        // unlock the globals
 
1626
 
 
1627
        /* Unlock the globals */
1352
1628
        fibril_rwlock_write_unlock(&tcp_globals.lock);
1353
 
        // release the timeout structure
 
1629
 
 
1630
        /* Release the timeout structure */
1354
1631
        free(timeout);
 
1632
 
1355
1633
        return EOK;
1356
1634
}
1357
1635
 
1358
 
void tcp_retransmit_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, size_t sequence_number){
1359
 
        packet_t packet;
1360
 
        packet_t copy;
 
1636
void tcp_retransmit_packet(socket_core_t *socket, tcp_socket_data_t *
 
1637
    socket_data, size_t sequence_number)
 
1638
{
 
1639
        packet_t *packet;
 
1640
        packet_t *copy;
1361
1641
        size_t data_length;
1362
1642
 
1363
1643
        assert(socket);
1364
1644
        assert(socket_data);
1365
1645
        assert(socket->specific_data == socket_data);
1366
1646
 
1367
 
        // sent packet?
 
1647
        /* Sent packet? */
1368
1648
        packet = pq_find(socket_data->outgoing, sequence_number);
1369
1649
        printf("retransmit %d\n", packet_get_id(packet));
1370
 
        if(packet){
 
1650
        if (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));
1375
 
                if(copy){
 
1655
//              printf("r send %d\n", packet_get_id(packet));
 
1656
                if (copy) 
1376
1657
                        tcp_send_packets(socket_data->device_id, copy);
1377
 
                }
1378
 
        }else{
 
1658
        } else {
1379
1659
                fibril_rwlock_write_unlock(socket_data->local_lock);
1380
1660
        }
1381
1661
}
1382
1662
 
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,
 
1664
    int backlog)
 
1665
{
 
1666
        socket_core_t *socket;
 
1667
        tcp_socket_data_t *socket_data;
1386
1668
 
1387
1669
        assert(local_sockets);
1388
1670
 
1389
 
        if(backlog < 0){
 
1671
        if (backlog < 0) 
1390
1672
                return EINVAL;
1391
 
        }
1392
 
        // find the socket
 
1673
 
 
1674
        /* Find the socket */
1393
1675
        socket = socket_cores_find(local_sockets, socket_id);
1394
 
        if(! socket){
 
1676
        if (!socket) 
1395
1677
                return ENOTSOCK;
1396
 
        }
1397
 
        // get the socket specific data
1398
 
        socket_data = (tcp_socket_data_ref) socket->specific_data;
 
1678
        
 
1679
        /* Get the socket specific data */
 
1680
        socket_data = (tcp_socket_data_t *) socket->specific_data;
1399
1681
        assert(socket_data);
1400
 
        // set the backlog
 
1682
 
 
1683
        /* Set the backlog */
1401
1684
        socket_data->backlog = backlog;
 
1685
 
1402
1686
        return EOK;
1403
1687
}
1404
1688
 
1405
 
int tcp_connect_message(socket_cores_ref local_sockets, int socket_id, struct sockaddr * addr, socklen_t addrlen){
1406
 
        ERROR_DECLARE;
1407
 
 
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)
 
1691
{
 
1692
        socket_core_t *socket;
 
1693
        int rc;
1409
1694
 
1410
1695
        assert(local_sockets);
1411
1696
        assert(addr);
1412
1697
        assert(addrlen > 0);
1413
1698
 
1414
 
        // find the socket
 
1699
        /* Find the socket */
1415
1700
        socket = socket_cores_find(local_sockets, socket_id);
1416
 
        if(! socket){
 
1701
        if (!socket)
1417
1702
                return ENOTSOCK;
1418
 
        }
1419
 
        if(ERROR_OCCURRED(tcp_connect_core(socket, local_sockets, addr, addrlen))){
 
1703
        
 
1704
        rc = tcp_connect_core(socket, local_sockets, addr, addrlen);
 
1705
        if (rc != EOK) {
1420
1706
                tcp_free_socket_data(socket);
1421
 
                // unbind if bound
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;
1425
1712
                }
1426
1713
        }
1427
 
        return ERROR_CODE;
 
1714
        return rc;
1428
1715
}
1429
1716
 
1430
 
int tcp_connect_core(socket_core_ref socket, socket_cores_ref local_sockets, struct sockaddr * addr, socklen_t addrlen){
1431
 
        ERROR_DECLARE;
1432
 
 
1433
 
        tcp_socket_data_ref socket_data;
1434
 
        packet_t packet;
 
1717
int tcp_connect_core(socket_core_t *socket, socket_cores_t *local_sockets,
 
1718
    struct sockaddr *addr, socklen_t addrlen)
 
1719
{
 
1720
        tcp_socket_data_t *socket_data;
 
1721
        packet_t *packet;
 
1722
        int rc;
1435
1723
 
1436
1724
        assert(socket);
1437
1725
        assert(addr);
1438
1726
        assert(addrlen > 0);
1439
1727
 
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)))
1446
1735
                return EINVAL;
1447
 
        }
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
 
1736
 
 
1737
        /* Get the destination port */
 
1738
        rc = tl_get_address_port(addr, addrlen, &socket_data->dest_port);
 
1739
        if (rc != EOK)
 
1740
                return rc;
 
1741
        
 
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);
 
1747
                if (rc != EOK)
 
1748
                        return rc;
 
1749
                /* Set the next port as the search starting port number */
1454
1750
                tcp_globals.last_used_port = socket->port;
1455
1751
        }
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));
1457
 
 
1458
 
        // create the notification packet
1459
 
        ERROR_PROPAGATE(tcp_create_notification_packet(&packet, socket, socket_data, 1, 0));
1460
 
 
1461
 
        // unlock the globals and wait for an operation
 
1752
 
 
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);
 
1756
        if (rc != EOK)
 
1757
                return rc;
 
1758
 
 
1759
        /* Create the notification packet */
 
1760
        rc = tcp_create_notification_packet(&packet, socket, socket_data, 1, 0);
 
1761
        if (rc != EOK)
 
1762
                return rc;
 
1763
 
 
1764
        /* Unlock the globals and wait for an operation */
1462
1765
        fibril_rwlock_write_unlock(&tcp_globals.lock);
1463
1766
 
1464
1767
        socket_data->addr = addr;
1465
1768
        socket_data->addrlen = addrlen;
1466
 
        // send the packet
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))){
 
1769
 
 
1770
        /* Send the packet */
 
1771
 
 
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)) !=
 
1775
            EOK)) {
1469
1776
                socket_data->addr = NULL;
1470
1777
                socket_data->addrlen = 0;
1471
1778
                fibril_rwlock_write_lock(&tcp_globals.lock);
1472
 
        }else{
 
1779
        } else {
1473
1780
                packet = tcp_get_packets_to_send(socket, socket_data);
1474
 
                if(packet){
 
1781
                if (packet) {
1475
1782
                        fibril_mutex_lock(&socket_data->operation.mutex);
1476
1783
                        fibril_rwlock_write_unlock(socket_data->local_lock);
1477
 
                        // send the packet
 
1784
 
 
1785
                        socket_data->state = TCP_SOCKET_SYN_SENT;
 
1786
 
 
1787
                        /* Send the packet */
1478
1788
                        printf("connecting %d\n", packet_get_id(packet));
1479
1789
                        tcp_send_packets(socket_data->device_id, packet);
1480
 
                        // wait for a reply
1481
 
                        fibril_condvar_wait(&socket_data->operation.condvar, &socket_data->operation.mutex);
1482
 
                        ERROR_CODE = socket_data->operation.result;
1483
 
                        if(ERROR_CODE != EOK){
 
1790
 
 
1791
                        /* Wait for a reply */
 
1792
                        fibril_condvar_wait(&socket_data->operation.condvar,
 
1793
                            &socket_data->operation.mutex);
 
1794
                        rc = socket_data->operation.result;
 
1795
                        if (rc != EOK) {
1484
1796
                                socket_data->addr = NULL;
1485
1797
                                socket_data->addrlen = 0;
1486
1798
                        }
1487
 
                }else{
 
1799
                } else {
1488
1800
                        socket_data->addr = NULL;
1489
1801
                        socket_data->addrlen = 0;
1490
 
                        ERROR_CODE = EINTR;
 
1802
                        rc = EINTR;
1491
1803
                }
1492
1804
        }
1493
1805
 
1494
1806
        fibril_mutex_unlock(&socket_data->operation.mutex);
1495
 
 
1496
 
        // return the result
1497
 
        return ERROR_CODE;
 
1807
        return rc;
1498
1808
}
1499
1809
 
1500
 
int tcp_queue_prepare_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length){
1501
 
        ERROR_DECLARE;
1502
 
 
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)
 
1812
{
 
1813
        tcp_header_t *header;
 
1814
        int rc;
1504
1815
 
1505
1816
        assert(socket);
1506
1817
        assert(socket_data);
1507
1818
        assert(socket->specific_data == socket_data);
1508
1819
 
1509
 
        // get tcp header
1510
 
        header = (tcp_header_ref) packet_get_data(packet);
1511
 
        if(! header){
 
1820
        /* Get TCP header */
 
1821
        header = (tcp_header_t *) packet_get_data(packet);
 
1822
        if (!header)
1512
1823
                return NO_DATA;
1513
 
        }
 
1824
        
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))){
 
1828
 
 
1829
        rc = packet_set_addr(packet, NULL, (uint8_t *) socket_data->addr,
 
1830
            socket_data->addrlen);
 
1831
        if (rc != EOK)
1518
1832
                return tcp_release_and_return(packet, EINVAL);
1519
 
        }
1520
 
        // remember the outgoing FIN
1521
 
        if(header->finalize){
 
1833
 
 
1834
        /* Remember the outgoing FIN */
 
1835
        if (header->finalize) 
1522
1836
                socket_data->fin_outgoing = socket_data->next_outgoing;
1523
 
        }
 
1837
        
1524
1838
        return EOK;
1525
1839
}
1526
1840
 
1527
 
int tcp_queue_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length){
1528
 
        ERROR_DECLARE;
 
1841
int tcp_queue_packet(socket_core_t *socket, tcp_socket_data_t *socket_data,
 
1842
    packet_t *packet, size_t data_length)
 
1843
{
 
1844
        int rc;
1529
1845
 
1530
1846
        assert(socket);
1531
1847
        assert(socket_data);
1532
1848
        assert(socket->specific_data == socket_data);
1533
1849
 
1534
 
        ERROR_PROPAGATE(tcp_queue_prepare_packet(socket, socket_data, packet, data_length));
1535
 
 
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);
1538
 
        }
 
1850
        rc = tcp_queue_prepare_packet(socket, socket_data, packet, data_length);
 
1851
        if (rc != EOK)
 
1852
                return rc;
 
1853
 
 
1854
        rc = pq_add(&socket_data->outgoing, packet, socket_data->next_outgoing,
 
1855
            data_length);
 
1856
        if (rc != EOK)
 
1857
                return tcp_release_and_return(packet, rc);
 
1858
 
1539
1859
        socket_data->next_outgoing += data_length;
1540
1860
        return EOK;
1541
1861
}
1542
1862
 
1543
 
packet_t tcp_get_packets_to_send(socket_core_ref socket, tcp_socket_data_ref socket_data){
1544
 
        ERROR_DECLARE;
1545
 
 
1546
 
        packet_t packet;
1547
 
        packet_t copy;
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 *
 
1864
    socket_data)
 
1865
{
 
1866
        packet_t *packet;
 
1867
        packet_t *copy;
 
1868
        packet_t *sending = NULL;
 
1869
        packet_t *previous = NULL;
1550
1870
        size_t data_length;
 
1871
        int rc;
1551
1872
 
1552
1873
        assert(socket);
1553
1874
        assert(socket_data);
1554
1875
        assert(socket->specific_data == socket_data);
1555
1876
 
1556
1877
        packet = pq_find(socket_data->outgoing, socket_data->last_outgoing + 1);
1557
 
        while(packet){
 
1878
        while (packet) {
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);
1563
 
                        if(! copy){
 
1880
 
 
1881
                /*
 
1882
                 * Send only if fits into the window, respecting the possible
 
1883
                 * overflow.
 
1884
                 */
 
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)))
 
1889
                        break;
 
1890
 
 
1891
                copy = tcp_prepare_copy(socket, socket_data, packet,
 
1892
                    data_length, socket_data->last_outgoing + 1);
 
1893
                if (!copy) 
 
1894
                        return sending;
 
1895
                        
 
1896
                if (!sending) {
 
1897
                        sending = copy;
 
1898
                } else {
 
1899
                        rc = pq_insert_after(previous, copy);
 
1900
                        if (rc != EOK) {
 
1901
                                pq_release_remote(tcp_globals.net_phone,
 
1902
                                    packet_get_id(copy));
1564
1903
                                return sending;
1565
1904
                        }
1566
 
                        if(! sending){
1567
 
                                sending = copy;
1568
 
                        }else{
1569
 
                                if(ERROR_OCCURRED(pq_insert_after(previous, copy))){
1570
 
                                        pq_release_remote(tcp_globals.net_phone, packet_get_id(copy));
1571
 
                                        return sending;
1572
 
                                }
1573
 
                        }
1574
 
                        previous = 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;
1581
 
                        }
1582
 
                        socket_data->last_outgoing += data_length;
1583
 
                }else{
1584
 
                        break;
1585
 
                }
 
1905
                }
 
1906
 
 
1907
                previous = copy;
 
1908
                packet = pq_next(packet);
 
1909
 
 
1910
                /* Overflow occurred? */
 
1911
                if (!packet &&
 
1912
                    (socket_data->last_outgoing > socket_data->next_outgoing)) {
 
1913
                        printf("gpts overflow\n");
 
1914
                        /* Continue from the beginning */
 
1915
                        packet = socket_data->outgoing;
 
1916
                }
 
1917
                socket_data->last_outgoing += data_length;
1586
1918
        }
 
1919
 
1587
1920
        return sending;
1588
1921
}
1589
1922
 
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){
1591
 
        ERROR_DECLARE;
1592
 
 
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)
 
1925
{
 
1926
        tcp_header_t *header;
1594
1927
        uint32_t checksum;
 
1928
        int rc;
1595
1929
 
1596
1930
        assert(socket);
1597
1931
        assert(socket_data);
1598
1932
        assert(socket->specific_data == socket_data);
1599
1933
 
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));
 
1937
        if (rc != EOK) {
1602
1938
                pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
1603
1939
                return NULL;
1604
1940
        }
1605
1941
 
1606
 
        // get the header
1607
 
        header = (tcp_header_ref) packet_get_data(packet);
1608
 
        if(! header){
 
1942
        /* Get the header */
 
1943
        header = (tcp_header_t *) packet_get_data(packet);
 
1944
        if (!header) {
1609
1945
                pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
1610
1946
                return NULL;
1611
1947
        }
1612
1948
        assert(ntohl(header->sequence_number) == sequence_number);
1613
1949
 
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;
1618
1955
        }
1619
1956
        header->window = htons(socket_data->window);
1620
1957
 
1621
 
        // checksum
 
1958
        /* Checksum */
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));
1631
 
                return NULL;
1632
 
        }
 
1966
 
 
1967
        /* Prepare the packet */
 
1968
        rc = ip_client_prepare_packet(packet, IPPROTO_TCP, 0, 0, 0, 0);
 
1969
        if (rc != EOK) {
 
1970
                pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
 
1971
                return NULL;
 
1972
        }
 
1973
 
 
1974
        rc = tcp_prepare_timeout(tcp_timeout, socket, socket_data,
 
1975
            sequence_number, socket_data->state, socket_data->timeout, true);
 
1976
        if (rc != EOK) {
 
1977
                pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
 
1978
                return NULL;
 
1979
        }
 
1980
 
1633
1981
        return packet;
1634
1982
}
1635
1983
 
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){
1637
 
        packet_t copy;
 
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)
 
1986
{
 
1987
        packet_t *copy;
1638
1988
 
1639
1989
        assert(socket);
1640
1990
        assert(socket_data);
1641
1991
        assert(socket->specific_data == socket_data);
1642
1992
 
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);
1645
 
        if(! copy){
 
1995
        if (!copy)
1646
1996
                return NULL;
1647
 
        }
1648
1997
 
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,
 
1999
            sequence_number);
1650
2000
}
1651
2001
 
1652
 
void tcp_send_packets(device_id_t device_id, packet_t packet){
1653
 
        packet_t next;
 
2002
void tcp_send_packets(device_id_t device_id, packet_t *packet)
 
2003
{
 
2004
        packet_t *next;
1654
2005
 
1655
 
        while(packet){
 
2006
        while (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,
 
2009
                    SERVICE_TCP, 0);
1658
2010
                packet = next;
1659
2011
        }
1660
2012
}
1661
2013
 
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,
 
2016
    int finalize)
 
2017
{
1663
2018
        assert(socket);
1664
2019
        assert(socket_data);
1665
2020
        assert(socket->specific_data == socket_data);
1673
2028
        header->finalize = finalize;
1674
2029
}
1675
2030
 
1676
 
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){
1677
 
        tcp_timeout_ref operation_timeout;
 
2031
int tcp_prepare_timeout(int (*timeout_function)(void *tcp_timeout_t),
 
2032
    socket_core_t *socket, tcp_socket_data_t *socket_data,
 
2033
    size_t sequence_number, tcp_socket_state_t state, suseconds_t timeout,
 
2034
    int globals_read_only)
 
2035
{
 
2036
        tcp_timeout_t *operation_timeout;
1678
2037
        fid_t fibril;
1679
2038
 
1680
2039
        assert(socket);
1681
2040
        assert(socket_data);
1682
2041
        assert(socket->specific_data == socket_data);
1683
2042
 
1684
 
        // prepare the timeout with key bundle structure
1685
 
        operation_timeout = malloc(sizeof(*operation_timeout) + socket->key_length + 1);
1686
 
        if(! operation_timeout){
 
2043
        /* Prepare the timeout with key bundle structure */
 
2044
        operation_timeout = malloc(sizeof(*operation_timeout) +
 
2045
            socket->key_length + 1);
 
2046
        if (!operation_timeout)
1687
2047
                return ENOMEM;
1688
 
        }
 
2048
 
1689
2049
        bzero(operation_timeout, sizeof(*operation_timeout));
1690
2050
        operation_timeout->globals_read_only = globals_read_only;
1691
2051
        operation_timeout->port = socket->port;
1695
2055
        operation_timeout->sequence_number = sequence_number;
1696
2056
        operation_timeout->state = state;
1697
2057
 
1698
 
        // copy the key
1699
 
        operation_timeout->key = ((char *) operation_timeout) + sizeof(*operation_timeout);
 
2058
        /* Copy the key */
 
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';
1703
2064
 
1704
 
        // prepare the timeouting thread
 
2065
        /* Prepare the timeouting thread */
1705
2066
        fibril = fibril_create(timeout_function, operation_timeout);
1706
 
        if(! fibril){
 
2067
        if (!fibril) {
1707
2068
                free(operation_timeout);
1708
 
                return EPARTY;
 
2069
                return ENOMEM;
1709
2070
        }
1710
 
//      fibril_mutex_lock(&socket_data->operation.mutex);
1711
 
        // start the timeouting fibril
 
2071
 
 
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;
1714
2076
        return EOK;
1715
2077
}
1716
2078
 
1717
 
int tcp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, int flags, size_t * addrlen){
1718
 
        ERROR_DECLARE;
1719
 
 
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)
 
2081
{
 
2082
        socket_core_t *socket;
 
2083
        tcp_socket_data_t *socket_data;
1722
2084
        int packet_id;
1723
 
        packet_t packet;
 
2085
        packet_t *packet;
1724
2086
        size_t length;
 
2087
        int rc;
1725
2088
 
1726
2089
        assert(local_sockets);
1727
2090
 
1728
 
        // find the socket
 
2091
        /* Find the socket */
1729
2092
        socket = socket_cores_find(local_sockets, socket_id);
1730
 
        if(! socket){
 
2093
        if (!socket)
1731
2094
                return ENOTSOCK;
1732
 
        }
1733
 
        // get the socket specific data
1734
 
        if(! socket->specific_data){
 
2095
 
 
2096
        /* Get the socket specific data */
 
2097
        if (!socket->specific_data)
1735
2098
                return NO_DATA;
1736
 
        }
1737
 
        socket_data = (tcp_socket_data_ref) socket->specific_data;
1738
 
 
1739
 
        // check state
1740
 
        if((socket_data->state != TCP_SOCKET_ESTABLISHED) && (socket_data->state != TCP_SOCKET_CLOSE_WAIT)){
 
2099
 
 
2100
        socket_data = (tcp_socket_data_t *) socket->specific_data;
 
2101
 
 
2102
        /* Check state */
 
2103
        if ((socket_data->state != TCP_SOCKET_ESTABLISHED) &&
 
2104
            (socket_data->state != TCP_SOCKET_CLOSE_WAIT))
1741
2105
                return ENOTCONN;
1742
 
        }
1743
2106
 
1744
 
        // send the source address if desired
1745
 
        if(addrlen){
1746
 
                ERROR_PROPAGATE(data_reply(socket_data->addr, socket_data->addrlen));
 
2107
        /* Send the source address if desired */
 
2108
        if (addrlen) {
 
2109
                rc = data_reply(socket_data->addr, socket_data->addrlen);
 
2110
                if (rc != EOK)
 
2111
                        return rc;
1747
2112
                *addrlen = socket_data->addrlen;
1748
2113
        }
1749
2114
 
1750
 
        // get the next received packet
 
2115
        /* Get the next received packet */
1751
2116
        packet_id = dyn_fifo_value(&socket->received);
1752
 
        if(packet_id < 0){
 
2117
        if (packet_id < 0)
1753
2118
                return NO_DATA;
1754
 
        }
1755
 
        ERROR_PROPAGATE(packet_translate_remote(tcp_globals.net_phone, &packet, packet_id));
1756
 
 
1757
 
        // reply the packets
1758
 
        ERROR_PROPAGATE(socket_reply_packets(packet, &length));
1759
 
 
1760
 
        // release the packet
 
2119
 
 
2120
        rc = packet_translate_remote(tcp_globals.net_phone, &packet, packet_id);
 
2121
        if (rc != EOK)
 
2122
                return rc;
 
2123
 
 
2124
        /* Reply the packets */
 
2125
        rc = socket_reply_packets(packet, &length);
 
2126
        if (rc != EOK)
 
2127
                return rc;
 
2128
 
 
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
 
2132
 
 
2133
        /* Return the total length */
1764
2134
        return (int) length;
1765
2135
}
1766
2136
 
1767
 
int tcp_send_message(socket_cores_ref local_sockets, int socket_id, int fragments, size_t * data_fragment_size, int flags){
1768
 
        ERROR_DECLARE;
1769
 
 
1770
 
        socket_core_ref socket;
1771
 
        tcp_socket_data_ref socket_data;
1772
 
        packet_dimension_ref packet_dimension;
1773
 
        packet_t packet;
 
2137
int tcp_send_message(socket_cores_t *local_sockets, int socket_id,
 
2138
    int fragments, size_t *data_fragment_size, int flags)
 
2139
{
 
2140
        socket_core_t *socket;
 
2141
        tcp_socket_data_t *socket_data;
 
2142
        packet_dimension_t *packet_dimension;
 
2143
        packet_t *packet;
1774
2144
        size_t total_length;
1775
 
        tcp_header_ref header;
 
2145
        tcp_header_t *header;
1776
2146
        int index;
1777
2147
        int result;
 
2148
        int rc;
1778
2149
 
1779
2150
        assert(local_sockets);
1780
2151
        assert(data_fragment_size);
1781
2152
 
1782
 
        // find the socket
 
2153
        /* Find the socket */
1783
2154
        socket = socket_cores_find(local_sockets, socket_id);
1784
 
        if(! socket){
 
2155
        if (!socket)
1785
2156
                return ENOTSOCK;
1786
 
        }
1787
 
        // get the socket specific data
1788
 
        if(! socket->specific_data){
 
2157
 
 
2158
        /* Get the socket specific data */
 
2159
        if (!socket->specific_data)
1789
2160
                return NO_DATA;
1790
 
        }
1791
 
        socket_data = (tcp_socket_data_ref) socket->specific_data;
1792
 
 
1793
 
        // check state
1794
 
        if((socket_data->state != TCP_SOCKET_ESTABLISHED) && (socket_data->state != TCP_SOCKET_CLOSE_WAIT)){
 
2161
 
 
2162
        socket_data = (tcp_socket_data_t *) socket->specific_data;
 
2163
 
 
2164
        /* Check state */
 
2165
        if ((socket_data->state != TCP_SOCKET_ESTABLISHED) &&
 
2166
            (socket_data->state != TCP_SOCKET_CLOSE_WAIT))
1795
2167
                return ENOTCONN;
1796
 
        }
1797
 
 
1798
 
        ERROR_PROPAGATE(tl_get_ip_packet_dimension(tcp_globals.ip_phone, &tcp_globals.dimensions, socket_data->device_id, &packet_dimension));
1799
 
 
1800
 
        *data_fragment_size = ((packet_dimension->content < socket_data->data_fragment_size) ? packet_dimension->content : socket_data->data_fragment_size);
1801
 
 
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);
1805
 
                if(result < 0){
 
2168
 
 
2169
        rc = tl_get_ip_packet_dimension(tcp_globals.ip_phone,
 
2170
            &tcp_globals.dimensions, socket_data->device_id, &packet_dimension);
 
2171
        if (rc != EOK)
 
2172
                return rc;
 
2173
 
 
2174
        *data_fragment_size =
 
2175
            ((packet_dimension->content < socket_data->data_fragment_size) ?
 
2176
            packet_dimension->content : socket_data->data_fragment_size);
 
2177
 
 
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);
 
2183
                if (result < 0)
1806
2184
                        return result;
1807
 
                }
 
2185
 
1808
2186
                total_length = (size_t) result;
1809
 
                // prefix the tcp header
 
2187
 
 
2188
                /* Prefix the TCP header */
1810
2189
                header = PACKET_PREFIX(packet, tcp_header_t);
1811
 
                if(! header){
 
2190
                if (!header)
1812
2191
                        return tcp_release_and_return(packet, ENOMEM);
1813
 
                }
 
2192
 
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);
 
2195
                if (rc != EOK)
 
2196
                        return rc;
1816
2197
        }
1817
2198
 
1818
 
        // flush packets
 
2199
        /* Flush packets */
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);
1822
 
        if(packet){
1823
 
                // send the packet
 
2203
 
 
2204
        if (packet) {
 
2205
                /* Send the packet */
1824
2206
                tcp_send_packets(socket_data->device_id, packet);
1825
2207
        }
1826
2208
 
1827
2209
        return EOK;
1828
2210
}
1829
2211
 
1830
 
int tcp_close_message(socket_cores_ref local_sockets, int socket_id){
1831
 
        ERROR_DECLARE;
1832
 
 
1833
 
        socket_core_ref socket;
1834
 
        tcp_socket_data_ref socket_data;
1835
 
        packet_t packet;
1836
 
 
1837
 
        // find the socket
 
2212
int
 
2213
tcp_close_message(socket_cores_t *local_sockets, int socket_id)
 
2214
{
 
2215
        socket_core_t *socket;
 
2216
        tcp_socket_data_t *socket_data;
 
2217
        packet_t *packet;
 
2218
        int rc;
 
2219
 
 
2220
        /* Find the socket */
1838
2221
        socket = socket_cores_find(local_sockets, socket_id);
1839
 
        if(! socket){
 
2222
        if (!socket)
1840
2223
                return ENOTSOCK;
1841
 
        }
1842
 
        // get the socket specific data
1843
 
        socket_data = (tcp_socket_data_ref) socket->specific_data;
 
2224
 
 
2225
        /* Get the socket specific data */
 
2226
        socket_data = (tcp_socket_data_t *) socket->specific_data;
1844
2227
        assert(socket_data);
1845
2228
 
1846
 
        // check state
1847
 
        switch(socket_data->state){
1848
 
                case TCP_SOCKET_ESTABLISHED:
1849
 
                        socket_data->state = TCP_SOCKET_FIN_WAIT_1;
1850
 
                        break;
1851
 
                case TCP_SOCKET_CLOSE_WAIT:
1852
 
                        socket_data->state = TCP_SOCKET_LAST_ACK;
1853
 
                        break;
1854
 
//              case TCP_SOCKET_LISTEN:
1855
 
                default:
1856
 
                        // just destroy
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);
1860
 
                        }
1861
 
                        return ERROR_CODE;
 
2229
        /* Check state */
 
2230
        switch (socket_data->state) {
 
2231
        case TCP_SOCKET_ESTABLISHED:
 
2232
                socket_data->state = TCP_SOCKET_FIN_WAIT_1;
 
2233
                break;
 
2234
 
 
2235
        case TCP_SOCKET_CLOSE_WAIT:
 
2236
                socket_data->state = TCP_SOCKET_LAST_ACK;
 
2237
                break;
 
2238
 
 
2239
//      case TCP_SOCKET_LISTEN:
 
2240
 
 
2241
        default:
 
2242
                /* Just destroy */
 
2243
                rc = socket_destroy(tcp_globals.net_phone, socket_id,
 
2244
                    local_sockets, &tcp_globals.sockets,
 
2245
                    tcp_free_socket_data);
 
2246
                if (rc == EOK) {
 
2247
                        fibril_rwlock_write_unlock(socket_data->local_lock);
 
2248
                        fibril_rwlock_write_unlock(&tcp_globals.lock);
 
2249
                }
 
2250
                return rc;
1862
2251
        }
1863
 
        // send FIN
1864
 
        // TODO should I wait to complete?
1865
 
 
1866
 
        // create the notification packet
1867
 
        ERROR_PROPAGATE(tcp_create_notification_packet(&packet, socket, socket_data, 0, 1));
1868
 
 
1869
 
        // send the packet
1870
 
        ERROR_PROPAGATE(tcp_queue_packet(socket, socket_data, packet, 1));
1871
 
 
1872
 
        // flush packets
 
2252
 
 
2253
        /*
 
2254
         * Send FIN.
 
2255
         * TODO should I wait to complete?
 
2256
         */
 
2257
 
 
2258
        /* Create the notification packet */
 
2259
        rc = tcp_create_notification_packet(&packet, socket, socket_data, 0, 1);
 
2260
        if (rc != EOK)
 
2261
                return rc;
 
2262
 
 
2263
        /* Send the packet */
 
2264
        rc = tcp_queue_packet(socket, socket_data, packet, 1);
 
2265
        if (rc != EOK)
 
2266
                return rc;
 
2267
 
 
2268
        /* Flush packets */
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);
1876
 
        if(packet){
1877
 
                // send the packet
 
2272
 
 
2273
        if (packet) {
 
2274
                /* Send the packet */
1878
2275
                tcp_send_packets(socket_data->device_id, packet);
1879
2276
        }
 
2277
 
1880
2278
        return EOK;
1881
2279
}
1882
2280
 
1883
 
int tcp_create_notification_packet(packet_t * packet, socket_core_ref socket, tcp_socket_data_ref socket_data, int synchronize, int finalize){
1884
 
        ERROR_DECLARE;
1885
 
 
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)
 
2283
{
 
2284
        packet_dimension_t *packet_dimension;
 
2285
        tcp_header_t *header;
 
2286
        int rc;
1888
2287
 
1889
2288
        assert(packet);
1890
2289
 
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));
1893
 
        // get a new packet
1894
 
        *packet = packet_get_4_remote(tcp_globals.net_phone, TCP_HEADER_SIZE, packet_dimension->addr_len, packet_dimension->prefix, packet_dimension->suffix);
1895
 
        if(! * packet){
 
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);
 
2293
        if (rc != EOK)
 
2294
                return rc;
 
2295
 
 
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);
 
2300
        
 
2301
        if (!*packet) 
1896
2302
                return ENOMEM;
1897
 
        }
1898
 
        // allocate space in the packet
 
2303
 
 
2304
        /* Allocate space in the packet */
1899
2305
        header = PACKET_SUFFIX(*packet, tcp_header_t);
1900
 
        if(! header){
 
2306
        if (!header)
1901
2307
                tcp_release_and_return(*packet, ENOMEM);
1902
 
        }
1903
 
 
1904
 
        tcp_prepare_operation_header(socket, socket_data, header, synchronize, finalize);
 
2308
 
 
2309
        tcp_prepare_operation_header(socket, socket_data, header, synchronize,
 
2310
            finalize);
 
2311
 
1905
2312
        return EOK;
1906
2313
}
1907
2314
 
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){
1909
 
        ERROR_DECLARE;
1910
 
 
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)
 
2317
{
 
2318
        socket_core_t *accepted;
 
2319
        socket_core_t *socket;
 
2320
        tcp_socket_data_t *socket_data;
 
2321
        packet_dimension_t *packet_dimension;
 
2322
        int rc;
1915
2323
 
1916
2324
        assert(local_sockets);
1917
2325
        assert(data_fragment_size);
1918
2326
        assert(addrlen);
1919
2327
 
1920
 
        // find the socket
 
2328
        /* Find the socket */
1921
2329
        socket = socket_cores_find(local_sockets, socket_id);
1922
 
        if(! socket){
 
2330
        if (!socket)
1923
2331
                return ENOTSOCK;
1924
 
        }
1925
 
        // get the socket specific data
1926
 
        socket_data = (tcp_socket_data_ref) socket->specific_data;
 
2332
 
 
2333
        /* Get the socket specific data */
 
2334
        socket_data = (tcp_socket_data_t *) socket->specific_data;
1927
2335
        assert(socket_data);
1928
2336
 
1929
 
        // check state
1930
 
        if(socket_data->state != TCP_SOCKET_LISTEN){
 
2337
        /* Check state */
 
2338
        if (socket_data->state != TCP_SOCKET_LISTEN)
1931
2339
                return EINVAL;
1932
 
        }
1933
2340
 
1934
 
        do{
 
2341
        do {
1935
2342
                socket_id = dyn_fifo_value(&socket->accepted);
1936
 
                if(socket_id < 0){
 
2343
                if (socket_id < 0)
1937
2344
                        return ENOTSOCK;
1938
 
                }
1939
2345
                socket_id *= -1;
1940
2346
 
1941
2347
                accepted = socket_cores_find(local_sockets, socket_id);
1942
 
                if(! accepted){
 
2348
                if (!accepted)
1943
2349
                        return ENOTSOCK;
1944
 
                }
1945
 
                // get the socket specific data
1946
 
                socket_data = (tcp_socket_data_ref) accepted->specific_data;
 
2350
 
 
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);
 
2358
                        if (rc != EOK)
 
2359
                                return rc;
 
2360
                        rc = tl_get_ip_packet_dimension(tcp_globals.ip_phone,
 
2361
                            &tcp_globals.dimensions, socket_data->device_id,
 
2362
                            &packet_dimension);
 
2363
                        if (rc != EOK)
 
2364
                                return rc;
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));
 
2366
 
 
2367
                        *data_fragment_size =
 
2368
                            ((packet_dimension->content <
 
2369
                            socket_data->data_fragment_size) ?
 
2370
                            packet_dimension->content :
 
2371
                            socket_data->data_fragment_size);
 
2372
        
 
2373
                        if (new_socket_id > 0) {
 
2374
                                rc = socket_cores_update(local_sockets,
 
2375
                                    accepted->socket_id, new_socket_id);
 
2376
                                if (rc != EOK)
 
2377
                                        return rc;
1956
2378
                                accepted->socket_id = new_socket_id;
1957
2379
                        }
1958
2380
                }
1959
2381
                dyn_fifo_pop(&socket->accepted);
1960
 
        }while(socket_data->state != TCP_SOCKET_ESTABLISHED);
 
2382
        } while (socket_data->state != TCP_SOCKET_ESTABLISHED);
 
2383
 
1961
2384
        printf("ret accept %d\n", accepted->socket_id);
1962
2385
        return accepted->socket_id;
1963
2386
}
1964
2387
 
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)
 
2389
{
 
2390
        tcp_socket_data_t *socket_data;
1967
2391
 
1968
2392
        assert(socket);
1969
2393
 
1970
2394
        printf("destroy_socket %d\n", socket->socket_id);
1971
2395
 
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){
 
2399
 
 
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;
1981
2406
                }
1982
2407
                socket_data->pseudo_header = NULL;
1983
2408
        }
 
2409
 
1984
2410
        socket_data->headerlen = 0;
1985
 
        // free the address
1986
 
        if(socket_data->addr){
1987
 
                if(socket_data->addrlen){
 
2411
 
 
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;
1994
2421
        socket_data->addrlen = 0;
1995
2422
}
1996
2423
 
1997
 
int tcp_release_and_return(packet_t packet, int result){
 
2424
/** Releases the packet and returns the result.
 
2425
 *
 
2426
 * @param[in] packet    The packet queue to be released.
 
2427
 * @param[in] result    The result to be returned.
 
2428
 * @return              The result parameter.
 
2429
 */
 
2430
int tcp_release_and_return(packet_t *packet, int result)
 
2431
{
1998
2432
        pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
1999
2433
        return result;
2000
2434
}
2001
2435
 
2002
 
/** Default thread for new connections.
2003
 
 *
2004
 
 *  @param[in] iid The initial message identifier.
2005
 
 *  @param[in] icall The initial message call structure.
2006
 
 *
2007
 
 */
2008
 
static void tl_client_connection(ipc_callid_t iid, ipc_call_t * icall)
2009
 
{
2010
 
        /*
2011
 
         * Accept the connection
2012
 
         *  - Answer the first IPC_M_CONNECT_ME_TO call.
2013
 
         */
2014
 
        ipc_answer_0(iid, EOK);
2015
 
        
2016
 
        while(true) {
2017
 
                ipc_call_t answer;
2018
 
                int answer_count;
2019
 
                
2020
 
                /* Clear the answer structure */
2021
 
                refresh_answer(&answer, &answer_count);
2022
 
                
2023
 
                /* Fetch the next message */
2024
 
                ipc_call_t call;
2025
 
                ipc_callid_t callid = async_get_call(&call);
2026
 
                
2027
 
                /* Process the message */
2028
 
                int res = tl_module_message_standalone(callid, &call, &answer,
2029
 
                    &answer_count);
2030
 
                
2031
 
                /* End if said to either by the message or the processing result */
2032
 
                if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) || (res == EHANGUP))
2033
 
                        return;
2034
 
                
2035
 
                /* Answer the message */
2036
 
                answer_call(callid, res, &answer, answer_count);
2037
 
        }
2038
 
}
2039
 
 
2040
 
/** Starts the module.
2041
 
 *
2042
 
 *  @param argc The count of the command line arguments. Ignored parameter.
2043
 
 *  @param argv The command line parameters. Ignored parameter.
2044
 
 *
2045
 
 *  @returns EOK on success.
2046
 
 *  @returns Other error codes as defined for each specific module start function.
2047
 
 *
2048
 
 */
 
2436
/** Process IPC messages from the IP module
 
2437
 *
 
2438
 * @param[in]     iid   Message identifier.
 
2439
 * @param[in,out] icall Message parameters.
 
2440
 *
 
2441
 */
 
2442
static void tcp_receiver(ipc_callid_t iid, ipc_call_t *icall)
 
2443
{
 
2444
        packet_t *packet;
 
2445
        int rc;
 
2446
        
 
2447
        while (true) {
 
2448
                switch (IPC_GET_IMETHOD(*icall)) {
 
2449
                case NET_TL_RECEIVED:
 
2450
                        rc = packet_translate_remote(tcp_globals.net_phone, &packet,
 
2451
                            IPC_GET_PACKET(*icall));
 
2452
                        if (rc == EOK)
 
2453
                                rc = tcp_received_msg(IPC_GET_DEVICE(*icall), packet,
 
2454
                                    SERVICE_TCP, IPC_GET_ERROR(*icall));
 
2455
                        
 
2456
                        async_answer_0(iid, (sysarg_t) rc);
 
2457
                        break;
 
2458
                default:
 
2459
                        async_answer_0(iid, (sysarg_t) ENOTSUP);
 
2460
                }
 
2461
                
 
2462
                iid = async_get_call(icall);
 
2463
        }
 
2464
}
 
2465
 
 
2466
/** Initialize the TCP module.
 
2467
 *
 
2468
 * @param[in] net_phone Network module phone.
 
2469
 *
 
2470
 * @return EOK on success.
 
2471
 * @return ENOMEM if there is not enough memory left.
 
2472
 *
 
2473
 */
 
2474
int tl_initialize(int net_phone)
 
2475
{
 
2476
        fibril_rwlock_initialize(&tcp_globals.lock);
 
2477
        fibril_rwlock_write_lock(&tcp_globals.lock);
 
2478
        
 
2479
        tcp_globals.net_phone = net_phone;
 
2480
        
 
2481
        tcp_globals.icmp_phone = icmp_connect_module(ICMP_CONNECT_TIMEOUT);
 
2482
        tcp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_TCP,
 
2483
            SERVICE_TCP, tcp_receiver);
 
2484
        if (tcp_globals.ip_phone < 0) {
 
2485
                fibril_rwlock_write_unlock(&tcp_globals.lock);
 
2486
                return tcp_globals.ip_phone;
 
2487
        }
 
2488
        
 
2489
        int rc = socket_ports_initialize(&tcp_globals.sockets);
 
2490
        if (rc != EOK)
 
2491
                goto out;
 
2492
 
 
2493
        rc = packet_dimensions_initialize(&tcp_globals.dimensions);
 
2494
        if (rc != EOK) {
 
2495
                socket_ports_destroy(&tcp_globals.sockets, free);
 
2496
                goto out;
 
2497
        }
 
2498
 
 
2499
        tcp_globals.last_used_port = TCP_FREE_PORTS_START - 1;
 
2500
 
 
2501
out:
 
2502
        fibril_rwlock_write_unlock(&tcp_globals.lock);
 
2503
        return rc;
 
2504
}
 
2505
 
2049
2506
int main(int argc, char *argv[])
2050
2507
{
2051
 
        ERROR_DECLARE;
2052
 
        
2053
 
        /* Start the module */
2054
 
        if (ERROR_OCCURRED(tl_module_start_standalone(tl_client_connection)))
2055
 
                return ERROR_CODE;
2056
 
        
2057
 
        return EOK;
 
2508
        return tl_module_start(SERVICE_TCP);
2058
2509
}
2059
2510
 
2060
2511
/** @}