Ignore:
File:
1 edited

Legend:

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

    r065d2d5 r8e3a65c  
    2828
    2929/** @addtogroup udp
    30  * @{
     30 *  @{
    3131 */
    3232
    3333/** @file
    34  * UDP module implementation.
    35  * @see udp.h
    36  */
    37 
    38 #include "udp.h"
    39 #include "udp_header.h"
    40 #include "udp_module.h"
     34 *  UDP module implementation.
     35 *  @see udp.h
     36 */
    4137
    4238#include <async.h>
     
    4945#include <ipc/tl.h>
    5046#include <ipc/socket.h>
    51 #include <adt/dynamic_fifo.h>
    5247#include <errno.h>
    5348#include <err.h>
     
    6055#include <net/modules.h>
    6156
     57#include <adt/dynamic_fifo.h>
    6258#include <packet_client.h>
    6359#include <packet_remote.h>
     
    7369#include <tl_interface.h>
    7470
     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 /** UDP global data.  */
     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 */
     107int
     108udp_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 */
     132int
     133udp_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 */
     141int 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 */
     156int 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 */
     185int
     186udp_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 */
     209int
     210udp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, int flags,
     211    size_t * addrlen);
     212
     213/*@}*/
     214
     215/** UDP global data.
     216 */
    94217udp_globals_t udp_globals;
    95218
    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  */
    103219int udp_initialize(async_client_conn_t client_connection)
    104220{
     
    107223        measured_string_t names[] = {
    108224                {
    109                         (char *) "UDP_CHECKSUM_COMPUTING",
     225                        str_dup("UDP_CHECKSUM_COMPUTING"),
    110226                        22
    111227                },
    112228                {
    113                         (char *) "UDP_AUTOBINDING",
     229                        str_dup("UDP_AUTOBINDING"),
    114230                        15
    115231                }
     
    117233        measured_string_ref configuration;
    118234        size_t count = sizeof(names) / sizeof(measured_string_t);
    119         char *data;
     235        char * data;
    120236
    121237        fibril_rwlock_initialize(&udp_globals.lock);
     
    142258        udp_globals.last_used_port = UDP_FREE_PORTS_START - 1;
    143259
     260        // get configuration
    144261        udp_globals.checksum_computing = NET_DEFAULT_UDP_CHECKSUM_COMPUTING;
    145262        udp_globals.autobinding = NET_DEFAULT_UDP_AUTOBINDING;
    146 
    147         // get configuration
    148263        configuration = &names[0];
    149264        ERROR_PROPAGATE(net_get_conf_req(udp_globals.net_phone, &configuration,
     
    165280}
    166281
    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  */
    173 static int udp_release_and_return(packet_t packet, int result)
     282int
     283udp_received_msg(device_id_t device_id, packet_t packet, services_t receiver,
     284    services_t error)
    174285{
    175         pq_release_remote(udp_globals.net_phone, packet_get_id(packet));
     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
    176293        return result;
    177294}
    178295
    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  */
    200 static int
    201 udp_process_packet(device_id_t device_id, packet_t packet, services_t error)
     296int udp_process_packet(device_id_t device_id, packet_t packet, services_t error)
    202297{
    203298        ERROR_DECLARE;
     
    220315        packet_dimension_ref packet_dimension;
    221316
    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);
     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                }
    240335        }
    241336
     
    279374
    280375        // compute header checksum if set
    281         if (header->checksum && !error) {
     376        if (header->checksum && (!error)) {
    282377                result = packet_get_addr(packet, (uint8_t **) &src,
    283378                    (uint8_t **) &dest);
    284                 if (result <= 0)
     379                if( result <= 0)
    285380                        return udp_release_and_return(packet, result);
    286381
     
    301396
    302397        do {
    303                 fragments++;
     398                ++ fragments;
    304399                length = packet_get_data_length(next_packet);
    305400                if (length <= 0)
     
    376471}
    377472
    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  */
    392 static int
    393 udp_received_msg(device_id_t device_id, packet_t packet, services_t receiver,
    394     services_t error)
     473int
     474udp_message_standalone(ipc_callid_t callid, ipc_call_t * call,
     475    ipc_call_t * answer, int * answer_count)
    395476{
    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;
     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;
    404497}
    405498
    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  */
    433 static int
     499int 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
     640int
    434641udp_sendto_message(socket_cores_ref local_sockets, int socket_id,
    435642    const struct sockaddr *addr, socklen_t addrlen, int fragments,
     
    518725        // prefix the udp header
    519726        header = PACKET_PREFIX(packet, udp_header_t);
    520         if (!header)
     727        if(! header)
    521728                return udp_release_and_return(packet, ENOMEM);
    522729
    523730        bzero(header, sizeof(*header));
    524731        // read the rest of the packet fragments
    525         for (index = 1; index < fragments; index++) {
     732        for (index = 1; index < fragments; ++ index) {
    526733                result = tl_socket_read_packet_data(udp_globals.net_phone,
    527734                    &next_packet, 0, packet_dimension, addr, addrlen);
     
    577784}
    578785
    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  */
    598 static int
     786int
    599787udp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, int flags,
    600788    size_t *addrlen)
     
    642830
    643831        // send the source address
    644         ERROR_PROPAGATE(data_reply(addr, *addrlen));
     832        ERROR_PROPAGATE(data_reply(addr, * addrlen));
    645833
    646834        // trim the header
     
    658846}
    659847
    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  */
    670 static int udp_process_client_messages(ipc_callid_t callid, ipc_call_t call)
     848int udp_release_and_return(packet_t packet, int result)
    671849{
    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  */
    824 int
    825 udp_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;
     850        pq_release_remote(udp_globals.net_phone, packet_get_id(packet));
     851        return result;
    848852}
    849853
     
    878882               
    879883                /*
    880                  * End if told to either by the message or the processing
    881                  * result.
     884                 * End if said to either by the message or the processing result
    882885                 */
    883886                if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) ||
     
    892895/** Starts the module.
    893896 *
    894  * @returns             EOK on success.
    895  * @returns             Other error codes as defined for each specific module
     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
    896903 *                      start function.
    897904 */
Note: See TracChangeset for help on using the changeset viewer.