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