Ignore:
File:
1 edited

Legend:

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

    rf1938c6 r46d4d9f  
    3535 * @see udp.h
    3636 */
     37
     38#include "udp.h"
     39#include "udp_header.h"
     40#include "udp_module.h"
    3741
    3842#include <async.h>
     
    6165#include <ip_interface.h>
    6266#include <icmp_client.h>
    63 #include <icmp_remote.h>
     67#include <icmp_interface.h>
    6468#include <net_interface.h>
    6569#include <socket_core.h>
    6670#include <tl_common.h>
    67 #include <tl_remote.h>
    68 #include <tl_skel.h>
    69 
    70 #include "udp.h"
    71 #include "udp_header.h"
     71#include <tl_local.h>
     72#include <tl_interface.h>
    7273
    7374/** UDP module name. */
    74 #define NAME  "udp"
     75#define NAME    "UDP protocol"
    7576
    7677/** Default UDP checksum computing. */
     
    9192/** UDP global data.  */
    9293udp_globals_t udp_globals;
     94
     95/** Initializes the UDP module.
     96 *
     97 * @param[in] client_connection The client connection processing function. The
     98 *                      module skeleton propagates its own one.
     99 * @return              EOK on success.
     100 * @return              ENOMEM if there is not enough memory left.
     101 */
     102int udp_initialize(async_client_conn_t client_connection)
     103{
     104        measured_string_t names[] = {
     105                {
     106                        (char *) "UDP_CHECKSUM_COMPUTING",
     107                        22
     108                },
     109                {
     110                        (char *) "UDP_AUTOBINDING",
     111                        15
     112                }
     113        };
     114        measured_string_t *configuration;
     115        size_t count = sizeof(names) / sizeof(measured_string_t);
     116        char *data;
     117        int rc;
     118
     119        fibril_rwlock_initialize(&udp_globals.lock);
     120        fibril_rwlock_write_lock(&udp_globals.lock);
     121
     122        udp_globals.icmp_phone = icmp_connect_module(SERVICE_ICMP,
     123            ICMP_CONNECT_TIMEOUT);
     124       
     125        udp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_UDP,
     126            SERVICE_UDP, client_connection);
     127        if (udp_globals.ip_phone < 0) {
     128                fibril_rwlock_write_unlock(&udp_globals.lock);
     129                return udp_globals.ip_phone;
     130        }
     131
     132        /* Read default packet dimensions */
     133        rc = ip_packet_size_req(udp_globals.ip_phone, -1,
     134            &udp_globals.packet_dimension);
     135        if (rc != EOK) {
     136                fibril_rwlock_write_unlock(&udp_globals.lock);
     137                return rc;
     138        }
     139       
     140        rc = socket_ports_initialize(&udp_globals.sockets);
     141        if (rc != EOK) {
     142                fibril_rwlock_write_unlock(&udp_globals.lock);
     143                return rc;
     144        }
     145       
     146        rc = packet_dimensions_initialize(&udp_globals.dimensions);
     147        if (rc != EOK) {
     148                socket_ports_destroy(&udp_globals.sockets);
     149                fibril_rwlock_write_unlock(&udp_globals.lock);
     150                return rc;
     151        }
     152       
     153        udp_globals.packet_dimension.prefix += sizeof(udp_header_t);
     154        udp_globals.packet_dimension.content -= sizeof(udp_header_t);
     155        udp_globals.last_used_port = UDP_FREE_PORTS_START - 1;
     156
     157        udp_globals.checksum_computing = NET_DEFAULT_UDP_CHECKSUM_COMPUTING;
     158        udp_globals.autobinding = NET_DEFAULT_UDP_AUTOBINDING;
     159
     160        /* Get configuration */
     161        configuration = &names[0];
     162        rc = net_get_conf_req(udp_globals.net_phone, &configuration, count,
     163            &data);
     164        if (rc != EOK) {
     165                socket_ports_destroy(&udp_globals.sockets);
     166                fibril_rwlock_write_unlock(&udp_globals.lock);
     167                return rc;
     168        }
     169       
     170        if (configuration) {
     171                if (configuration[0].value)
     172                        udp_globals.checksum_computing =
     173                            (configuration[0].value[0] == 'y');
     174               
     175                if (configuration[1].value)
     176                        udp_globals.autobinding =
     177                            (configuration[1].value[0] == 'y');
     178
     179                net_free_settings(configuration, data);
     180        }
     181
     182        fibril_rwlock_write_unlock(&udp_globals.lock);
     183        return EOK;
     184}
    93185
    94186/** Releases the packet and returns the result.
     
    191283        /* Find the destination socket */
    192284        socket = socket_port_find(&udp_globals.sockets,
    193             ntohs(header->destination_port), (uint8_t *) SOCKET_MAP_KEY_LISTENING, 0);
     285        ntohs(header->destination_port), SOCKET_MAP_KEY_LISTENING, 0);
    194286        if (!socket) {
    195287                if (tl_prepare_icmp_packet(udp_globals.net_phone,
     
    301393        fibril_rwlock_write_unlock(&udp_globals.lock);
    302394        async_msg_5(socket->phone, NET_SOCKET_RECEIVED,
    303             (sysarg_t) socket->socket_id, packet_dimension->content, 0, 0,
    304             (sysarg_t) fragments);
     395            (ipcarg_t) socket->socket_id, packet_dimension->content, 0, 0,
     396            (ipcarg_t) fragments);
    305397
    306398        return EOK;
     
    332424
    333425        return result;
    334 }
    335 
    336 /** Process IPC messages from the IP module
    337  *
    338  * @param[in]     iid   Message identifier.
    339  * @param[in,out] icall Message parameters.
    340  *
    341  */
    342 static void udp_receiver(ipc_callid_t iid, ipc_call_t *icall)
    343 {
    344         packet_t *packet;
    345         int rc;
    346        
    347         while (true) {
    348                 switch (IPC_GET_IMETHOD(*icall)) {
    349                 case NET_TL_RECEIVED:
    350                         rc = packet_translate_remote(udp_globals.net_phone, &packet,
    351                             IPC_GET_PACKET(*icall));
    352                         if (rc == EOK)
    353                                 rc = udp_received_msg(IPC_GET_DEVICE(*icall), packet,
    354                                     SERVICE_UDP, IPC_GET_ERROR(*icall));
    355                        
    356                         ipc_answer_0(iid, (sysarg_t) rc);
    357                         break;
    358                 default:
    359                         ipc_answer_0(iid, (sysarg_t) ENOTSUP);
    360                 }
    361                
    362                 iid = async_get_call(icall);
    363         }
    364 }
    365 
    366 /** Initialize the UDP module.
    367  *
    368  * @param[in] net_phone Network module phone.
    369  *
    370  * @return EOK on success.
    371  * @return ENOMEM if there is not enough memory left.
    372  *
    373  */
    374 int tl_initialize(int net_phone)
    375 {
    376         measured_string_t names[] = {
    377                 {
    378                         (uint8_t *) "UDP_CHECKSUM_COMPUTING",
    379                         22
    380                 },
    381                 {
    382                         (uint8_t *) "UDP_AUTOBINDING",
    383                         15
    384                 }
    385         };
    386         measured_string_t *configuration;
    387         size_t count = sizeof(names) / sizeof(measured_string_t);
    388         uint8_t *data;
    389        
    390         fibril_rwlock_initialize(&udp_globals.lock);
    391         fibril_rwlock_write_lock(&udp_globals.lock);
    392        
    393         udp_globals.net_phone = net_phone;
    394        
    395         udp_globals.icmp_phone = icmp_connect_module(ICMP_CONNECT_TIMEOUT);
    396        
    397         udp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_UDP,
    398             SERVICE_UDP, udp_receiver);
    399         if (udp_globals.ip_phone < 0) {
    400                 fibril_rwlock_write_unlock(&udp_globals.lock);
    401                 return udp_globals.ip_phone;
    402         }
    403        
    404         /* Read default packet dimensions */
    405         int rc = ip_packet_size_req(udp_globals.ip_phone, -1,
    406             &udp_globals.packet_dimension);
    407         if (rc != EOK) {
    408                 fibril_rwlock_write_unlock(&udp_globals.lock);
    409                 return rc;
    410         }
    411        
    412         rc = socket_ports_initialize(&udp_globals.sockets);
    413         if (rc != EOK) {
    414                 fibril_rwlock_write_unlock(&udp_globals.lock);
    415                 return rc;
    416         }
    417        
    418         rc = packet_dimensions_initialize(&udp_globals.dimensions);
    419         if (rc != EOK) {
    420                 socket_ports_destroy(&udp_globals.sockets);
    421                 fibril_rwlock_write_unlock(&udp_globals.lock);
    422                 return rc;
    423         }
    424        
    425         udp_globals.packet_dimension.prefix += sizeof(udp_header_t);
    426         udp_globals.packet_dimension.content -= sizeof(udp_header_t);
    427         udp_globals.last_used_port = UDP_FREE_PORTS_START - 1;
    428 
    429         udp_globals.checksum_computing = NET_DEFAULT_UDP_CHECKSUM_COMPUTING;
    430         udp_globals.autobinding = NET_DEFAULT_UDP_AUTOBINDING;
    431 
    432         /* Get configuration */
    433         configuration = &names[0];
    434         rc = net_get_conf_req(udp_globals.net_phone, &configuration, count,
    435             &data);
    436         if (rc != EOK) {
    437                 socket_ports_destroy(&udp_globals.sockets);
    438                 fibril_rwlock_write_unlock(&udp_globals.lock);
    439                 return rc;
    440         }
    441        
    442         if (configuration) {
    443                 if (configuration[0].value)
    444                         udp_globals.checksum_computing =
    445                             (configuration[0].value[0] == 'y');
    446                
    447                 if (configuration[1].value)
    448                         udp_globals.autobinding =
    449                             (configuration[1].value[0] == 'y');
    450 
    451                 net_free_settings(configuration, data);
    452         }
    453 
    454         fibril_rwlock_write_unlock(&udp_globals.lock);
    455         return EOK;
    456426}
    457427
     
    737707        bool keep_on_going = true;
    738708        socket_cores_t local_sockets;
    739         int app_phone = IPC_GET_PHONE(call);
     709        int app_phone = IPC_GET_PHONE(&call);
    740710        struct sockaddr *addr;
    741711        int socket_id;
     
    743713        size_t size;
    744714        ipc_call_t answer;
    745         size_t answer_count;
     715        int answer_count;
    746716        packet_dimension_t *packet_dimension;
    747717
     
    772742
    773743                /* Process the call */
    774                 switch (IPC_GET_IMETHOD(call)) {
     744                switch (IPC_GET_METHOD(call)) {
    775745                case IPC_M_PHONE_HUNGUP:
    776746                        keep_on_going = false;
     
    801771
    802772                case NET_SOCKET_BIND:
    803                         res = async_data_write_accept((void **) &addr, false,
    804                             0, 0, 0, &addrlen);
     773                        res = data_receive((void **) &addr, &addrlen);
    805774                        if (res != EOK)
    806775                                break;
     
    815784
    816785                case NET_SOCKET_SENDTO:
    817                         res = async_data_write_accept((void **) &addr, false,
    818                             0, 0, 0, &addrlen);
     786                        res = data_receive((void **) &addr, &addrlen);
    819787                        if (res != EOK)
    820788                                break;
     
    877845}
    878846
    879 /** Per-connection initialization
    880  *
    881  */
    882 void tl_connection(void)
    883 {
    884 }
    885 
    886847/** Processes the UDP message.
    887848 *
     
    897858 * @see IS_NET_UDP_MESSAGE()
    898859 */
    899 int tl_message(ipc_callid_t callid, ipc_call_t *call,
    900     ipc_call_t *answer, size_t *answer_count)
     860int udp_message_standalone(ipc_callid_t callid, ipc_call_t *call,
     861    ipc_call_t *answer, int *answer_count)
    901862{
     863        packet_t *packet;
     864        int rc;
     865
    902866        *answer_count = 0;
    903867
    904         switch (IPC_GET_IMETHOD(*call)) {
     868        switch (IPC_GET_METHOD(*call)) {
     869        case NET_TL_RECEIVED:
     870                rc = packet_translate_remote(udp_globals.net_phone, &packet,
     871                    IPC_GET_PACKET(call));
     872                if (rc != EOK)
     873                        return rc;
     874                return udp_received_msg(IPC_GET_DEVICE(call), packet,
     875                    SERVICE_UDP, IPC_GET_ERROR(call));
    905876        case IPC_M_CONNECT_TO_ME:
    906                 return udp_process_client_messages(callid, *call);
     877                return udp_process_client_messages(callid, * call);
    907878        }
    908879
     
    910881}
    911882
     883/** Default thread for new connections.
     884 *
     885 * @param[in] iid       The initial message identifier.
     886 * @param[in] icall     The initial message call structure.
     887 */
     888static void tl_client_connection(ipc_callid_t iid, ipc_call_t * icall)
     889{
     890        /*
     891         * Accept the connection
     892         *  - Answer the first IPC_M_CONNECT_ME_TO call.
     893         */
     894        ipc_answer_0(iid, EOK);
     895       
     896        while (true) {
     897                ipc_call_t answer;
     898                int answer_count;
     899               
     900                /* Clear the answer structure */
     901                refresh_answer(&answer, &answer_count);
     902               
     903                /* Fetch the next message */
     904                ipc_call_t call;
     905                ipc_callid_t callid = async_get_call(&call);
     906               
     907                /* Process the message */
     908                int res = tl_module_message_standalone(callid, &call, &answer,
     909                    &answer_count);
     910               
     911                /*
     912                 * End if told to either by the message or the processing
     913                 * result.
     914                 */
     915                if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) ||
     916                    (res == EHANGUP))
     917                        return;
     918               
     919                /* Answer the message */
     920                answer_call(callid, res, &answer, answer_count);
     921        }
     922}
     923
     924/** Starts the module.
     925 *
     926 * @return              EOK on success.
     927 * @return              Other error codes as defined for each specific module
     928 *                      start function.
     929 */
    912930int main(int argc, char *argv[])
    913931{
     932        int rc;
     933       
    914934        /* Start the module */
    915         return tl_module_start(SERVICE_UDP);
     935        rc = tl_module_start_standalone(tl_client_connection);
     936        return rc;
    916937}
    917938
Note: See TracChangeset for help on using the changeset viewer.