Changeset 457a6f5 in mainline for uspace/srv/net/tl/udp/udp.c


Ignore:
Timestamp:
2010-11-02T22:30:14Z (14 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
065d2d5
Parents:
89e57cee
Message:

Cleanup udp.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/net/tl/udp/udp.c

    r89e57cee r457a6f5  
    2828
    2929/** @addtogroup udp
    30  *  @{
     30 * @{
    3131 */
    3232
    3333/** @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"
    3741
    3842#include <async.h>
     
    4549#include <ipc/tl.h>
    4650#include <ipc/socket.h>
     51#include <adt/dynamic_fifo.h>
    4752#include <errno.h>
    4853#include <err.h>
     
    5560#include <net/modules.h>
    5661
    57 #include <adt/dynamic_fifo.h>
    5862#include <packet_client.h>
    5963#include <packet_remote.h>
     
    6973#include <tl_interface.h>
    7074
    71 #include "udp.h"
    72 #include "udp_header.h"
    73 #include "udp_module.h"
    74 
    7575/** UDP module name. */
    7676#define NAME    "UDP protocol"
     
    9191#define UDP_FREE_PORTS_END              65535
    9292
    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.  */
    21794udp_globals_t udp_globals;
    21895
     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 */
    219103int udp_initialize(async_client_conn_t client_connection)
    220104{
     
    233117        measured_string_ref configuration;
    234118        size_t count = sizeof(names) / sizeof(measured_string_t);
    235         char * data;
     119        char *data;
    236120
    237121        fibril_rwlock_initialize(&udp_globals.lock);
     
    280164}
    281165
    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 */
     172static int udp_release_and_return(packet_t packet, int result)
    285173{
    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));
    293175        return result;
    294176}
    295177
    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 */
     199static int
     200udp_process_packet(device_id_t device_id, packet_t packet, services_t error)
    297201{
    298202        ERROR_DECLARE;
     
    315219        packet_dimension_ref packet_dimension;
    316220
    317         if (error) {
    318                 switch (error) {
    319                 case SERVICE_ICMP:
    320                         // ignore error
    321                         // length = icmp_client_header_length(packet);
    322                         // process error
    323                         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);
    335239        }
    336240
     
    374278
    375279        // compute header checksum if set
    376         if (header->checksum && (!error)) {
     280        if (header->checksum && !error) {
    377281                result = packet_get_addr(packet, (uint8_t **) &src,
    378282                    (uint8_t **) &dest);
    379                 if( result <= 0)
     283                if (result <= 0)
    380284                        return udp_release_and_return(packet, result);
    381285
     
    396300
    397301        do {
    398                 ++ fragments;
     302                fragments++;
    399303                length = packet_get_data_length(next_packet);
    400304                if (length <= 0)
     
    471375}
    472376
    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 */
     391static int
     392udp_received_msg(device_id_t device_id, packet_t packet, services_t receiver,
     393    services_t error)
    476394{
    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;
    497403}
    498404
    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 */
     432static int
    641433udp_sendto_message(socket_cores_ref local_sockets, int socket_id,
    642434    const struct sockaddr *addr, socklen_t addrlen, int fragments,
     
    725517        // prefix the udp header
    726518        header = PACKET_PREFIX(packet, udp_header_t);
    727         if(! header)
     519        if (!header)
    728520                return udp_release_and_return(packet, ENOMEM);
    729521
    730522        bzero(header, sizeof(*header));
    731523        // read the rest of the packet fragments
    732         for (index = 1; index < fragments; ++ index) {
     524        for (index = 1; index < fragments; index++) {
    733525                result = tl_socket_read_packet_data(udp_globals.net_phone,
    734526                    &next_packet, 0, packet_dimension, addr, addrlen);
     
    784576}
    785577
    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 */
     597static int
    787598udp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, int flags,
    788599    size_t *addrlen)
     
    830641
    831642        // send the source address
    832         ERROR_PROPAGATE(data_reply(addr, * addrlen));
     643        ERROR_PROPAGATE(data_reply(addr, *addrlen));
    833644
    834645        // trim the header
     
    846657}
    847658
    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 */
     669static int udp_process_client_messages(ipc_callid_t callid, ipc_call_t call)
    849670{
    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 */
     823int
     824udp_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;
    852847}
    853848
     
    882877               
    883878                /*
    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.
    885881                 */
    886882                if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) ||
     
    895891/** Starts the module.
    896892 *
    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
    903895 *                      start function.
    904896 */
Note: See TracChangeset for help on using the changeset viewer.