Changes in uspace/lib/net/tl/socket_core.c [6b82009:61bfc370] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/net/tl/socket_core.c
r6b82009 r61bfc370 38 38 #include <packet_client.h> 39 39 #include <packet_remote.h> 40 40 41 #include <net/socket_codes.h> 41 42 #include <net/in.h> … … 43 44 #include <net/packet.h> 44 45 #include <net/modules.h> 46 45 47 #include <stdint.h> 46 48 #include <stdlib.h> 47 49 #include <errno.h> 50 48 51 #include <adt/dynamic_fifo.h> 49 52 #include <adt/int_map.h> … … 53 56 * switching to the sequence. 54 57 */ 55 #define SOCKET_ID_TRIES 58 #define SOCKET_ID_TRIES 100 56 59 57 60 /** Bound port sockets.*/ … … 69 72 INT_MAP_IMPLEMENT(socket_ports, socket_port_t); 70 73 71 /** Destroy the socket.74 /** Destroys the socket. 72 75 * 73 76 * If the socket is bound, the port is released. 74 * Release all buffered packets, call the release function and removethe77 * Releases all buffered packets, calls the release function and removes the 75 78 * socket from the local sockets. 76 79 * 77 * @param[in] sess Packet server session.78 * @param[in] socket Socket to be destroyed.79 * @param[in,out] local_sockets Local sockets to be updated.80 * @param[in,out] global_sockets Global sockets to be updated.81 * @param[in] socket_release Client release callback function.82 * 83 */ 84 s tatic void socket_destroy_core(async_sess_t *sess, socket_core_t *socket,80 * @param[in] packet_phone The packet server phone to release buffered packets. 81 * @param[in] socket The socket to be destroyed. 82 * @param[in,out] local_sockets The local sockets to be updated. 83 * @param[in,out] global_sockets The global sockets to be updated. 84 * @param[in] socket_release The client release callback function. 85 */ 86 static void 87 socket_destroy_core(int packet_phone, socket_core_t *socket, 85 88 socket_cores_t *local_sockets, socket_ports_t *global_sockets, 86 89 void (* socket_release)(socket_core_t *socket)) 87 90 { 88 /* If bound */ 91 int packet_id; 92 93 // if bound 89 94 if (socket->port) { 90 / * Release the port */95 // release the port 91 96 socket_port_release(global_sockets, socket); 92 97 } 93 98 94 /* Release all received packets */ 95 int packet_id; 99 // release all received packets 96 100 while ((packet_id = dyn_fifo_pop(&socket->received)) >= 0) 97 pq_release_remote( sess, packet_id);98 101 pq_release_remote(packet_phone, packet_id); 102 99 103 dyn_fifo_destroy(&socket->received); 100 104 dyn_fifo_destroy(&socket->accepted); 101 105 102 106 if (socket_release) 103 107 socket_release(socket); 104 105 socket_cores_exclude(local_sockets, socket->socket_id , free);106 } 107 108 /** Destroy local sockets.109 * 110 * Release all buffered packets and callthe release function for each of the108 109 socket_cores_exclude(local_sockets, socket->socket_id); 110 } 111 112 /** Destroys local sockets. 113 * 114 * Releases all buffered packets and calls the release function for each of the 111 115 * sockets. 112 116 * 113 * @param[in] sess Packet server session.114 * @param[in] local_sockets Local sockets to be destroyed.115 * @param[in,out] global_sockets Global sockets to be updated.116 * @param[in] socket_release Client release callback function.117 * 118 */ 119 void socket_cores_release(async_sess_t *sess, socket_cores_t *local_sockets,117 * @param[in] packet_phone The packet server phone to release buffered packets. 118 * @param[in] local_sockets The local sockets to be destroyed. 119 * @param[in,out] global_sockets The global sockets to be updated. 120 * @param[in] socket_release The client release callback function. 121 */ 122 void 123 socket_cores_release(int packet_phone, socket_cores_t *local_sockets, 120 124 socket_ports_t *global_sockets, 121 125 void (* socket_release)(socket_core_t *socket)) 122 126 { 127 int index; 128 123 129 if (!socket_cores_is_valid(local_sockets)) 124 130 return; 125 131 126 132 local_sockets->magic = 0; 127 128 int index; 133 129 134 for (index = 0; index < local_sockets->next; ++index) { 130 135 if (socket_cores_item_is_valid(&local_sockets->items[index])) { 131 136 local_sockets->items[index].magic = 0; 132 137 133 138 if (local_sockets->items[index].value) { 134 socket_destroy_core( sess,139 socket_destroy_core(packet_phone, 135 140 local_sockets->items[index].value, 136 141 local_sockets, global_sockets, … … 141 146 } 142 147 } 143 148 144 149 free(local_sockets->items); 145 150 } … … 161 166 int rc; 162 167 163 / * Create a wrapper */168 // create a wrapper 164 169 socket_ref = malloc(sizeof(*socket_ref)); 165 170 if (!socket_ref) … … 167 172 168 173 *socket_ref = socket; 169 / * Add the wrapper */174 // add the wrapper 170 175 rc = socket_port_map_add(&socket_port->map, key, key_length, 171 176 socket_ref); … … 201 206 int rc; 202 207 203 / * Create a wrapper */208 // create a wrapper 204 209 socket_port = malloc(sizeof(*socket_port)); 205 210 if (!socket_port) … … 216 221 goto fail; 217 222 218 / * Register the incoming port */223 // register the incomming port 219 224 rc = socket_ports_add(global_sockets, port, socket_port); 220 225 if (rc < 0) … … 225 230 226 231 fail: 227 socket_port_map_destroy(&socket_port->map , free);232 socket_port_map_destroy(&socket_port->map); 228 233 free(socket_port); 229 234 return rc; … … 272 277 273 278 address_in = (struct sockaddr_in *) addr; 274 / * Find the socket */279 // find the socket 275 280 socket = socket_cores_find(local_sockets, socket_id); 276 281 if (!socket) 277 282 return ENOTSOCK; 278 283 279 / * Bind a free port? */284 // bind a free port? 280 285 if (address_in->sin_port <= 0) 281 286 return socket_bind_free_port(global_sockets, socket, 282 287 free_ports_start, free_ports_end, last_used_port); 283 288 284 / * Try to find the port */289 // try to find the port 285 290 socket_port = socket_ports_find(global_sockets, 286 291 ntohs(address_in->sin_port)); 287 292 if (socket_port) { 288 / * Already used */293 // already used 289 294 return EADDRINUSE; 290 295 } 291 296 292 / * If bound */297 // if bound 293 298 if (socket->port) { 294 / * Release the port */299 // release the port 295 300 socket_port_release(global_sockets, socket); 296 301 } … … 328 333 int index; 329 334 330 / * From the last used one */335 // from the last used one 331 336 index = last_used_port; 332 337 … … 334 339 ++index; 335 340 336 / * Till the range end */341 // til the range end 337 342 if (index >= free_ports_end) { 338 / * Start from the range beginning */343 // start from the range beginning 339 344 index = free_ports_start - 1; 340 345 do { 341 346 ++index; 342 / * Till the last used one */347 // til the last used one 343 348 if (index >= last_used_port) { 344 / * None found */349 // none found 345 350 return ENOTCONN; 346 351 } 347 352 } while (socket_ports_find(global_sockets, index)); 348 353 349 / * Found, break immediately */354 // found, break immediately 350 355 break; 351 356 } … … 371 376 372 377 count = 0; 373 #if 0 374 socket_id = socket_globals.last_id; 375 #endif 378 // socket_id = socket_globals.last_id; 376 379 do { 377 380 if (count < SOCKET_ID_TRIES) { … … 381 384 socket_id = 1; 382 385 ++count; 383 / * Only this branch for last_id */386 // only this branch for last_id 384 387 } else { 385 388 if (socket_id < INT_MAX) { 386 389 ++ socket_id; 387 #if 0 388 } else if(socket_globals.last_id) { 389 socket_globals.last_id = 0; 390 socket_id = 1; 391 #endif 392 } else { 390 /* } else if(socket_globals.last_id) { 391 * socket_globals.last_id = 0; 392 * socket_id = 1; 393 */ } else { 393 394 return ELIMIT; 394 395 } … … 401 402 } 402 403 403 /** Create a new socket. 404 * 405 * @param[in,out] local_sockets Local sockets to be updated. 406 * @param[in] sess Application session. 407 * @param[in] specific_data Socket specific data. 408 * @param[in,out] socket_id New socket identifier. A new identifier 409 * is chosen if set to zero or negative. 410 * A negative identifier is chosen if set 411 * to negative. 412 * 413 * @return EOK on success. 414 * @return EINVAL if the socket_id parameter is NULL. 415 * @return ENOMEM if there is not enough memory left. 416 * 417 */ 418 int socket_create(socket_cores_t *local_sockets, async_sess_t* sess, 404 /** Creates a new socket. 405 * 406 * @param[in,out] local_sockets The local sockets to be updated. 407 * @param[in] app_phone The application phone. 408 * @param[in] specific_data The socket specific data. 409 * @param[in,out] socket_id The new socket identifier. A new identifier is 410 * chosen if set to zero or negative. A negative identifier 411 * is chosen if set to negative. 412 * @return EOK on success. 413 * @return EINVAL if the socket_id parameter is NULL. 414 * @return ENOMEM if there is not enough memory left. 415 */ 416 int 417 socket_create(socket_cores_t *local_sockets, int app_phone, 419 418 void *specific_data, int *socket_id) 420 419 { … … 426 425 return EINVAL; 427 426 428 / * Store the socket */427 // store the socket 429 428 if (*socket_id <= 0) { 430 429 positive = (*socket_id == 0); … … 442 441 return ENOMEM; 443 442 444 / * Initialize */445 socket-> sess = sess;443 // initialize 444 socket->phone = app_phone; 446 445 socket->port = -1; 447 446 socket->key = NULL; … … 472 471 } 473 472 474 /** Destroy the socket.473 /** Destroys the socket. 475 474 * 476 475 * If the socket is bound, the port is released. 477 * Release all buffered packets, call the release function and removethe476 * Releases all buffered packets, calls the release function and removes the 478 477 * socket from the local sockets. 479 478 * 480 * @param[in] sess Packet server session. 481 * @param[in] socket_id Socket identifier. 482 * @param[in,out] local_sockets Local sockets to be updated. 483 * @param[in,out] global_sockets Global sockets to be updated. 484 * @param[in] socket_release Client release callback function. 485 * 486 * @return EOK on success. 487 * @return ENOTSOCK if the socket is not found. 488 * 479 * @param[in] packet_phone The packet server phone to release buffered packets. 480 * @param[in] socket_id The socket identifier. 481 * @param[in,out] local_sockets The local sockets to be updated. 482 * @param[in,out] global_sockets The global sockets to be updated. 483 * @param[in] socket_release The client release callback function. 484 * @return EOK on success. 485 * @return ENOTSOCK if the socket is not found. 489 486 */ 490 487 int 491 socket_destroy( async_sess_t *sess, int socket_id, socket_cores_t *local_sockets,488 socket_destroy(int packet_phone, int socket_id, socket_cores_t *local_sockets, 492 489 socket_ports_t *global_sockets, 493 490 void (*socket_release)(socket_core_t *socket)) 494 491 { 495 /* Find the socket */ 496 socket_core_t *socket = socket_cores_find(local_sockets, socket_id); 492 socket_core_t *socket; 493 int accepted_id; 494 495 // find the socket 496 socket = socket_cores_find(local_sockets, socket_id); 497 497 if (!socket) 498 498 return ENOTSOCK; 499 499 500 /* Destroy all accepted sockets */ 501 int accepted_id; 500 // destroy all accepted sockets 502 501 while ((accepted_id = dyn_fifo_pop(&socket->accepted)) >= 0) 503 socket_destroy( sess, accepted_id, local_sockets,502 socket_destroy(packet_phone, accepted_id, local_sockets, 504 503 global_sockets, socket_release); 505 504 506 socket_destroy_core( sess, socket, local_sockets, global_sockets,505 socket_destroy_core(packet_phone, socket, local_sockets, global_sockets, 507 506 socket_release); 508 507 … … 536 535 next_packet = pq_next(packet); 537 536 if (!next_packet) { 538 / * Write all if only one fragment */537 // write all if only one fragment 539 538 rc = data_reply(packet_get_data(packet), 540 539 packet_get_data_length(packet)); 541 540 if (rc != EOK) 542 541 return rc; 543 / * Store the total length */542 // store the total length 544 543 *length = packet_get_data_length(packet); 545 544 } else { 546 / * Count the packet fragments */545 // count the packet fragments 547 546 fragments = 1; 548 547 next_packet = pq_next(packet); … … 550 549 ++fragments; 551 550 552 / * Compute and store the fragment lengths */551 // compute and store the fragment lengths 553 552 lengths = (size_t *) malloc(sizeof(size_t) * fragments + 554 553 sizeof(size_t)); … … 566 565 } 567 566 568 / * Write the fragment lengths */567 // write the fragment lengths 569 568 rc = data_reply(lengths, sizeof(int) * (fragments + 1)); 570 569 if (rc != EOK) { … … 574 573 next_packet = packet; 575 574 576 / * Write the fragments */575 // write the fragments 577 576 for (index = 0; index < fragments; ++index) { 578 577 rc = data_reply(packet_get_data(next_packet), … … 585 584 } 586 585 587 / * Store the total length */586 // store the total length 588 587 *length = lengths[fragments]; 589 588 free(lengths); … … 637 636 return; 638 637 639 / * Find ports */638 // find ports 640 639 socket_port = socket_ports_find(global_sockets, socket->port); 641 640 if (socket_port) { 642 / * Find the socket */641 // find the socket 643 642 socket_ref = socket_port_map_find(&socket_port->map, 644 643 socket->key, socket->key_length); … … 647 646 --socket_port->count; 648 647 649 / * Release if empty */648 // release if empty 650 649 if (socket_port->count <= 0) { 651 / * Destroy the map */652 socket_port_map_destroy(&socket_port->map , free);653 / * Release the port */650 // destroy the map 651 socket_port_map_destroy(&socket_port->map); 652 // release the port 654 653 socket_ports_exclude(global_sockets, 655 socket->port , free);654 socket->port); 656 655 } else { 657 / * Remove */656 // remove 658 657 socket_port_map_exclude(&socket_port->map, 659 socket->key, socket->key_length , free);658 socket->key, socket->key_length); 660 659 } 661 660 } … … 686 685 int rc; 687 686 688 / * Find ports */687 // find ports 689 688 socket_port = socket_ports_find(global_sockets, port); 690 689 if (!socket_port) 691 690 return ENOENT; 692 691 693 / * Add the socket */692 // add the socket 694 693 rc = socket_port_add_core(socket_port, socket, key, key_length); 695 694 if (rc != EOK)
Note:
See TracChangeset
for help on using the changeset viewer.