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