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