Changeset b5e68c8 in mainline for uspace/lib/net/tl/socket_core.c
- Timestamp:
- 2011-05-12T16:49:44Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f36787d7
- Parents:
- e80329d6 (diff), 750636a (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/net/tl/socket_core.c
re80329d6 rb5e68c8 48 48 #include <stdlib.h> 49 49 #include <errno.h> 50 #include <err.h>51 50 52 51 #include <adt/dynamic_fifo.h> … … 69 68 INT_MAP_IMPLEMENT(socket_cores, socket_core_t); 70 69 71 GENERIC_CHAR_MAP_IMPLEMENT(socket_port_map, socket_core_ ref);70 GENERIC_CHAR_MAP_IMPLEMENT(socket_port_map, socket_core_t *); 72 71 73 72 INT_MAP_IMPLEMENT(socket_ports, socket_port_t); … … 86 85 */ 87 86 static void 88 socket_destroy_core(int packet_phone, socket_core_ refsocket,89 socket_cores_ ref local_sockets, socket_ports_refglobal_sockets,90 void (* socket_release)(socket_core_ refsocket))87 socket_destroy_core(int packet_phone, socket_core_t *socket, 88 socket_cores_t *local_sockets, socket_ports_t *global_sockets, 89 void (* socket_release)(socket_core_t *socket)) 91 90 { 92 91 int packet_id; 93 92 94 / / if bound93 /* If bound */ 95 94 if (socket->port) { 96 / / release the port95 /* Release the port */ 97 96 socket_port_release(global_sockets, socket); 98 97 } 99 98 100 / / release all received packets99 /* Release all received packets */ 101 100 while ((packet_id = dyn_fifo_pop(&socket->received)) >= 0) 102 101 pq_release_remote(packet_phone, packet_id); … … 108 107 socket_release(socket); 109 108 110 socket_cores_exclude(local_sockets, socket->socket_id );109 socket_cores_exclude(local_sockets, socket->socket_id, free); 111 110 } 112 111 … … 122 121 */ 123 122 void 124 socket_cores_release(int packet_phone, socket_cores_ reflocal_sockets,125 socket_ports_ refglobal_sockets,126 void (* socket_release)(socket_core_ refsocket))123 socket_cores_release(int packet_phone, socket_cores_t *local_sockets, 124 socket_ports_t *global_sockets, 125 void (* socket_release)(socket_core_t *socket)) 127 126 { 128 127 int index; … … 157 156 * @param[in] key The socket key identifier. 158 157 * @param[in] key_length The socket key length. 159 * @return sEOK on success.160 * @return sENOMEM if there is not enough memory left.158 * @return EOK on success. 159 * @return ENOMEM if there is not enough memory left. 161 160 */ 162 161 static int 163 socket_port_add_core(socket_port_ref socket_port, socket_core_ref socket, 164 const char *key, size_t key_length) 165 { 166 ERROR_DECLARE; 167 168 socket_core_ref *socket_ref; 169 170 // create a wrapper 162 socket_port_add_core(socket_port_t *socket_port, socket_core_t *socket, 163 const uint8_t *key, size_t key_length) 164 { 165 socket_core_t **socket_ref; 166 int rc; 167 168 /* Create a wrapper */ 171 169 socket_ref = malloc(sizeof(*socket_ref)); 172 170 if (!socket_ref) … … 174 172 175 173 *socket_ref = socket; 176 // add the wrapper 177 if (ERROR_OCCURRED(socket_port_map_add(&socket_port->map, key, 178 key_length, socket_ref))) { 174 /* Add the wrapper */ 175 rc = socket_port_map_add(&socket_port->map, key, key_length, 176 socket_ref); 177 if (rc != EOK) { 179 178 free(socket_ref); 180 return ERROR_CODE;179 return rc; 181 180 } 182 181 … … 195 194 * @param[in] socket The socket to be added. 196 195 * @param[in] port The port number to be bound to. 197 * @return sEOK on success.198 * @return sENOMEM if there is not enough memory left.199 * @return sOther error codes as defined for the196 * @return EOK on success. 197 * @return ENOMEM if there is not enough memory left. 198 * @return Other error codes as defined for the 200 199 * socket_ports_add() function. 201 200 */ 202 201 static int 203 socket_bind_insert(socket_ports_ ref global_sockets, socket_core_refsocket,202 socket_bind_insert(socket_ports_t *global_sockets, socket_core_t *socket, 204 203 int port) 205 204 { 206 ERROR_DECLARE; 207 208 socket_port_ref socket_port; 209 210 // create a wrapper 205 socket_port_t *socket_port; 206 int rc; 207 208 /* Create a wrapper */ 211 209 socket_port = malloc(sizeof(*socket_port)); 212 210 if (!socket_port) … … 214 212 215 213 socket_port->count = 0; 216 if (ERROR_OCCURRED(socket_port_map_initialize(&socket_port->map)) || 217 ERROR_OCCURRED(socket_port_add_core(socket_port, socket, 218 SOCKET_MAP_KEY_LISTENING, 0))) { 219 socket_port_map_destroy(&socket_port->map); 220 free(socket_port); 221 return ERROR_CODE; 222 } 223 224 // register the incomming port 225 ERROR_CODE = socket_ports_add(global_sockets, port, socket_port); 226 if (ERROR_CODE < 0) { 227 socket_port_map_destroy(&socket_port->map); 228 free(socket_port); 229 return ERROR_CODE; 230 } 214 rc = socket_port_map_initialize(&socket_port->map); 215 if (rc != EOK) 216 goto fail; 217 218 rc = socket_port_add_core(socket_port, socket, 219 (const uint8_t *) SOCKET_MAP_KEY_LISTENING, 0); 220 if (rc != EOK) 221 goto fail; 222 223 /* Register the incoming port */ 224 rc = socket_ports_add(global_sockets, port, socket_port); 225 if (rc < 0) 226 goto fail; 231 227 232 228 socket->port = port; 233 229 return EOK; 230 231 fail: 232 socket_port_map_destroy(&socket_port->map, free); 233 free(socket_port); 234 return rc; 235 234 236 } 235 237 … … 246 248 * @param[in] free_ports_end The maximum free port. 247 249 * @param[in] last_used_port The last used free port. 248 * @return sEOK on success.249 * @return sENOTSOCK if the socket was not found.250 * @return sEAFNOSUPPORT if the address family is not supported.251 * @return sEADDRINUSE if the port is already in use.252 * @return sOther error codes as defined for the250 * @return EOK on success. 251 * @return ENOTSOCK if the socket was not found. 252 * @return EAFNOSUPPORT if the address family is not supported. 253 * @return EADDRINUSE if the port is already in use. 254 * @return Other error codes as defined for the 253 255 * socket_bind_free_port() function. 254 * @return sOther error codes as defined for the256 * @return Other error codes as defined for the 255 257 * socket_bind_insert() function. 256 258 */ 257 259 int 258 socket_bind(socket_cores_ ref local_sockets, socket_ports_refglobal_sockets,260 socket_bind(socket_cores_t *local_sockets, socket_ports_t *global_sockets, 259 261 int socket_id, void *addr, size_t addrlen, int free_ports_start, 260 262 int free_ports_end, int last_used_port) 261 263 { 262 socket_core_ refsocket;263 socket_port_ refsocket_port;264 socket_core_t *socket; 265 socket_port_t *socket_port; 264 266 struct sockaddr *address; 265 267 struct sockaddr_in *address_in; … … 275 277 276 278 address_in = (struct sockaddr_in *) addr; 277 / / find the socket279 /* Find the socket */ 278 280 socket = socket_cores_find(local_sockets, socket_id); 279 281 if (!socket) 280 282 return ENOTSOCK; 281 283 282 / / bind a free port?284 /* Bind a free port? */ 283 285 if (address_in->sin_port <= 0) 284 286 return socket_bind_free_port(global_sockets, socket, 285 287 free_ports_start, free_ports_end, last_used_port); 286 288 287 / / try to find the port289 /* Try to find the port */ 288 290 socket_port = socket_ports_find(global_sockets, 289 291 ntohs(address_in->sin_port)); 290 292 if (socket_port) { 291 / / already used293 /* Already used */ 292 294 return EADDRINUSE; 293 295 } 294 296 295 / / if bound297 /* If bound */ 296 298 if (socket->port) { 297 / / release the port299 /* Release the port */ 298 300 socket_port_release(global_sockets, socket); 299 301 } … … 320 322 * @param[in] free_ports_end The maximum free port. 321 323 * @param[in] last_used_port The last used free port. 322 * @return sEOK on success.323 * @return sENOTCONN if no free port was found.324 * @return sOther error codes as defined for the324 * @return EOK on success. 325 * @return ENOTCONN if no free port was found. 326 * @return Other error codes as defined for the 325 327 * socket_bind_insert() function. 326 328 */ 327 329 int 328 socket_bind_free_port(socket_ports_ ref global_sockets, socket_core_refsocket,330 socket_bind_free_port(socket_ports_t *global_sockets, socket_core_t *socket, 329 331 int free_ports_start, int free_ports_end, int last_used_port) 330 332 { 331 333 int index; 332 334 333 / / from the last used one335 /* From the last used one */ 334 336 index = last_used_port; 335 337 … … 337 339 ++index; 338 340 339 / / til the range end341 /* Till the range end */ 340 342 if (index >= free_ports_end) { 341 / / start from the range beginning343 /* Start from the range beginning */ 342 344 index = free_ports_start - 1; 343 345 do { 344 346 ++index; 345 / / til the last used one347 /* Till the last used one */ 346 348 if (index >= last_used_port) { 347 / / none found349 /* None found */ 348 350 return ENOTCONN; 349 351 } 350 352 } while (socket_ports_find(global_sockets, index)); 351 353 352 / / found, break immediately354 /* Found, break immediately */ 353 355 break; 354 356 } … … 365 367 * requested. A negative identifier is requested if set to 366 368 * false. 367 * @return sThe new socket identifier.368 * @return sELIMIT if there is no socket identifier available.369 */ 370 static int socket_generate_new_id(socket_cores_ reflocal_sockets, int positive)369 * @return The new socket identifier. 370 * @return ELIMIT if there is no socket identifier available. 371 */ 372 static int socket_generate_new_id(socket_cores_t *local_sockets, int positive) 371 373 { 372 374 int socket_id; … … 374 376 375 377 count = 0; 376 // socket_id = socket_globals.last_id; 378 #if 0 379 socket_id = socket_globals.last_id; 380 #endif 377 381 do { 378 382 if (count < SOCKET_ID_TRIES) { … … 382 386 socket_id = 1; 383 387 ++count; 384 / / only this branch for last_id388 /* Only this branch for last_id */ 385 389 } else { 386 390 if (socket_id < INT_MAX) { 387 391 ++ socket_id; 388 /* } else if(socket_globals.last_id) { 389 * socket_globals.last_id = 0; 390 * socket_id = 1; 391 */ } else { 392 #if 0 393 } else if(socket_globals.last_id) { 394 socket_globals.last_id = 0; 395 socket_id = 1; 396 #endif 397 } else { 392 398 return ELIMIT; 393 399 } … … 408 414 * chosen if set to zero or negative. A negative identifier 409 415 * is chosen if set to negative. 410 * @return sEOK on success.411 * @return sEINVAL if the socket_id parameter is NULL.412 * @return sENOMEM if there is not enough memory left.416 * @return EOK on success. 417 * @return EINVAL if the socket_id parameter is NULL. 418 * @return ENOMEM if there is not enough memory left. 413 419 */ 414 420 int 415 socket_create(socket_cores_ reflocal_sockets, int app_phone,421 socket_create(socket_cores_t *local_sockets, int app_phone, 416 422 void *specific_data, int *socket_id) 417 423 { 418 ERROR_DECLARE; 419 420 socket_core_ref socket; 421 int res; 424 socket_core_t *socket; 422 425 int positive; 426 int rc; 423 427 424 428 if (!socket_id) 425 429 return EINVAL; 426 430 427 / / store the socket431 /* Store the socket */ 428 432 if (*socket_id <= 0) { 429 433 positive = (*socket_id == 0); … … 437 441 } 438 442 439 socket = (socket_core_ ref) malloc(sizeof(*socket));443 socket = (socket_core_t *) malloc(sizeof(*socket)); 440 444 if (!socket) 441 445 return ENOMEM; 442 446 443 / / initialize447 /* Initialize */ 444 448 socket->phone = app_phone; 445 449 socket->port = -1; … … 447 451 socket->key_length = 0; 448 452 socket->specific_data = specific_data; 449 if (ERROR_OCCURRED(dyn_fifo_initialize(&socket->received,450 SOCKET_INITIAL_RECEIVED_SIZE))) {453 rc = dyn_fifo_initialize(&socket->received, SOCKET_INITIAL_RECEIVED_SIZE); 454 if (rc != EOK) { 451 455 free(socket); 452 return ERROR_CODE; 453 } 454 if (ERROR_OCCURRED(dyn_fifo_initialize(&socket->accepted, 455 SOCKET_INITIAL_ACCEPTED_SIZE))) { 456 return rc; 457 } 458 459 rc = dyn_fifo_initialize(&socket->accepted, SOCKET_INITIAL_ACCEPTED_SIZE); 460 if (rc != EOK) { 456 461 dyn_fifo_destroy(&socket->received); 457 462 free(socket); 458 return ERROR_CODE;463 return rc; 459 464 } 460 465 socket->socket_id = *socket_id; 461 r es= socket_cores_add(local_sockets, socket->socket_id, socket);462 if (r es< 0) {466 rc = socket_cores_add(local_sockets, socket->socket_id, socket); 467 if (rc < 0) { 463 468 dyn_fifo_destroy(&socket->received); 464 469 dyn_fifo_destroy(&socket->accepted); 465 470 free(socket); 466 return r es;471 return rc; 467 472 } 468 473 … … 481 486 * @param[in,out] global_sockets The global sockets to be updated. 482 487 * @param[in] socket_release The client release callback function. 483 * @return sEOK on success.484 * @return sENOTSOCK if the socket is not found.488 * @return EOK on success. 489 * @return ENOTSOCK if the socket is not found. 485 490 */ 486 491 int 487 socket_destroy(int packet_phone, int socket_id, socket_cores_ reflocal_sockets,488 socket_ports_ refglobal_sockets,489 void (*socket_release)(socket_core_ refsocket))490 { 491 socket_core_ refsocket;492 socket_destroy(int packet_phone, int socket_id, socket_cores_t *local_sockets, 493 socket_ports_t *global_sockets, 494 void (*socket_release)(socket_core_t *socket)) 495 { 496 socket_core_t *socket; 492 497 int accepted_id; 493 498 494 / / find the socket499 /* Find the socket */ 495 500 socket = socket_cores_find(local_sockets, socket_id); 496 501 if (!socket) 497 502 return ENOTSOCK; 498 503 499 / / destroy all accepted sockets504 /* Destroy all accepted sockets */ 500 505 while ((accepted_id = dyn_fifo_pop(&socket->accepted)) >= 0) 501 506 socket_destroy(packet_phone, accepted_id, local_sockets, … … 515 520 * @param[in] packet The packet to be transfered. 516 521 * @param[out] length The total data length. 517 * @return sEOK on success.518 * @return sEBADMEM if the length parameter is NULL.519 * @return sENOMEM if there is not enough memory left.520 * @return sOther error codes as defined for the data_reply()522 * @return EOK on success. 523 * @return EBADMEM if the length parameter is NULL. 524 * @return ENOMEM if there is not enough memory left. 525 * @return Other error codes as defined for the data_reply() 521 526 * function. 522 527 */ 523 int socket_reply_packets(packet_t packet, size_t *length) 524 { 525 ERROR_DECLARE; 526 527 packet_t next_packet; 528 int socket_reply_packets(packet_t *packet, size_t *length) 529 { 530 packet_t *next_packet; 528 531 size_t fragments; 529 532 size_t *lengths; 530 533 size_t index; 534 int rc; 531 535 532 536 if (!length) … … 535 539 next_packet = pq_next(packet); 536 540 if (!next_packet) { 537 // write all if only one fragment 538 ERROR_PROPAGATE(data_reply(packet_get_data(packet), 539 packet_get_data_length(packet))); 540 // store the total length 541 /* Write all if only one fragment */ 542 rc = data_reply(packet_get_data(packet), 543 packet_get_data_length(packet)); 544 if (rc != EOK) 545 return rc; 546 /* Store the total length */ 541 547 *length = packet_get_data_length(packet); 542 548 } else { 543 / / count the packet fragments549 /* Count the packet fragments */ 544 550 fragments = 1; 545 551 next_packet = pq_next(packet); … … 547 553 ++fragments; 548 554 549 / / compute and store the fragment lengths555 /* Compute and store the fragment lengths */ 550 556 lengths = (size_t *) malloc(sizeof(size_t) * fragments + 551 557 sizeof(size_t)); … … 563 569 } 564 570 565 / / write the fragment lengths566 if (ERROR_OCCURRED(data_reply(lengths,567 sizeof(int) * (fragments + 1)))) {571 /* Write the fragment lengths */ 572 rc = data_reply(lengths, sizeof(int) * (fragments + 1)); 573 if (rc != EOK) { 568 574 free(lengths); 569 return ERROR_CODE;575 return rc; 570 576 } 571 577 next_packet = packet; 572 578 573 / / write the fragments579 /* Write the fragments */ 574 580 for (index = 0; index < fragments; ++index) { 575 ERROR_CODE= data_reply(packet_get_data(next_packet),581 rc = data_reply(packet_get_data(next_packet), 576 582 lengths[index]); 577 if ( ERROR_OCCURRED(ERROR_CODE)) {583 if (rc != EOK) { 578 584 free(lengths); 579 return ERROR_CODE;585 return rc; 580 586 } 581 587 next_packet = pq_next(next_packet); 582 588 } 583 589 584 / / store the total length590 /* Store the total length */ 585 591 *length = lengths[fragments]; 586 592 free(lengths); … … 596 602 * @param[in] key The socket key identifier. 597 603 * @param[in] key_length The socket key length. 598 * @return sThe found socket.599 * @return sNULL if no socket was found.600 */ 601 socket_core_ ref602 socket_port_find(socket_ports_ ref global_sockets, int port, const char*key,604 * @return The found socket. 605 * @return NULL if no socket was found. 606 */ 607 socket_core_t * 608 socket_port_find(socket_ports_t *global_sockets, int port, const uint8_t *key, 603 609 size_t key_length) 604 610 { 605 socket_port_ refsocket_port;606 socket_core_ ref*socket_ref;611 socket_port_t *socket_port; 612 socket_core_t **socket_ref; 607 613 608 614 socket_port = socket_ports_find(global_sockets, port); … … 626 632 */ 627 633 void 628 socket_port_release(socket_ports_ ref global_sockets, socket_core_refsocket)629 { 630 socket_port_ refsocket_port;631 socket_core_ ref*socket_ref;634 socket_port_release(socket_ports_t *global_sockets, socket_core_t *socket) 635 { 636 socket_port_t *socket_port; 637 socket_core_t **socket_ref; 632 638 633 639 if (!socket->port) 634 640 return; 635 641 636 / / find ports642 /* Find ports */ 637 643 socket_port = socket_ports_find(global_sockets, socket->port); 638 644 if (socket_port) { 639 / / find the socket645 /* Find the socket */ 640 646 socket_ref = socket_port_map_find(&socket_port->map, 641 647 socket->key, socket->key_length); … … 644 650 --socket_port->count; 645 651 646 / / release if empty652 /* Release if empty */ 647 653 if (socket_port->count <= 0) { 648 / / destroy the map649 socket_port_map_destroy(&socket_port->map );650 / / release the port654 /* Destroy the map */ 655 socket_port_map_destroy(&socket_port->map, free); 656 /* Release the port */ 651 657 socket_ports_exclude(global_sockets, 652 socket->port );658 socket->port, free); 653 659 } else { 654 / / remove660 /* Remove */ 655 661 socket_port_map_exclude(&socket_port->map, 656 socket->key, socket->key_length );662 socket->key, socket->key_length, free); 657 663 } 658 664 } … … 671 677 * @param[in] key The socket key identifier. 672 678 * @param[in] key_length The socket key length. 673 * @return sEOK on success.674 * @return sENOENT if the port is not already used.675 * @return sOther error codes as defined for the679 * @return EOK on success. 680 * @return ENOENT if the port is not already used. 681 * @return Other error codes as defined for the 676 682 * socket_port_add_core() function. 677 683 */ 678 684 int 679 socket_port_add(socket_ports_ref global_sockets, int port, 680 socket_core_ref socket, const char *key, size_t key_length) 681 { 682 ERROR_DECLARE; 683 684 socket_port_ref socket_port; 685 686 // find ports 685 socket_port_add(socket_ports_t *global_sockets, int port, 686 socket_core_t *socket, const uint8_t *key, size_t key_length) 687 { 688 socket_port_t *socket_port; 689 int rc; 690 691 /* Find ports */ 687 692 socket_port = socket_ports_find(global_sockets, port); 688 693 if (!socket_port) 689 694 return ENOENT; 690 695 691 // add the socket 692 ERROR_PROPAGATE(socket_port_add_core(socket_port, socket, key, 693 key_length)); 696 /* Add the socket */ 697 rc = socket_port_add_core(socket_port, socket, key, key_length); 698 if (rc != EOK) 699 return rc; 694 700 695 701 socket->port = port;
Note:
See TracChangeset
for help on using the changeset viewer.