Changeset 357b5f5 in mainline for uspace/srv/net/tl/udp/udp.c
- Timestamp:
- 2011-01-23T20:09:13Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- fdb9982c
- Parents:
- cead2aa (diff), 7e36c8d (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/tl/udp/udp.c
rcead2aa r357b5f5 35 35 * @see udp.h 36 36 */ 37 38 #include "udp.h"39 #include "udp_header.h"40 #include "udp_module.h"41 37 42 38 #include <async.h> … … 65 61 #include <ip_interface.h> 66 62 #include <icmp_client.h> 67 #include <icmp_ interface.h>63 #include <icmp_remote.h> 68 64 #include <net_interface.h> 69 65 #include <socket_core.h> 70 66 #include <tl_common.h> 71 #include <tl_local.h> 72 #include <tl_interface.h> 67 #include <tl_remote.h> 68 #include <tl_skel.h> 69 70 #include "udp.h" 71 #include "udp_header.h" 73 72 74 73 /** UDP module name. */ 75 #define NAME "UDP protocol"74 #define NAME "udp" 76 75 77 76 /** Default UDP checksum computing. */ … … 92 91 /** UDP global data. */ 93 92 udp_globals_t udp_globals; 94 95 /** Initializes the UDP module.96 *97 * @param[in] client_connection The client connection processing function. The98 * module skeleton propagates its own one.99 * @return EOK on success.100 * @return ENOMEM if there is not enough memory left.101 */102 int udp_initialize(async_client_conn_t client_connection)103 {104 measured_string_t names[] = {105 {106 (char *) "UDP_CHECKSUM_COMPUTING",107 22108 },109 {110 (char *) "UDP_AUTOBINDING",111 15112 }113 };114 measured_string_t *configuration;115 size_t count = sizeof(names) / sizeof(measured_string_t);116 char *data;117 int rc;118 119 fibril_rwlock_initialize(&udp_globals.lock);120 fibril_rwlock_write_lock(&udp_globals.lock);121 122 udp_globals.icmp_phone = icmp_connect_module(SERVICE_ICMP,123 ICMP_CONNECT_TIMEOUT);124 125 udp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_UDP,126 SERVICE_UDP, client_connection);127 if (udp_globals.ip_phone < 0) {128 fibril_rwlock_write_unlock(&udp_globals.lock);129 return udp_globals.ip_phone;130 }131 132 /* Read default packet dimensions */133 rc = ip_packet_size_req(udp_globals.ip_phone, -1,134 &udp_globals.packet_dimension);135 if (rc != EOK) {136 fibril_rwlock_write_unlock(&udp_globals.lock);137 return rc;138 }139 140 rc = socket_ports_initialize(&udp_globals.sockets);141 if (rc != EOK) {142 fibril_rwlock_write_unlock(&udp_globals.lock);143 return rc;144 }145 146 rc = packet_dimensions_initialize(&udp_globals.dimensions);147 if (rc != EOK) {148 socket_ports_destroy(&udp_globals.sockets);149 fibril_rwlock_write_unlock(&udp_globals.lock);150 return rc;151 }152 153 udp_globals.packet_dimension.prefix += sizeof(udp_header_t);154 udp_globals.packet_dimension.content -= sizeof(udp_header_t);155 udp_globals.last_used_port = UDP_FREE_PORTS_START - 1;156 157 udp_globals.checksum_computing = NET_DEFAULT_UDP_CHECKSUM_COMPUTING;158 udp_globals.autobinding = NET_DEFAULT_UDP_AUTOBINDING;159 160 /* Get configuration */161 configuration = &names[0];162 rc = net_get_conf_req(udp_globals.net_phone, &configuration, count,163 &data);164 if (rc != EOK) {165 socket_ports_destroy(&udp_globals.sockets);166 fibril_rwlock_write_unlock(&udp_globals.lock);167 return rc;168 }169 170 if (configuration) {171 if (configuration[0].value)172 udp_globals.checksum_computing =173 (configuration[0].value[0] == 'y');174 175 if (configuration[1].value)176 udp_globals.autobinding =177 (configuration[1].value[0] == 'y');178 179 net_free_settings(configuration, data);180 }181 182 fibril_rwlock_write_unlock(&udp_globals.lock);183 return EOK;184 }185 93 186 94 /** Releases the packet and returns the result. … … 283 191 /* Find the destination socket */ 284 192 socket = socket_port_find(&udp_globals.sockets, 285 ntohs(header->destination_port),SOCKET_MAP_KEY_LISTENING, 0);193 ntohs(header->destination_port), (uint8_t *) SOCKET_MAP_KEY_LISTENING, 0); 286 194 if (!socket) { 287 195 if (tl_prepare_icmp_packet(udp_globals.net_phone, … … 393 301 fibril_rwlock_write_unlock(&udp_globals.lock); 394 302 async_msg_5(socket->phone, NET_SOCKET_RECEIVED, 395 ( ipcarg_t) socket->socket_id, packet_dimension->content, 0, 0,396 ( ipcarg_t) fragments);303 (sysarg_t) socket->socket_id, packet_dimension->content, 0, 0, 304 (sysarg_t) fragments); 397 305 398 306 return EOK; … … 424 332 425 333 return result; 334 } 335 336 /** Process IPC messages from the IP module 337 * 338 * @param[in] iid Message identifier. 339 * @param[in,out] icall Message parameters. 340 * 341 */ 342 static void udp_receiver(ipc_callid_t iid, ipc_call_t *icall) 343 { 344 packet_t *packet; 345 int rc; 346 347 while (true) { 348 switch (IPC_GET_IMETHOD(*icall)) { 349 case NET_TL_RECEIVED: 350 rc = packet_translate_remote(udp_globals.net_phone, &packet, 351 IPC_GET_PACKET(*icall)); 352 if (rc == EOK) 353 rc = udp_received_msg(IPC_GET_DEVICE(*icall), packet, 354 SERVICE_UDP, IPC_GET_ERROR(*icall)); 355 356 ipc_answer_0(iid, (sysarg_t) rc); 357 break; 358 default: 359 ipc_answer_0(iid, (sysarg_t) ENOTSUP); 360 } 361 362 iid = async_get_call(icall); 363 } 364 } 365 366 /** Initialize the UDP module. 367 * 368 * @param[in] net_phone Network module phone. 369 * 370 * @return EOK on success. 371 * @return ENOMEM if there is not enough memory left. 372 * 373 */ 374 int tl_initialize(int net_phone) 375 { 376 measured_string_t names[] = { 377 { 378 (uint8_t *) "UDP_CHECKSUM_COMPUTING", 379 22 380 }, 381 { 382 (uint8_t *) "UDP_AUTOBINDING", 383 15 384 } 385 }; 386 measured_string_t *configuration; 387 size_t count = sizeof(names) / sizeof(measured_string_t); 388 uint8_t *data; 389 390 fibril_rwlock_initialize(&udp_globals.lock); 391 fibril_rwlock_write_lock(&udp_globals.lock); 392 393 udp_globals.net_phone = net_phone; 394 395 udp_globals.icmp_phone = icmp_connect_module(ICMP_CONNECT_TIMEOUT); 396 397 udp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_UDP, 398 SERVICE_UDP, udp_receiver); 399 if (udp_globals.ip_phone < 0) { 400 fibril_rwlock_write_unlock(&udp_globals.lock); 401 return udp_globals.ip_phone; 402 } 403 404 /* Read default packet dimensions */ 405 int rc = ip_packet_size_req(udp_globals.ip_phone, -1, 406 &udp_globals.packet_dimension); 407 if (rc != EOK) { 408 fibril_rwlock_write_unlock(&udp_globals.lock); 409 return rc; 410 } 411 412 rc = socket_ports_initialize(&udp_globals.sockets); 413 if (rc != EOK) { 414 fibril_rwlock_write_unlock(&udp_globals.lock); 415 return rc; 416 } 417 418 rc = packet_dimensions_initialize(&udp_globals.dimensions); 419 if (rc != EOK) { 420 socket_ports_destroy(&udp_globals.sockets); 421 fibril_rwlock_write_unlock(&udp_globals.lock); 422 return rc; 423 } 424 425 udp_globals.packet_dimension.prefix += sizeof(udp_header_t); 426 udp_globals.packet_dimension.content -= sizeof(udp_header_t); 427 udp_globals.last_used_port = UDP_FREE_PORTS_START - 1; 428 429 udp_globals.checksum_computing = NET_DEFAULT_UDP_CHECKSUM_COMPUTING; 430 udp_globals.autobinding = NET_DEFAULT_UDP_AUTOBINDING; 431 432 /* Get configuration */ 433 configuration = &names[0]; 434 rc = net_get_conf_req(udp_globals.net_phone, &configuration, count, 435 &data); 436 if (rc != EOK) { 437 socket_ports_destroy(&udp_globals.sockets); 438 fibril_rwlock_write_unlock(&udp_globals.lock); 439 return rc; 440 } 441 442 if (configuration) { 443 if (configuration[0].value) 444 udp_globals.checksum_computing = 445 (configuration[0].value[0] == 'y'); 446 447 if (configuration[1].value) 448 udp_globals.autobinding = 449 (configuration[1].value[0] == 'y'); 450 451 net_free_settings(configuration, data); 452 } 453 454 fibril_rwlock_write_unlock(&udp_globals.lock); 455 return EOK; 426 456 } 427 457 … … 707 737 bool keep_on_going = true; 708 738 socket_cores_t local_sockets; 709 int app_phone = IPC_GET_PHONE( &call);739 int app_phone = IPC_GET_PHONE(call); 710 740 struct sockaddr *addr; 711 741 int socket_id; … … 713 743 size_t size; 714 744 ipc_call_t answer; 715 int answer_count;745 size_t answer_count; 716 746 packet_dimension_t *packet_dimension; 717 747 … … 742 772 743 773 /* Process the call */ 744 switch (IPC_GET_ METHOD(call)) {774 switch (IPC_GET_IMETHOD(call)) { 745 775 case IPC_M_PHONE_HUNGUP: 746 776 keep_on_going = false; … … 771 801 772 802 case NET_SOCKET_BIND: 773 res = data_receive((void **) &addr, &addrlen); 803 res = async_data_write_accept((void **) &addr, false, 804 0, 0, 0, &addrlen); 774 805 if (res != EOK) 775 806 break; … … 784 815 785 816 case NET_SOCKET_SENDTO: 786 res = data_receive((void **) &addr, &addrlen); 817 res = async_data_write_accept((void **) &addr, false, 818 0, 0, 0, &addrlen); 787 819 if (res != EOK) 788 820 break; … … 845 877 } 846 878 879 /** Per-connection initialization 880 * 881 */ 882 void tl_connection(void) 883 { 884 } 885 847 886 /** Processes the UDP message. 848 887 * … … 858 897 * @see IS_NET_UDP_MESSAGE() 859 898 */ 860 int udp_message_standalone(ipc_callid_t callid, ipc_call_t *call, 861 ipc_call_t *answer, int *answer_count) 862 { 863 packet_t *packet; 864 int rc; 865 899 int tl_message(ipc_callid_t callid, ipc_call_t *call, 900 ipc_call_t *answer, size_t *answer_count) 901 { 866 902 *answer_count = 0; 867 903 868 switch (IPC_GET_METHOD(*call)) { 869 case NET_TL_RECEIVED: 870 rc = packet_translate_remote(udp_globals.net_phone, &packet, 871 IPC_GET_PACKET(call)); 872 if (rc != EOK) 873 return rc; 874 return udp_received_msg(IPC_GET_DEVICE(call), packet, 875 SERVICE_UDP, IPC_GET_ERROR(call)); 904 switch (IPC_GET_IMETHOD(*call)) { 876 905 case IPC_M_CONNECT_TO_ME: 877 return udp_process_client_messages(callid, * 906 return udp_process_client_messages(callid, *call); 878 907 } 879 908 … … 881 910 } 882 911 883 /** Default thread for new connections.884 *885 * @param[in] iid The initial message identifier.886 * @param[in] icall The initial message call structure.887 */888 static void tl_client_connection(ipc_callid_t iid, ipc_call_t * icall)889 {890 /*891 * Accept the connection892 * - Answer the first IPC_M_CONNECT_ME_TO call.893 */894 ipc_answer_0(iid, EOK);895 896 while (true) {897 ipc_call_t answer;898 int answer_count;899 900 /* Clear the answer structure */901 refresh_answer(&answer, &answer_count);902 903 /* Fetch the next message */904 ipc_call_t call;905 ipc_callid_t callid = async_get_call(&call);906 907 /* Process the message */908 int res = tl_module_message_standalone(callid, &call, &answer,909 &answer_count);910 911 /*912 * End if told to either by the message or the processing913 * result.914 */915 if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) ||916 (res == EHANGUP))917 return;918 919 /* Answer the message */920 answer_call(callid, res, &answer, answer_count);921 }922 }923 924 /** Starts the module.925 *926 * @return EOK on success.927 * @return Other error codes as defined for each specific module928 * start function.929 */930 912 int main(int argc, char *argv[]) 931 913 { 932 int rc;933 934 914 /* Start the module */ 935 rc = tl_module_start_standalone(tl_client_connection); 936 return rc; 915 return tl_module_start(SERVICE_UDP); 937 916 } 938 917
Note:
See TracChangeset
for help on using the changeset viewer.