Ignore:
File:
1 edited

Legend:

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

    rffa2c8ef r61bfc370  
    3636 */
    3737
     38#include "udp.h"
     39#include "udp_header.h"
     40#include "udp_module.h"
     41
    3842#include <async.h>
    3943#include <fibril_synch.h>
    4044#include <malloc.h>
    4145#include <stdio.h>
     46#include <ipc/ipc.h>
    4247#include <ipc/services.h>
    4348#include <ipc/net.h>
     
    6065#include <ip_interface.h>
    6166#include <icmp_client.h>
    62 #include <icmp_remote.h>
     67#include <icmp_interface.h>
    6368#include <net_interface.h>
    6469#include <socket_core.h>
    6570#include <tl_common.h>
    66 #include <tl_remote.h>
    67 #include <tl_skel.h>
    68 
    69 #include "udp.h"
    70 #include "udp_header.h"
     71#include <tl_local.h>
     72#include <tl_interface.h>
    7173
    7274/** UDP module name. */
    73 #define NAME  "udp"
     75#define NAME    "UDP protocol"
    7476
    7577/** Default UDP checksum computing. */
     
    9092/** UDP global data.  */
    9193udp_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                        (uint8_t *) "UDP_CHECKSUM_COMPUTING",
     107                        22
     108                },
     109                {
     110                        (uint8_t *) "UDP_AUTOBINDING",
     111                        15
     112                }
     113        };
     114        measured_string_t *configuration;
     115        size_t count = sizeof(names) / sizeof(measured_string_t);
     116        uint8_t *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}
    92185
    93186/** Releases the packet and returns the result.
     
    333426}
    334427
    335 /** Process IPC messages from the IP module
    336  *
    337  * @param[in]     iid   Message identifier.
    338  * @param[in,out] icall Message parameters.
    339  *
    340  */
    341 static void udp_receiver(ipc_callid_t iid, ipc_call_t *icall)
    342 {
    343         packet_t *packet;
    344         int rc;
    345        
    346         while (true) {
    347                 switch (IPC_GET_IMETHOD(*icall)) {
    348                 case NET_TL_RECEIVED:
    349                         rc = packet_translate_remote(udp_globals.net_phone, &packet,
    350                             IPC_GET_PACKET(*icall));
    351                         if (rc == EOK)
    352                                 rc = udp_received_msg(IPC_GET_DEVICE(*icall), packet,
    353                                     SERVICE_UDP, IPC_GET_ERROR(*icall));
    354                        
    355                         async_answer_0(iid, (sysarg_t) rc);
    356                         break;
    357                 default:
    358                         async_answer_0(iid, (sysarg_t) ENOTSUP);
    359                 }
    360                
    361                 iid = async_get_call(icall);
    362         }
    363 }
    364 
    365 /** Initialize the UDP module.
    366  *
    367  * @param[in] net_phone Network module phone.
    368  *
    369  * @return EOK on success.
    370  * @return ENOMEM if there is not enough memory left.
    371  *
    372  */
    373 int tl_initialize(int net_phone)
    374 {
    375         measured_string_t names[] = {
    376                 {
    377                         (uint8_t *) "UDP_CHECKSUM_COMPUTING",
    378                         22
    379                 },
    380                 {
    381                         (uint8_t *) "UDP_AUTOBINDING",
    382                         15
    383                 }
    384         };
    385         measured_string_t *configuration;
    386         size_t count = sizeof(names) / sizeof(measured_string_t);
    387         uint8_t *data;
    388        
    389         fibril_rwlock_initialize(&udp_globals.lock);
    390         fibril_rwlock_write_lock(&udp_globals.lock);
    391        
    392         udp_globals.net_phone = net_phone;
    393        
    394         udp_globals.icmp_phone = icmp_connect_module(ICMP_CONNECT_TIMEOUT);
    395        
    396         udp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_UDP,
    397             SERVICE_UDP, udp_receiver);
    398         if (udp_globals.ip_phone < 0) {
    399                 fibril_rwlock_write_unlock(&udp_globals.lock);
    400                 return udp_globals.ip_phone;
    401         }
    402        
    403         /* Read default packet dimensions */
    404         int rc = ip_packet_size_req(udp_globals.ip_phone, -1,
    405             &udp_globals.packet_dimension);
    406         if (rc != EOK) {
    407                 fibril_rwlock_write_unlock(&udp_globals.lock);
    408                 return rc;
    409         }
    410        
    411         rc = socket_ports_initialize(&udp_globals.sockets);
    412         if (rc != EOK) {
    413                 fibril_rwlock_write_unlock(&udp_globals.lock);
    414                 return rc;
    415         }
    416        
    417         rc = packet_dimensions_initialize(&udp_globals.dimensions);
    418         if (rc != EOK) {
    419                 socket_ports_destroy(&udp_globals.sockets);
    420                 fibril_rwlock_write_unlock(&udp_globals.lock);
    421                 return rc;
    422         }
    423        
    424         udp_globals.packet_dimension.prefix += sizeof(udp_header_t);
    425         udp_globals.packet_dimension.content -= sizeof(udp_header_t);
    426         udp_globals.last_used_port = UDP_FREE_PORTS_START - 1;
    427 
    428         udp_globals.checksum_computing = NET_DEFAULT_UDP_CHECKSUM_COMPUTING;
    429         udp_globals.autobinding = NET_DEFAULT_UDP_AUTOBINDING;
    430 
    431         /* Get configuration */
    432         configuration = &names[0];
    433         rc = net_get_conf_req(udp_globals.net_phone, &configuration, count,
    434             &data);
    435         if (rc != EOK) {
    436                 socket_ports_destroy(&udp_globals.sockets);
    437                 fibril_rwlock_write_unlock(&udp_globals.lock);
    438                 return rc;
    439         }
    440        
    441         if (configuration) {
    442                 if (configuration[0].value)
    443                         udp_globals.checksum_computing =
    444                             (configuration[0].value[0] == 'y');
    445                
    446                 if (configuration[1].value)
    447                         udp_globals.autobinding =
    448                             (configuration[1].value[0] == 'y');
    449 
    450                 net_free_settings(configuration, data);
    451         }
    452 
    453         fibril_rwlock_write_unlock(&udp_globals.lock);
    454         return EOK;
    455 }
    456 
    457428/** Sends data from the socket to the remote address.
    458429 *
     
    736707        bool keep_on_going = true;
    737708        socket_cores_t local_sockets;
    738         int app_phone = IPC_GET_PHONE(call);
     709        int app_phone = IPC_GET_PHONE(&call);
    739710        struct sockaddr *addr;
    740711        int socket_id;
     
    742713        size_t size;
    743714        ipc_call_t answer;
    744         size_t answer_count;
     715        int answer_count;
    745716        packet_dimension_t *packet_dimension;
    746717
     
    867838
    868839        /* Release the application phone */
    869         async_hangup(app_phone);
     840        ipc_hangup(app_phone);
    870841
    871842        /* Release all local sockets */
     
    874845
    875846        return res;
    876 }
    877 
    878 /** Per-connection initialization
    879  *
    880  */
    881 void tl_connection(void)
    882 {
    883847}
    884848
     
    896860 * @see IS_NET_UDP_MESSAGE()
    897861 */
    898 int tl_message(ipc_callid_t callid, ipc_call_t *call,
    899     ipc_call_t *answer, size_t *answer_count)
     862int udp_message_standalone(ipc_callid_t callid, ipc_call_t *call,
     863    ipc_call_t *answer, int *answer_count)
    900864{
     865        packet_t *packet;
     866        int rc;
     867
    901868        *answer_count = 0;
    902869
    903870        switch (IPC_GET_IMETHOD(*call)) {
     871        case NET_TL_RECEIVED:
     872                rc = packet_translate_remote(udp_globals.net_phone, &packet,
     873                    IPC_GET_PACKET(call));
     874                if (rc != EOK)
     875                        return rc;
     876                return udp_received_msg(IPC_GET_DEVICE(call), packet,
     877                    SERVICE_UDP, IPC_GET_ERROR(call));
    904878        case IPC_M_CONNECT_TO_ME:
    905                 return udp_process_client_messages(callid, *call);
     879                return udp_process_client_messages(callid, * call);
    906880        }
    907881
     
    909883}
    910884
     885/** Default thread for new connections.
     886 *
     887 * @param[in] iid       The initial message identifier.
     888 * @param[in] icall     The initial message call structure.
     889 */
     890static void tl_client_connection(ipc_callid_t iid, ipc_call_t * icall)
     891{
     892        /*
     893         * Accept the connection
     894         *  - Answer the first IPC_M_CONNECT_ME_TO call.
     895         */
     896        ipc_answer_0(iid, EOK);
     897       
     898        while (true) {
     899                ipc_call_t answer;
     900                int answer_count;
     901               
     902                /* Clear the answer structure */
     903                refresh_answer(&answer, &answer_count);
     904               
     905                /* Fetch the next message */
     906                ipc_call_t call;
     907                ipc_callid_t callid = async_get_call(&call);
     908               
     909                /* Process the message */
     910                int res = tl_module_message_standalone(callid, &call, &answer,
     911                    &answer_count);
     912               
     913                /*
     914                 * End if told to either by the message or the processing
     915                 * result.
     916                 */
     917                if ((IPC_GET_IMETHOD(call) == IPC_M_PHONE_HUNGUP) ||
     918                    (res == EHANGUP))
     919                        return;
     920               
     921                /* Answer the message */
     922                answer_call(callid, res, &answer, answer_count);
     923        }
     924}
     925
     926/** Starts the module.
     927 *
     928 * @return              EOK on success.
     929 * @return              Other error codes as defined for each specific module
     930 *                      start function.
     931 */
    911932int main(int argc, char *argv[])
    912933{
     934        int rc;
     935       
    913936        /* Start the module */
    914         return tl_module_start(SERVICE_UDP);
     937        rc = tl_module_start_standalone(tl_client_connection);
     938        return rc;
    915939}
    916940
Note: See TracChangeset for help on using the changeset viewer.