Ignore:
File:
1 edited

Legend:

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

    r8e3a65c r065d2d5  
    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{
     
    223107        measured_string_t names[] = {
    224108                {
    225                         str_dup("UDP_CHECKSUM_COMPUTING"),
     109                        (char *) "UDP_CHECKSUM_COMPUTING",
    226110                        22
    227111                },
    228112                {
    229                         str_dup("UDP_AUTOBINDING"),
     113                        (char *) "UDP_AUTOBINDING",
    230114                        15
    231115                }
     
    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);
     
    258142        udp_globals.last_used_port = UDP_FREE_PORTS_START - 1;
    259143
    260         // get configuration
    261144        udp_globals.checksum_computing = NET_DEFAULT_UDP_CHECKSUM_COMPUTING;
    262145        udp_globals.autobinding = NET_DEFAULT_UDP_AUTOBINDING;
     146
     147        // get configuration
    263148        configuration = &names[0];
    264149        ERROR_PROPAGATE(net_get_conf_req(udp_globals.net_phone, &configuration,
     
    280165}
    281166
    282 int
    283 udp_received_msg(device_id_t device_id, packet_t packet, services_t receiver,
    284     services_t error)
     167/** Releases the packet and returns the result.
     168 *
     169 * @param[in] packet    The packet queue to be released.
     170 * @param[in] result    The result to be returned.
     171 * @return              The result parameter.
     172 */
     173static int udp_release_and_return(packet_t packet, int result)
    285174{
    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 
     175        pq_release_remote(udp_globals.net_phone, packet_get_id(packet));
    293176        return result;
    294177}
    295178
    296 int udp_process_packet(device_id_t device_id, packet_t packet, services_t error)
     179/** Processes the received UDP packet queue.
     180 *
     181 * Notifies the destination socket application.
     182 * Releases the packet on error or sends an ICMP error notification.
     183 *
     184 * @param[in] device_id The receiving device identifier.
     185 * @param[in,out] packet The received packet queue.
     186 * @param[in] error     The packet error reporting service. Prefixes the
     187 *                      received packet.
     188 * @returns             EOK on success.
     189 * @returns             EINVAL if the packet is not valid.
     190 * @returns             EINVAL if the stored packet address is not the
     191 *                      an_addr_t.
     192 * @returns             EINVAL if the packet does not contain any data.
     193 * @returns             NO_DATA if the packet content is shorter than the user
     194 *                      datagram header.
     195 * @returns             ENOMEM if there is not enough memory left.
     196 * @returns             EADDRNOTAVAIL if the destination socket does not exist.
     197 * @returns             Other error codes as defined for the
     198 *                      ip_client_process_packet() function.
     199 */
     200static int
     201udp_process_packet(device_id_t device_id, packet_t packet, services_t error)
    297202{
    298203        ERROR_DECLARE;
     
    315220        packet_dimension_ref packet_dimension;
    316221
    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                 }
     222        switch (error) {
     223        case SERVICE_NONE:
     224                break;
     225        case SERVICE_ICMP:
     226                // ignore error
     227                // length = icmp_client_header_length(packet);
     228                // process error
     229                result = icmp_client_process_packet(packet, &type,
     230                    &code, NULL, NULL);
     231                if (result < 0)
     232                        return udp_release_and_return(packet, result);
     233                length = (size_t) result;
     234                if (ERROR_OCCURRED(packet_trim(packet, length, 0)))
     235                        return udp_release_and_return(packet,
     236                            ERROR_CODE);
     237                break;
     238        default:
     239                return udp_release_and_return(packet, ENOTSUP);
    335240        }
    336241
     
    374279
    375280        // compute header checksum if set
    376         if (header->checksum && (!error)) {
     281        if (header->checksum && !error) {
    377282                result = packet_get_addr(packet, (uint8_t **) &src,
    378283                    (uint8_t **) &dest);
    379                 if( result <= 0)
     284                if (result <= 0)
    380285                        return udp_release_and_return(packet, result);
    381286
     
    396301
    397302        do {
    398                 ++ fragments;
     303                fragments++;
    399304                length = packet_get_data_length(next_packet);
    400305                if (length <= 0)
     
    471376}
    472377
    473 int
    474 udp_message_standalone(ipc_callid_t callid, ipc_call_t * call,
    475     ipc_call_t * answer, int * answer_count)
     378/** Processes the received UDP packet queue.
     379 *
     380 * Is used as an entry point from the underlying IP module.
     381 * Locks the global lock and calls udp_process_packet() function.
     382 *
     383 * @param[in] device_id The receiving device identifier.
     384 * @param[in,out] packet The received packet queue.
     385 * @param receiver      The target service. Ignored parameter.
     386 * @param[in] error     The packet error reporting service. Prefixes the
     387 *                      received packet.
     388 * @returns             EOK on success.
     389 * @returns             Other error codes as defined for the
     390 *                      udp_process_packet() function.
     391 */
     392static int
     393udp_received_msg(device_id_t device_id, packet_t packet, services_t receiver,
     394    services_t error)
    476395{
    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;
     396        int result;
     397
     398        fibril_rwlock_write_lock(&udp_globals.lock);
     399        result = udp_process_packet(device_id, packet, error);
     400        if (result != EOK)
     401                fibril_rwlock_write_unlock(&udp_globals.lock);
     402
     403        return result;
    497404}
    498405
    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
     406/** Sends data from the socket to the remote address.
     407 *
     408 * Binds the socket to a free port if not already connected/bound.
     409 * Handles the NET_SOCKET_SENDTO message.
     410 * Supports AF_INET and AF_INET6 address families.
     411 *
     412 * @param[in,out] local_sockets The application local sockets.
     413 * @param[in] socket_id Socket identifier.
     414 * @param[in] addr      The destination address.
     415 * @param[in] addrlen   The address length.
     416 * @param[in] fragments The number of data fragments.
     417 * @param[out] data_fragment_size The data fragment size in bytes.
     418 * @param[in] flags     Various send flags.
     419 * @returns             EOK on success.
     420 * @returns             EAFNOTSUPPORT if the address family is not supported.
     421 * @returns             ENOTSOCK if the socket is not found.
     422 * @returns             EINVAL if the address is invalid.
     423 * @returns             ENOTCONN if the sending socket is not and cannot be
     424 *                      bound.
     425 * @returns             ENOMEM if there is not enough memory left.
     426 * @returns             Other error codes as defined for the
     427 *                      socket_read_packet_data() function.
     428 * @returns             Other error codes as defined for the
     429 *                      ip_client_prepare_packet() function.
     430 * @returns             Other error codes as defined for the ip_send_msg()
     431 *                      function.
     432 */
     433static int
    641434udp_sendto_message(socket_cores_ref local_sockets, int socket_id,
    642435    const struct sockaddr *addr, socklen_t addrlen, int fragments,
     
    725518        // prefix the udp header
    726519        header = PACKET_PREFIX(packet, udp_header_t);
    727         if(! header)
     520        if (!header)
    728521                return udp_release_and_return(packet, ENOMEM);
    729522
    730523        bzero(header, sizeof(*header));
    731524        // read the rest of the packet fragments
    732         for (index = 1; index < fragments; ++ index) {
     525        for (index = 1; index < fragments; index++) {
    733526                result = tl_socket_read_packet_data(udp_globals.net_phone,
    734527                    &next_packet, 0, packet_dimension, addr, addrlen);
     
    784577}
    785578
    786 int
     579/** Receives data to the socket.
     580 *
     581 * Handles the NET_SOCKET_RECVFROM message.
     582 * Replies the source address as well.
     583 *
     584 * @param[in] local_sockets The application local sockets.
     585 * @param[in] socket_id Socket identifier.
     586 * @param[in] flags     Various receive flags.
     587 * @param[out] addrlen  The source address length.
     588 * @returns             The number of bytes received.
     589 * @returns             ENOTSOCK if the socket is not found.
     590 * @returns             NO_DATA if there are no received packets or data.
     591 * @returns             ENOMEM if there is not enough memory left.
     592 * @returns             EINVAL if the received address is not an IP address.
     593 * @returns             Other error codes as defined for the packet_translate()
     594 *                      function.
     595 * @returns             Other error codes as defined for the data_reply()
     596 *                      function.
     597 */
     598static int
    787599udp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, int flags,
    788600    size_t *addrlen)
     
    830642
    831643        // send the source address
    832         ERROR_PROPAGATE(data_reply(addr, * addrlen));
     644        ERROR_PROPAGATE(data_reply(addr, *addrlen));
    833645
    834646        // trim the header
     
    846658}
    847659
    848 int udp_release_and_return(packet_t packet, int result)
     660/** Processes the socket client messages.
     661 *
     662 * Runs until the client module disconnects.
     663 *
     664 * @param[in] callid    The message identifier.
     665 * @param[in] call      The message parameters.
     666 * @returns             EOK on success.
     667 *
     668 * @see socket.h
     669 */
     670static int udp_process_client_messages(ipc_callid_t callid, ipc_call_t call)
    849671{
    850         pq_release_remote(udp_globals.net_phone, packet_get_id(packet));
    851         return result;
     672        int res;
     673        bool keep_on_going = true;
     674        socket_cores_t local_sockets;
     675        int app_phone = IPC_GET_PHONE(&call);
     676        struct sockaddr *addr;
     677        int socket_id;
     678        size_t addrlen;
     679        size_t size;
     680        ipc_call_t answer;
     681        int answer_count;
     682        packet_dimension_ref packet_dimension;
     683
     684        /*
     685         * Accept the connection
     686         *  - Answer the first IPC_M_CONNECT_TO_ME call.
     687         */
     688        res = EOK;
     689        answer_count = 0;
     690
     691        // The client connection is only in one fibril and therefore no
     692        // additional locks are needed.
     693
     694        socket_cores_initialize(&local_sockets);
     695
     696        while (keep_on_going) {
     697
     698                // answer the call
     699                answer_call(callid, res, &answer, answer_count);
     700
     701                // refresh data
     702                refresh_answer(&answer, &answer_count);
     703
     704                // get the next call
     705                callid = async_get_call(&call);
     706
     707                // process the call
     708                switch (IPC_GET_METHOD(call)) {
     709                case IPC_M_PHONE_HUNGUP:
     710                        keep_on_going = false;
     711                        res = EHANGUP;
     712                        break;
     713
     714                case NET_SOCKET:
     715                        socket_id = SOCKET_GET_SOCKET_ID(call);
     716                        res = socket_create(&local_sockets, app_phone, NULL,
     717                            &socket_id);
     718                        SOCKET_SET_SOCKET_ID(answer, socket_id);
     719
     720                        if (res != EOK)
     721                                break;
     722                       
     723                        if (tl_get_ip_packet_dimension(udp_globals.ip_phone,
     724                            &udp_globals.dimensions, DEVICE_INVALID_ID,
     725                            &packet_dimension) == EOK) {
     726                                SOCKET_SET_DATA_FRAGMENT_SIZE(answer,
     727                                    packet_dimension->content);
     728                        }
     729
     730//                      SOCKET_SET_DATA_FRAGMENT_SIZE(answer,
     731//                          MAX_UDP_FRAGMENT_SIZE);
     732                        SOCKET_SET_HEADER_SIZE(answer, UDP_HEADER_SIZE);
     733                        answer_count = 3;
     734                        break;
     735
     736                case NET_SOCKET_BIND:
     737                        res = data_receive((void **) &addr, &addrlen);
     738                        if (res != EOK)
     739                                break;
     740                        fibril_rwlock_write_lock(&udp_globals.lock);
     741                        res = socket_bind(&local_sockets, &udp_globals.sockets,
     742                            SOCKET_GET_SOCKET_ID(call), addr, addrlen,
     743                            UDP_FREE_PORTS_START, UDP_FREE_PORTS_END,
     744                            udp_globals.last_used_port);
     745                        fibril_rwlock_write_unlock(&udp_globals.lock);
     746                        free(addr);
     747                        break;
     748
     749                case NET_SOCKET_SENDTO:
     750                        res = data_receive((void **) &addr, &addrlen);
     751                        if (res != EOK)
     752                                break;
     753
     754                        fibril_rwlock_write_lock(&udp_globals.lock);
     755                        res = udp_sendto_message(&local_sockets,
     756                            SOCKET_GET_SOCKET_ID(call), addr, addrlen,
     757                            SOCKET_GET_DATA_FRAGMENTS(call), &size,
     758                            SOCKET_GET_FLAGS(call));
     759                        SOCKET_SET_DATA_FRAGMENT_SIZE(answer, size);
     760
     761                        if (res != EOK)
     762                                fibril_rwlock_write_unlock(&udp_globals.lock);
     763                        else
     764                                answer_count = 2;
     765                       
     766                        free(addr);
     767                        break;
     768
     769                case NET_SOCKET_RECVFROM:
     770                        fibril_rwlock_write_lock(&udp_globals.lock);
     771                        res = udp_recvfrom_message(&local_sockets,
     772                             SOCKET_GET_SOCKET_ID(call), SOCKET_GET_FLAGS(call),
     773                             &addrlen);
     774                        fibril_rwlock_write_unlock(&udp_globals.lock);
     775
     776                        if (res <= 0)
     777                                break;
     778
     779                        SOCKET_SET_READ_DATA_LENGTH(answer, res);
     780                        SOCKET_SET_ADDRESS_LENGTH(answer, addrlen);
     781                        answer_count = 3;
     782                        res = EOK;
     783                        break;
     784                       
     785                case NET_SOCKET_CLOSE:
     786                        fibril_rwlock_write_lock(&udp_globals.lock);
     787                        res = socket_destroy(udp_globals.net_phone,
     788                            SOCKET_GET_SOCKET_ID(call), &local_sockets,
     789                            &udp_globals.sockets, NULL);
     790                        fibril_rwlock_write_unlock(&udp_globals.lock);
     791                        break;
     792
     793                case NET_SOCKET_GETSOCKOPT:
     794                case NET_SOCKET_SETSOCKOPT:
     795                default:
     796                        res = ENOTSUP;
     797                        break;
     798                }
     799        }
     800
     801        // release the application phone
     802        ipc_hangup(app_phone);
     803
     804        // release all local sockets
     805        socket_cores_release(udp_globals.net_phone, &local_sockets,
     806            &udp_globals.sockets, NULL);
     807
     808        return res;
     809}
     810
     811/** Processes the UDP message.
     812 *
     813 * @param[in] callid    The message identifier.
     814 * @param[in] call      The message parameters.
     815 * @param[out] answer   The message answer parameters.
     816 * @param[out] answer_count The last parameter for the actual answer in the
     817 *                      answer parameter.
     818 * @returns             EOK on success.
     819 * @returns             ENOTSUP if the message is not known.
     820 *
     821 * @see udp_interface.h
     822 * @see IS_NET_UDP_MESSAGE()
     823 */
     824int
     825udp_message_standalone(ipc_callid_t callid, ipc_call_t *call,
     826    ipc_call_t *answer, int *answer_count)
     827{
     828        ERROR_DECLARE;
     829
     830        packet_t packet;
     831
     832        *answer_count = 0;
     833
     834        switch (IPC_GET_METHOD(*call)) {
     835        case NET_TL_RECEIVED:
     836                if (ERROR_NONE(packet_translate_remote(udp_globals.net_phone,
     837                    &packet, IPC_GET_PACKET(call)))) {
     838                        ERROR_CODE = udp_received_msg(IPC_GET_DEVICE(call),
     839                            packet, SERVICE_UDP, IPC_GET_ERROR(call));
     840                }
     841                return ERROR_CODE;
     842       
     843        case IPC_M_CONNECT_TO_ME:
     844                return udp_process_client_messages(callid, * call);
     845        }
     846
     847        return ENOTSUP;
    852848}
    853849
     
    882878               
    883879                /*
    884                  * End if said to either by the message or the processing result
     880                 * End if told to either by the message or the processing
     881                 * result.
    885882                 */
    886883                if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) ||
     
    895892/** Starts the module.
    896893 *
    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
     894 * @returns             EOK on success.
     895 * @returns             Other error codes as defined for each specific module
    903896 *                      start function.
    904897 */
Note: See TracChangeset for help on using the changeset viewer.