Changeset 457a6f5 in mainline
- Timestamp:
- 2010-11-02T22:30:14Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 065d2d5
- Parents:
- 89e57cee
- Location:
- uspace/srv/net/tl/udp
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/tl/udp/udp.c
r89e57cee r457a6f5 28 28 29 29 /** @addtogroup udp 30 * 30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * UDP module implementation. 35 * @see udp.h 36 */ 34 * UDP module implementation. 35 * @see udp.h 36 */ 37 38 #include "udp.h" 39 #include "udp_header.h" 40 #include "udp_module.h" 37 41 38 42 #include <async.h> … … 45 49 #include <ipc/tl.h> 46 50 #include <ipc/socket.h> 51 #include <adt/dynamic_fifo.h> 47 52 #include <errno.h> 48 53 #include <err.h> … … 55 60 #include <net/modules.h> 56 61 57 #include <adt/dynamic_fifo.h>58 62 #include <packet_client.h> 59 63 #include <packet_remote.h> … … 69 73 #include <tl_interface.h> 70 74 71 #include "udp.h"72 #include "udp_header.h"73 #include "udp_module.h"74 75 75 /** UDP module name. */ 76 76 #define NAME "UDP protocol" … … 91 91 #define UDP_FREE_PORTS_END 65535 92 92 93 /** Processes the received UDP packet queue. 94 * 95 * Is used as an entry point from the underlying IP module. 96 * Locks the global lock and calls udp_process_packet() function. 97 * 98 * @param[in] device_id The receiving device identifier. 99 * @param[in,out] packet The received packet queue. 100 * @param receiver The target service. Ignored parameter. 101 * @param[in] error The packet error reporting service. Prefixes the 102 * received packet. 103 * @returns EOK on success. 104 * @returns Other error codes as defined for the 105 * udp_process_packet() function. 106 */ 107 int 108 udp_received_msg(device_id_t device_id, packet_t packet, services_t receiver, 109 services_t error); 110 111 /** Processes the received UDP packet queue. 112 * 113 * Notifies the destination socket application. 114 * Releases the packet on error or sends an ICMP error notification. 115 * 116 * @param[in] device_id The receiving device identifier. 117 * @param[in,out] packet The received packet queue. 118 * @param[in] error The packet error reporting service. Prefixes the 119 * received packet. 120 * @returns EOK on success. 121 * @returns EINVAL if the packet is not valid. 122 * @returns EINVAL if the stored packet address is not the 123 * an_addr_t. 124 * @returns EINVAL if the packet does not contain any data. 125 * @returns NO_DATA if the packet content is shorter than the user 126 * datagram header. 127 * @returns ENOMEM if there is not enough memory left. 128 * @returns EADDRNOTAVAIL if the destination socket does not exist. 129 * @returns Other error codes as defined for the 130 * ip_client_process_packet() function. 131 */ 132 int 133 udp_process_packet(device_id_t device_id, packet_t packet, services_t error); 134 135 /** Releases the packet and returns the result. 136 * 137 * @param[in] packet The packet queue to be released. 138 * @param[in] result The result to be returned. 139 * @return The result parameter. 140 */ 141 int udp_release_and_return(packet_t packet, int result); 142 143 /** @name Socket messages processing functions 144 */ 145 /*@{*/ 146 147 /** Processes the socket client messages. 148 * 149 * Runs until the client module disconnects. 150 * 151 * @param[in] callid The message identifier. 152 * @param[in] call The message parameters. 153 * @returns EOK on success. 154 * @see socket.h 155 */ 156 int udp_process_client_messages(ipc_callid_t callid, ipc_call_t call); 157 158 /** Sends data from the socket to the remote address. 159 * 160 * Binds the socket to a free port if not already connected/bound. 161 * Handles the NET_SOCKET_SENDTO message. 162 * Supports AF_INET and AF_INET6 address families. 163 * 164 * @param[in,out] local_sockets The application local sockets. 165 * @param[in] socket_id Socket identifier. 166 * @param[in] addr The destination address. 167 * @param[in] addrlen The address length. 168 * @param[in] fragments The number of data fragments. 169 * @param[out] data_fragment_size The data fragment size in bytes. 170 * @param[in] flags Various send flags. 171 * @returns EOK on success. 172 * @returns EAFNOTSUPPORT if the address family is not supported. 173 * @returns ENOTSOCK if the socket is not found. 174 * @returns EINVAL if the address is invalid. 175 * @returns ENOTCONN if the sending socket is not and cannot be 176 * bound. 177 * @returns ENOMEM if there is not enough memory left. 178 * @returns Other error codes as defined for the 179 * socket_read_packet_data() function. 180 * @returns Other error codes as defined for the 181 * ip_client_prepare_packet() function. 182 * @returns Other error codes as defined for the ip_send_msg() 183 * function. 184 */ 185 int 186 udp_sendto_message(socket_cores_ref local_sockets, int socket_id, 187 const struct sockaddr * addr, socklen_t addrlen, int fragments, 188 size_t * data_fragment_size, int flags); 189 190 /** Receives data to the socket. 191 * 192 * Handles the NET_SOCKET_RECVFROM message. 193 * Replies the source address as well. 194 * 195 * @param[in] local_sockets The application local sockets. 196 * @param[in] socket_id Socket identifier. 197 * @param[in] flags Various receive flags. 198 * @param[out] addrlen The source address length. 199 * @returns The number of bytes received. 200 * @returns ENOTSOCK if the socket is not found. 201 * @returns NO_DATA if there are no received packets or data. 202 * @returns ENOMEM if there is not enough memory left. 203 * @returns EINVAL if the received address is not an IP address. 204 * @returns Other error codes as defined for the packet_translate() 205 * function. 206 * @returns Other error codes as defined for the data_reply() 207 * function. 208 */ 209 int 210 udp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, int flags, 211 size_t * addrlen); 212 213 /*@}*/ 214 215 /** UDP global data. 216 */ 93 /** UDP global data. */ 217 94 udp_globals_t udp_globals; 218 95 96 /** Initializes the UDP module. 97 * 98 * @param[in] client_connection The client connection processing function. The 99 * module skeleton propagates its own one. 100 * @returns EOK on success. 101 * @returns ENOMEM if there is not enough memory left. 102 */ 219 103 int udp_initialize(async_client_conn_t client_connection) 220 104 { … … 233 117 measured_string_ref configuration; 234 118 size_t count = sizeof(names) / sizeof(measured_string_t); 235 char * 119 char *data; 236 120 237 121 fibril_rwlock_initialize(&udp_globals.lock); … … 280 164 } 281 165 282 int 283 udp_received_msg(device_id_t device_id, packet_t packet, services_t receiver, 284 services_t error) 166 /** Releases the packet and returns the result. 167 * 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 static int udp_release_and_return(packet_t packet, int result) 285 173 { 286 int result; 287 288 fibril_rwlock_write_lock(&udp_globals.lock); 289 result = udp_process_packet(device_id, packet, error); 290 if (result != EOK) 291 fibril_rwlock_write_unlock(&udp_globals.lock); 292 174 pq_release_remote(udp_globals.net_phone, packet_get_id(packet)); 293 175 return result; 294 176 } 295 177 296 int udp_process_packet(device_id_t device_id, packet_t packet, services_t error) 178 /** Processes the received UDP packet queue. 179 * 180 * Notifies the destination socket application. 181 * Releases the packet on error or sends an ICMP error notification. 182 * 183 * @param[in] device_id The receiving device identifier. 184 * @param[in,out] packet The received packet queue. 185 * @param[in] error The packet error reporting service. Prefixes the 186 * received packet. 187 * @returns EOK on success. 188 * @returns EINVAL if the packet is not valid. 189 * @returns EINVAL if the stored packet address is not the 190 * an_addr_t. 191 * @returns EINVAL if the packet does not contain any data. 192 * @returns NO_DATA if the packet content is shorter than the user 193 * datagram header. 194 * @returns ENOMEM if there is not enough memory left. 195 * @returns EADDRNOTAVAIL if the destination socket does not exist. 196 * @returns Other error codes as defined for the 197 * ip_client_process_packet() function. 198 */ 199 static int 200 udp_process_packet(device_id_t device_id, packet_t packet, services_t error) 297 201 { 298 202 ERROR_DECLARE; … … 315 219 packet_dimension_ref packet_dimension; 316 220 317 if(error) {318 switch (error) {319 case SERVICE_ICMP:320 // ignore error321 // length = icmp_client_header_length(packet);322 // process error323 result = icmp_client_process_packet(packet, &type,324 &code, NULL, NULL);325 if (result < 0)326 return udp_release_and_return(packet, result);327 length = (size_t) result;328 if (ERROR_OCCURRED(packet_trim(packet, length, 0)))329 return udp_release_and_return(packet,330 ERROR_CODE);331 break;332 default:333 return udp_release_and_return(packet, ENOTSUP);334 }221 switch (error) { 222 case SERVICE_NONE: 223 break; 224 case SERVICE_ICMP: 225 // ignore error 226 // length = icmp_client_header_length(packet); 227 // process error 228 result = icmp_client_process_packet(packet, &type, 229 &code, NULL, NULL); 230 if (result < 0) 231 return udp_release_and_return(packet, result); 232 length = (size_t) result; 233 if (ERROR_OCCURRED(packet_trim(packet, length, 0))) 234 return udp_release_and_return(packet, 235 ERROR_CODE); 236 break; 237 default: 238 return udp_release_and_return(packet, ENOTSUP); 335 239 } 336 240 … … 374 278 375 279 // compute header checksum if set 376 if (header->checksum && (!error)) {280 if (header->checksum && !error) { 377 281 result = packet_get_addr(packet, (uint8_t **) &src, 378 282 (uint8_t **) &dest); 379 if (result <= 0)283 if (result <= 0) 380 284 return udp_release_and_return(packet, result); 381 285 … … 396 300 397 301 do { 398 ++ fragments;302 fragments++; 399 303 length = packet_get_data_length(next_packet); 400 304 if (length <= 0) … … 471 375 } 472 376 473 int 474 udp_message_standalone(ipc_callid_t callid, ipc_call_t * call, 475 ipc_call_t * answer, int * answer_count) 377 /** Processes the received UDP packet queue. 378 * 379 * Is used as an entry point from the underlying IP module. 380 * Locks the global lock and calls udp_process_packet() function. 381 * 382 * @param[in] device_id The receiving device identifier. 383 * @param[in,out] packet The received packet queue. 384 * @param receiver The target service. Ignored parameter. 385 * @param[in] error The packet error reporting service. Prefixes the 386 * received packet. 387 * @returns EOK on success. 388 * @returns Other error codes as defined for the 389 * udp_process_packet() function. 390 */ 391 static int 392 udp_received_msg(device_id_t device_id, packet_t packet, services_t receiver, 393 services_t error) 476 394 { 477 ERROR_DECLARE; 478 479 packet_t packet; 480 481 *answer_count = 0; 482 483 switch (IPC_GET_METHOD(*call)) { 484 case NET_TL_RECEIVED: 485 if (!ERROR_OCCURRED(packet_translate_remote( 486 udp_globals.net_phone, &packet, IPC_GET_PACKET(call)))) { 487 ERROR_CODE = udp_received_msg(IPC_GET_DEVICE(call), 488 packet, SERVICE_UDP, IPC_GET_ERROR(call)); 489 } 490 return ERROR_CODE; 491 492 case IPC_M_CONNECT_TO_ME: 493 return udp_process_client_messages(callid, * call); 494 } 495 496 return ENOTSUP; 395 int result; 396 397 fibril_rwlock_write_lock(&udp_globals.lock); 398 result = udp_process_packet(device_id, packet, error); 399 if (result != EOK) 400 fibril_rwlock_write_unlock(&udp_globals.lock); 401 402 return result; 497 403 } 498 404 499 int udp_process_client_messages(ipc_callid_t callid, ipc_call_t call) 500 { 501 int res; 502 bool keep_on_going = true; 503 socket_cores_t local_sockets; 504 int app_phone = IPC_GET_PHONE(&call); 505 struct sockaddr *addr; 506 int socket_id; 507 size_t addrlen; 508 size_t size; 509 ipc_call_t answer; 510 int answer_count; 511 packet_dimension_ref packet_dimension; 512 513 /* 514 * Accept the connection 515 * - Answer the first IPC_M_CONNECT_TO_ME call. 516 */ 517 res = EOK; 518 answer_count = 0; 519 520 // The client connection is only in one fibril and therefore no 521 // additional locks are needed. 522 523 socket_cores_initialize(&local_sockets); 524 525 while (keep_on_going) { 526 527 // answer the call 528 answer_call(callid, res, &answer, answer_count); 529 530 // refresh data 531 refresh_answer(&answer, &answer_count); 532 533 // get the next call 534 callid = async_get_call(&call); 535 536 // process the call 537 switch (IPC_GET_METHOD(call)) { 538 case IPC_M_PHONE_HUNGUP: 539 keep_on_going = false; 540 res = EHANGUP; 541 break; 542 543 case NET_SOCKET: 544 socket_id = SOCKET_GET_SOCKET_ID(call); 545 res = socket_create(&local_sockets, app_phone, NULL, 546 &socket_id); 547 SOCKET_SET_SOCKET_ID(answer, socket_id); 548 549 if (res != EOK) 550 break; 551 552 if (tl_get_ip_packet_dimension(udp_globals.ip_phone, 553 &udp_globals.dimensions, DEVICE_INVALID_ID, 554 &packet_dimension) == EOK) { 555 SOCKET_SET_DATA_FRAGMENT_SIZE(answer, 556 packet_dimension->content); 557 } 558 559 // SOCKET_SET_DATA_FRAGMENT_SIZE(answer, 560 // MAX_UDP_FRAGMENT_SIZE); 561 SOCKET_SET_HEADER_SIZE(answer, UDP_HEADER_SIZE); 562 answer_count = 3; 563 break; 564 565 case NET_SOCKET_BIND: 566 res = data_receive((void **) &addr, &addrlen); 567 if (res != EOK) 568 break; 569 fibril_rwlock_write_lock(&udp_globals.lock); 570 res = socket_bind(&local_sockets, &udp_globals.sockets, 571 SOCKET_GET_SOCKET_ID(call), addr, addrlen, 572 UDP_FREE_PORTS_START, UDP_FREE_PORTS_END, 573 udp_globals.last_used_port); 574 fibril_rwlock_write_unlock(&udp_globals.lock); 575 free(addr); 576 break; 577 578 case NET_SOCKET_SENDTO: 579 res = data_receive((void **) &addr, &addrlen); 580 if (res != EOK) 581 break; 582 583 fibril_rwlock_write_lock(&udp_globals.lock); 584 res = udp_sendto_message(&local_sockets, 585 SOCKET_GET_SOCKET_ID(call), addr, addrlen, 586 SOCKET_GET_DATA_FRAGMENTS(call), &size, 587 SOCKET_GET_FLAGS(call)); 588 SOCKET_SET_DATA_FRAGMENT_SIZE(answer, size); 589 590 if (res != EOK) 591 fibril_rwlock_write_unlock(&udp_globals.lock); 592 else 593 answer_count = 2; 594 595 free(addr); 596 break; 597 598 case NET_SOCKET_RECVFROM: 599 fibril_rwlock_write_lock(&udp_globals.lock); 600 res = udp_recvfrom_message(&local_sockets, 601 SOCKET_GET_SOCKET_ID(call), SOCKET_GET_FLAGS(call), 602 &addrlen); 603 fibril_rwlock_write_unlock(&udp_globals.lock); 604 605 if (res <= 0) 606 break; 607 608 SOCKET_SET_READ_DATA_LENGTH(answer, res); 609 SOCKET_SET_ADDRESS_LENGTH(answer, addrlen); 610 answer_count = 3; 611 res = EOK; 612 break; 613 614 case NET_SOCKET_CLOSE: 615 fibril_rwlock_write_lock(&udp_globals.lock); 616 res = socket_destroy(udp_globals.net_phone, 617 SOCKET_GET_SOCKET_ID(call), &local_sockets, 618 &udp_globals.sockets, NULL); 619 fibril_rwlock_write_unlock(&udp_globals.lock); 620 break; 621 622 case NET_SOCKET_GETSOCKOPT: 623 case NET_SOCKET_SETSOCKOPT: 624 default: 625 res = ENOTSUP; 626 break; 627 } 628 } 629 630 // release the application phone 631 ipc_hangup(app_phone); 632 633 // release all local sockets 634 socket_cores_release(udp_globals.net_phone, &local_sockets, 635 &udp_globals.sockets, NULL); 636 637 return res; 638 } 639 640 int 405 /** Sends data from the socket to the remote address. 406 * 407 * Binds the socket to a free port if not already connected/bound. 408 * Handles the NET_SOCKET_SENDTO message. 409 * Supports AF_INET and AF_INET6 address families. 410 * 411 * @param[in,out] local_sockets The application local sockets. 412 * @param[in] socket_id Socket identifier. 413 * @param[in] addr The destination address. 414 * @param[in] addrlen The address length. 415 * @param[in] fragments The number of data fragments. 416 * @param[out] data_fragment_size The data fragment size in bytes. 417 * @param[in] flags Various send flags. 418 * @returns EOK on success. 419 * @returns EAFNOTSUPPORT if the address family is not supported. 420 * @returns ENOTSOCK if the socket is not found. 421 * @returns EINVAL if the address is invalid. 422 * @returns ENOTCONN if the sending socket is not and cannot be 423 * bound. 424 * @returns ENOMEM if there is not enough memory left. 425 * @returns Other error codes as defined for the 426 * socket_read_packet_data() function. 427 * @returns Other error codes as defined for the 428 * ip_client_prepare_packet() function. 429 * @returns Other error codes as defined for the ip_send_msg() 430 * function. 431 */ 432 static int 641 433 udp_sendto_message(socket_cores_ref local_sockets, int socket_id, 642 434 const struct sockaddr *addr, socklen_t addrlen, int fragments, … … 725 517 // prefix the udp header 726 518 header = PACKET_PREFIX(packet, udp_header_t); 727 if (!header)519 if (!header) 728 520 return udp_release_and_return(packet, ENOMEM); 729 521 730 522 bzero(header, sizeof(*header)); 731 523 // read the rest of the packet fragments 732 for (index = 1; index < fragments; ++ index) {524 for (index = 1; index < fragments; index++) { 733 525 result = tl_socket_read_packet_data(udp_globals.net_phone, 734 526 &next_packet, 0, packet_dimension, addr, addrlen); … … 784 576 } 785 577 786 int 578 /** Receives data to the socket. 579 * 580 * Handles the NET_SOCKET_RECVFROM message. 581 * Replies the source address as well. 582 * 583 * @param[in] local_sockets The application local sockets. 584 * @param[in] socket_id Socket identifier. 585 * @param[in] flags Various receive flags. 586 * @param[out] addrlen The source address length. 587 * @returns The number of bytes received. 588 * @returns ENOTSOCK if the socket is not found. 589 * @returns NO_DATA if there are no received packets or data. 590 * @returns ENOMEM if there is not enough memory left. 591 * @returns EINVAL if the received address is not an IP address. 592 * @returns Other error codes as defined for the packet_translate() 593 * function. 594 * @returns Other error codes as defined for the data_reply() 595 * function. 596 */ 597 static int 787 598 udp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, int flags, 788 599 size_t *addrlen) … … 830 641 831 642 // send the source address 832 ERROR_PROPAGATE(data_reply(addr, * 643 ERROR_PROPAGATE(data_reply(addr, *addrlen)); 833 644 834 645 // trim the header … … 846 657 } 847 658 848 int udp_release_and_return(packet_t packet, int result) 659 /** Processes the socket client messages. 660 * 661 * Runs until the client module disconnects. 662 * 663 * @param[in] callid The message identifier. 664 * @param[in] call The message parameters. 665 * @returns EOK on success. 666 * 667 * @see socket.h 668 */ 669 static int udp_process_client_messages(ipc_callid_t callid, ipc_call_t call) 849 670 { 850 pq_release_remote(udp_globals.net_phone, packet_get_id(packet)); 851 return result; 671 int res; 672 bool keep_on_going = true; 673 socket_cores_t local_sockets; 674 int app_phone = IPC_GET_PHONE(&call); 675 struct sockaddr *addr; 676 int socket_id; 677 size_t addrlen; 678 size_t size; 679 ipc_call_t answer; 680 int answer_count; 681 packet_dimension_ref packet_dimension; 682 683 /* 684 * Accept the connection 685 * - Answer the first IPC_M_CONNECT_TO_ME call. 686 */ 687 res = EOK; 688 answer_count = 0; 689 690 // The client connection is only in one fibril and therefore no 691 // additional locks are needed. 692 693 socket_cores_initialize(&local_sockets); 694 695 while (keep_on_going) { 696 697 // answer the call 698 answer_call(callid, res, &answer, answer_count); 699 700 // refresh data 701 refresh_answer(&answer, &answer_count); 702 703 // get the next call 704 callid = async_get_call(&call); 705 706 // process the call 707 switch (IPC_GET_METHOD(call)) { 708 case IPC_M_PHONE_HUNGUP: 709 keep_on_going = false; 710 res = EHANGUP; 711 break; 712 713 case NET_SOCKET: 714 socket_id = SOCKET_GET_SOCKET_ID(call); 715 res = socket_create(&local_sockets, app_phone, NULL, 716 &socket_id); 717 SOCKET_SET_SOCKET_ID(answer, socket_id); 718 719 if (res != EOK) 720 break; 721 722 if (tl_get_ip_packet_dimension(udp_globals.ip_phone, 723 &udp_globals.dimensions, DEVICE_INVALID_ID, 724 &packet_dimension) == EOK) { 725 SOCKET_SET_DATA_FRAGMENT_SIZE(answer, 726 packet_dimension->content); 727 } 728 729 // SOCKET_SET_DATA_FRAGMENT_SIZE(answer, 730 // MAX_UDP_FRAGMENT_SIZE); 731 SOCKET_SET_HEADER_SIZE(answer, UDP_HEADER_SIZE); 732 answer_count = 3; 733 break; 734 735 case NET_SOCKET_BIND: 736 res = data_receive((void **) &addr, &addrlen); 737 if (res != EOK) 738 break; 739 fibril_rwlock_write_lock(&udp_globals.lock); 740 res = socket_bind(&local_sockets, &udp_globals.sockets, 741 SOCKET_GET_SOCKET_ID(call), addr, addrlen, 742 UDP_FREE_PORTS_START, UDP_FREE_PORTS_END, 743 udp_globals.last_used_port); 744 fibril_rwlock_write_unlock(&udp_globals.lock); 745 free(addr); 746 break; 747 748 case NET_SOCKET_SENDTO: 749 res = data_receive((void **) &addr, &addrlen); 750 if (res != EOK) 751 break; 752 753 fibril_rwlock_write_lock(&udp_globals.lock); 754 res = udp_sendto_message(&local_sockets, 755 SOCKET_GET_SOCKET_ID(call), addr, addrlen, 756 SOCKET_GET_DATA_FRAGMENTS(call), &size, 757 SOCKET_GET_FLAGS(call)); 758 SOCKET_SET_DATA_FRAGMENT_SIZE(answer, size); 759 760 if (res != EOK) 761 fibril_rwlock_write_unlock(&udp_globals.lock); 762 else 763 answer_count = 2; 764 765 free(addr); 766 break; 767 768 case NET_SOCKET_RECVFROM: 769 fibril_rwlock_write_lock(&udp_globals.lock); 770 res = udp_recvfrom_message(&local_sockets, 771 SOCKET_GET_SOCKET_ID(call), SOCKET_GET_FLAGS(call), 772 &addrlen); 773 fibril_rwlock_write_unlock(&udp_globals.lock); 774 775 if (res <= 0) 776 break; 777 778 SOCKET_SET_READ_DATA_LENGTH(answer, res); 779 SOCKET_SET_ADDRESS_LENGTH(answer, addrlen); 780 answer_count = 3; 781 res = EOK; 782 break; 783 784 case NET_SOCKET_CLOSE: 785 fibril_rwlock_write_lock(&udp_globals.lock); 786 res = socket_destroy(udp_globals.net_phone, 787 SOCKET_GET_SOCKET_ID(call), &local_sockets, 788 &udp_globals.sockets, NULL); 789 fibril_rwlock_write_unlock(&udp_globals.lock); 790 break; 791 792 case NET_SOCKET_GETSOCKOPT: 793 case NET_SOCKET_SETSOCKOPT: 794 default: 795 res = ENOTSUP; 796 break; 797 } 798 } 799 800 // release the application phone 801 ipc_hangup(app_phone); 802 803 // release all local sockets 804 socket_cores_release(udp_globals.net_phone, &local_sockets, 805 &udp_globals.sockets, NULL); 806 807 return res; 808 } 809 810 /** Processes the UDP message. 811 * 812 * @param[in] callid The message identifier. 813 * @param[in] call The message parameters. 814 * @param[out] answer The message answer parameters. 815 * @param[out] answer_count The last parameter for the actual answer in the 816 * answer parameter. 817 * @returns EOK on success. 818 * @returns ENOTSUP if the message is not known. 819 * 820 * @see udp_interface.h 821 * @see IS_NET_UDP_MESSAGE() 822 */ 823 int 824 udp_message_standalone(ipc_callid_t callid, ipc_call_t *call, 825 ipc_call_t *answer, int *answer_count) 826 { 827 ERROR_DECLARE; 828 829 packet_t packet; 830 831 *answer_count = 0; 832 833 switch (IPC_GET_METHOD(*call)) { 834 case NET_TL_RECEIVED: 835 if (ERROR_NONE(packet_translate_remote(udp_globals.net_phone, 836 &packet, IPC_GET_PACKET(call)))) { 837 ERROR_CODE = udp_received_msg(IPC_GET_DEVICE(call), 838 packet, SERVICE_UDP, IPC_GET_ERROR(call)); 839 } 840 return ERROR_CODE; 841 842 case IPC_M_CONNECT_TO_ME: 843 return udp_process_client_messages(callid, * call); 844 } 845 846 return ENOTSUP; 852 847 } 853 848 … … 882 877 883 878 /* 884 * End if said to either by the message or the processing result 879 * End if told to either by the message or the processing 880 * result. 885 881 */ 886 882 if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) || … … 895 891 /** Starts the module. 896 892 * 897 * @param argc The count of the command line arguments. Ignored 898 * parameter. 899 * @param argv The command line parameters. Ignored parameter. 900 * 901 * @returns EOK on success. 902 * @returns Other error codes as defined for each specific module 893 * @returns EOK on success. 894 * @returns Other error codes as defined for each specific module 903 895 * start function. 904 896 */ -
uspace/srv/net/tl/udp/udp.h
r89e57cee r457a6f5 28 28 29 29 /** @addtogroup udp 30 * 30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * 34 * UDP module. 35 35 */ 36 36 37 #ifndef __NET_UDP_H__38 #define __NET_UDP_H__37 #ifndef NET_UDP_H_ 38 #define NET_UDP_H_ 39 39 40 40 #include <fibril_synch.h> … … 43 43 44 44 /** Type definition of the UDP global data. 45 * 45 * @see udp_globals 46 46 */ 47 typedef struct udp_globals 47 typedef struct udp_globals udp_globals_t; 48 48 49 /** UDP global data. 50 */ 51 struct udp_globals{ 52 /** Networking module phone. 53 */ 49 /** UDP global data. */ 50 struct udp_globals { 51 /** Networking module phone. */ 54 52 int net_phone; 55 /** IP module phone. 56 */ 53 /** IP module phone. */ 57 54 int ip_phone; 58 /** ICMP module phone. 59 */ 55 /** ICMP module phone. */ 60 56 int icmp_phone; 61 /** Packet dimension. 62 */ 57 /** Packet dimension. */ 63 58 packet_dimension_t packet_dimension; 64 /** Indicates whether UDP checksum computing is enabled. 65 */ 59 /** Indicates whether UDP checksum computing is enabled. */ 66 60 int checksum_computing; 67 /** Indicates whether UDP autobnding on send is enabled. 68 */ 61 /** Indicates whether UDP autobnding on send is enabled. */ 69 62 int autobinding; 70 /** Last used free port. 71 */ 63 /** Last used free port. */ 72 64 int last_used_port; 73 /** Active sockets. 74 */ 65 /** Active sockets. */ 75 66 socket_ports_t sockets; 76 /** Device packet dimensions. 77 */ 67 /** Device packet dimensions. */ 78 68 packet_dimensions_t dimensions; 79 /** Safety lock. 80 */ 69 /** Safety lock. */ 81 70 fibril_rwlock_t lock; 82 71 }; … … 86 75 /** @} 87 76 */ 88 -
uspace/srv/net/tl/udp/udp_header.h
r89e57cee r457a6f5 28 28 29 29 /** @addtogroup udp 30 * 30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * 35 * Based on the RFC~768.34 * UDP header definition. 35 * Based on the RFC 768. 36 36 */ 37 37 38 #ifndef __NET_UDP_HEADER_H__39 #define __NET_UDP_HEADER_H__38 #ifndef NET_UDP_HEADER_H_ 39 #define NET_UDP_HEADER_H_ 40 40 41 41 #include <sys/types.h> 42 42 43 /** UDP header size in bytes. 44 */ 45 #define UDP_HEADER_SIZE sizeof(udp_header_t) 43 /** UDP header size in bytes. */ 44 #define UDP_HEADER_SIZE sizeof(udp_header_t) 46 45 47 46 /** Type definition of the user datagram header. 48 * 47 * @see udp_header 49 48 */ 50 typedef struct udp_header 49 typedef struct udp_header udp_header_t; 51 50 52 51 /** Type definition of the user datagram header pointer. 53 * 52 * @see udp_header 54 53 */ 55 typedef udp_header_t * 54 typedef udp_header_t *udp_header_ref; 56 55 57 /** User datagram header. 58 */ 59 struct udp_header{ 60 /** Source Port is an optional field, when meaningful, it indicates the port of the sending process, and may be assumed to be the port to which a reply should be addressed in the absence of any other information. 61 * If not used, a value of zero is inserted. 62 */ 56 /** User datagram header. */ 57 struct udp_header { 63 58 uint16_t source_port; 64 /** Destination port has a meaning within the context of a particular internet destination address.65 */66 59 uint16_t destination_port; 67 /** Length is the length in octets of this user datagram including this header and the data.68 * This means the minimum value of the length is eight.69 */70 60 uint16_t total_length; 71 /** Checksum is the 16-bit one's complement of the one's complement sum of a pseudo header of information from the IP header, the UDP header, and the data, padded with zero octets at the end (if necessary) to make a multiple of two octets.72 * The pseudo header conceptually prefixed to the UDP header contains the source address, the destination address, the protocol, and the UDP length.73 * This information gives protection against misrouted datagrams.74 * If the computed checksum is zero, it is transmitted as all ones (the equivalent in one's complement arithmetic).75 * An all zero transmitted checksum value means that the transmitter generated no checksum (for debugging or for higher level protocols that don't care).76 */77 61 uint16_t checksum; 78 62 } __attribute__ ((packed)); -
uspace/srv/net/tl/udp/udp_module.c
r89e57cee r457a6f5 28 28 29 29 /** @addtogroup udp 30 * 30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * UDP standalone module implementation. 35 * Contains skeleton module functions mapping. 36 * The functions are used by the module skeleton as module specific entry points. 37 * @see module.c 34 * UDP standalone module implementation. 35 * Contains skeleton module functions mapping. 36 * The functions are used by the module skeleton as module specific entry 37 * points. 38 * @see module.c 38 39 */ 40 41 #include "udp.h" 42 #include "udp_module.h" 39 43 40 44 #include <async.h> … … 46 50 #include <net/modules.h> 47 51 #include <net/packet.h> 52 48 53 #include <net_interface.h> 49 54 #include <tl_local.h> 50 55 51 #include "udp.h" 52 #include "udp_module.h" 56 /** UDP module global data. */ 57 extern udp_globals_t udp_globals; 53 58 54 /** UDP module global data. 55 */ 56 extern udp_globals_t udp_globals; 57 58 /** Starts the UDP module. 59 * Initializes the client connection serving function, initializes the module, registers the module service and starts the async manager, processing IPC messages in an infinite loop. 60 * @param[in] client_connection The client connection processing function. The module skeleton propagates its own one. 61 * @returns EOK on successful module termination. 62 * @returns Other error codes as defined for the udp_initialize() function. 63 * @returns Other error codes as defined for the REGISTER_ME() macro function. 64 */ 65 int tl_module_start_standalone(async_client_conn_t client_connection){ 59 int tl_module_start_standalone(async_client_conn_t client_connection) 60 { 66 61 ERROR_DECLARE; 67 62 … … 70 65 async_set_client_connection(client_connection); 71 66 udp_globals.net_phone = net_connect_module(); 72 if (udp_globals.net_phone < 0){67 if (udp_globals.net_phone < 0) 73 68 return udp_globals.net_phone; 74 } 69 75 70 ERROR_PROPAGATE(pm_init()); 76 if (ERROR_OCCURRED(udp_initialize(client_connection))77 || ERROR_OCCURRED(REGISTER_ME(SERVICE_UDP, &phonehash))){71 if (ERROR_OCCURRED(udp_initialize(client_connection)) || 72 ERROR_OCCURRED(REGISTER_ME(SERVICE_UDP, &phonehash))) { 78 73 pm_destroy(); 79 74 return ERROR_CODE; … … 86 81 } 87 82 88 /** Processes the UDP message. 89 * @param[in] callid The message identifier. 90 * @param[in] call The message parameters. 91 * @param[out] answer The message answer parameters. 92 * @param[out] answer_count The last parameter for the actual answer in the answer parameter. 93 * @returns EOK on success. 94 * @returns Other error codes as defined for the udp_message() function. 95 */ 96 int tl_module_message_standalone(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){ 83 int 84 tl_module_message_standalone(ipc_callid_t callid, ipc_call_t *call, 85 ipc_call_t *answer, int *answer_count) 86 { 97 87 return udp_message_standalone(callid, call, answer, answer_count); 98 88 } -
uspace/srv/net/tl/udp/udp_module.h
r89e57cee r457a6f5 28 28 29 29 /** @addtogroup udp 30 * 30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * 35 * 34 * UDP module functions. 35 * The functions are used as UDP module entry points. 36 36 */ 37 37 38 #ifndef __NET_UDP_MODULE_H__39 #define __NET_UDP_MODULE_H__38 #ifndef NET_UDP_MODULE_H_ 39 #define NET_UDP_MODULE_H_ 40 40 41 41 #include <async.h> 42 42 #include <ipc/ipc.h> 43 43 44 /** Initializes the UDP module. 45 * @param[in] client_connection The client connection processing function. The module skeleton propagates its own one. 46 * @returns EOK on success. 47 * @returns ENOMEM if there is not enough memory left. 48 */ 49 extern int udp_initialize(async_client_conn_t client_connection); 50 51 /** Processes the UDP message. 52 * @param[in] callid The message identifier. 53 * @param[in] call The message parameters. 54 * @param[out] answer The message answer parameters. 55 * @param[out] answer_count The last parameter for the actual answer in the answer parameter. 56 * @returns EOK on success. 57 * @returns ENOTSUP if the message is not known. 58 * @see udp_interface.h 59 * @see IS_NET_UDP_MESSAGE() 60 */ 61 extern int udp_message_standalone(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count); 44 extern int udp_initialize(async_client_conn_t); 45 extern int udp_message_standalone(ipc_callid_t, ipc_call_t *, ipc_call_t *, 46 int *); 62 47 63 48 #endif
Note:
See TracChangeset
for help on using the changeset viewer.