Ignore:
File:
1 edited

Legend:

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

    r8e3a65c r14f1db0  
    4242#include <ipc/ipc.h>
    4343#include <ipc/services.h>
    44 #include <ipc/net.h>
    45 #include <ipc/tl.h>
    46 #include <ipc/socket.h>
    47 #include <errno.h>
    48 #include <err.h>
    49 
    50 #include <net/socket_codes.h>
    51 #include <net/ip_protocols.h>
    52 #include <net/in.h>
    53 #include <net/in6.h>
    54 #include <net/inet.h>
    55 #include <net/modules.h>
    56 
     44
     45#include <net_err.h>
     46#include <net_messages.h>
     47#include <net_modules.h>
    5748#include <adt/dynamic_fifo.h>
    58 #include <packet_client.h>
     49#include <packet/packet_client.h>
    5950#include <packet_remote.h>
    6051#include <net_checksum.h>
     52#include <in.h>
     53#include <in6.h>
     54#include <inet.h>
    6155#include <ip_client.h>
    6256#include <ip_interface.h>
     57#include <ip_protocols.h>
    6358#include <icmp_client.h>
    6459#include <icmp_interface.h>
    6560#include <net_interface.h>
     61#include <socket_codes.h>
     62#include <socket_errno.h>
    6663#include <socket_core.h>
     64#include <socket_messages.h>
    6765#include <tl_common.h>
    6866#include <tl_local.h>
    6967#include <tl_interface.h>
     68#include <tl_messages.h>
    7069
    7170#include "udp.h"
     
    7372#include "udp_module.h"
    7473
    75 /** UDP module name. */
     74/** UDP module name.
     75 */
    7676#define NAME    "UDP protocol"
    7777
    78 /** Default UDP checksum computing. */
     78/** Default UDP checksum computing.
     79 */
    7980#define NET_DEFAULT_UDP_CHECKSUM_COMPUTING      true
    8081
    81 /** Default UDP autobind when sending via unbound sockets. */
     82/** Default UDP autobind when sending via unbound sockets.
     83 */
    8284#define NET_DEFAULT_UDP_AUTOBINDING     true
    8385
    84 /** Maximum UDP fragment size. */
    85 #define MAX_UDP_FRAGMENT_SIZE           65535
    86 
    87 /** Free ports pool start. */
    88 #define UDP_FREE_PORTS_START            1025
    89 
    90 /** Free ports pool end. */
     86/** Maximum UDP fragment size.
     87 */
     88#define MAX_UDP_FRAGMENT_SIZE   65535
     89
     90/** Free ports pool start.
     91 */
     92#define UDP_FREE_PORTS_START    1025
     93
     94/** Free ports pool end.
     95 */
    9196#define UDP_FREE_PORTS_END              65535
    9297
    9398/** Processes the received UDP packet queue.
    94  *
    9599 *  Is used as an entry point from the underlying IP module.
    96100 *  Locks the global lock and calls udp_process_packet() function.
    97  *
    98101 *  @param[in] device_id The receiving device identifier.
    99102 *  @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);
     103 *  @param receiver The target service. Ignored parameter.
     104 *  @param[in] error The packet error reporting service. Prefixes the received packet.
     105 *  @returns EOK on success.
     106 *  @returns Other error codes as defined for the udp_process_packet() function.
     107 */
     108int udp_received_msg(device_id_t device_id, packet_t packet, services_t receiver, services_t error);
    110109
    111110/** Processes the received UDP packet queue.
    112  *
    113111 *  Notifies the destination socket application.
    114  *  Releases the packet on error or sends an ICMP error notification.
    115  *
     112 *  Releases the packet on error or sends an ICMP error notification..
    116113 *  @param[in] device_id The receiving device identifier.
    117114 *  @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);
     115 *  @param[in] error The packet error reporting service. Prefixes the received packet.
     116 *  @returns EOK on success.
     117 *  @returns EINVAL if the packet is not valid.
     118 *  @returns EINVAL if the stored packet address is not the an_addr_t.
     119 *  @returns EINVAL if the packet does not contain any data.
     120 *  @returns NO_DATA if the packet content is shorter than the user datagram header.
     121 *  @returns ENOMEM if there is not enough memory left.
     122 *  @returns EADDRNOTAVAIL if the destination socket does not exist.
     123 *  @returns Other error codes as defined for the ip_client_process_packet() function.
     124 */
     125int udp_process_packet(device_id_t device_id, packet_t packet, services_t error);
    134126
    135127/** 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.
     128 *  @param[in] packet The packet queue to be released.
     129 *  @param[in] result The result to be returned.
     130 *  @return The result parameter.
    140131 */
    141132int udp_release_and_return(packet_t packet, int result);
     
    146137
    147138/** Processes the socket client messages.
    148  *
    149139 *  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
     140 *  @param[in] callid The message identifier.
     141 *  @param[in] call The message parameters.
     142 *  @returns EOK on success.
     143 *  @see socket.h
    155144 */
    156145int udp_process_client_messages(ipc_callid_t callid, ipc_call_t call);
    157146
    158147/** Sends data from the socket to the remote address.
    159  *
    160148 *  Binds the socket to a free port if not already connected/bound.
    161149 *  Handles the NET_SOCKET_SENDTO message.
    162150 *  Supports AF_INET and AF_INET6 address families.
    163  *
    164151 *  @param[in,out] local_sockets The application local sockets.
    165152 *  @param[in] socket_id Socket identifier.
    166  *  @param[in] addr     The destination address.
    167  *  @param[in] addrlen  The address length.
     153 *  @param[in] addr The destination address.
     154 *  @param[in] addrlen The address length.
    168155 *  @param[in] fragments The number of data fragments.
    169156 *  @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);
     157 *  @param[in] flags Various send flags.
     158 *  @returns EOK on success.
     159 *  @returns EAFNOTSUPPORT if the address family is not supported.
     160 *  @returns ENOTSOCK if the socket is not found.
     161 *  @returns EINVAL if the address is invalid.
     162 *  @returns ENOTCONN if the sending socket is not and cannot be bound.
     163 *  @returns ENOMEM if there is not enough memory left.
     164 *  @returns Other error codes as defined for the socket_read_packet_data() function.
     165 *  @returns Other error codes as defined for the ip_client_prepare_packet() function.
     166 *  @returns Other error codes as defined for the ip_send_msg() function.
     167 */
     168int udp_sendto_message(socket_cores_ref local_sockets, int socket_id, const struct sockaddr * addr, socklen_t addrlen, int fragments, size_t * data_fragment_size, int flags);
    189169
    190170/** Receives data to the socket.
    191  *
    192171 *  Handles the NET_SOCKET_RECVFROM message.
    193172 *  Replies the source address as well.
    194  *
    195173 *  @param[in] local_sockets The application local sockets.
    196174 *  @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);
     175 *  @param[in] flags Various receive flags.
     176 *  @param[out] addrlen The source address length.
     177 *  @returns The number of bytes received.
     178 *  @returns ENOTSOCK if the socket is not found.
     179 *  @returns NO_DATA if there are no received packets or data.
     180 *  @returns ENOMEM if there is not enough memory left.
     181 *  @returns EINVAL if the received address is not an IP address.
     182 *  @returns Other error codes as defined for the packet_translate() function.
     183 *  @returns Other error codes as defined for the data_reply() function.
     184 */
     185int udp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, int flags, size_t * addrlen);
    212186
    213187/*@}*/
     
    215189/** UDP global data.
    216190 */
    217 udp_globals_t udp_globals;
    218 
    219 int udp_initialize(async_client_conn_t client_connection)
    220 {
     191udp_globals_t   udp_globals;
     192
     193int udp_initialize(async_client_conn_t client_connection){
    221194        ERROR_DECLARE;
    222195
    223         measured_string_t names[] = {
    224                 {
    225                         str_dup("UDP_CHECKSUM_COMPUTING"),
    226                         22
    227                 },
    228                 {
    229                         str_dup("UDP_AUTOBINDING"),
    230                         15
    231                 }
    232         };
     196        measured_string_t names[] = {{str_dup("UDP_CHECKSUM_COMPUTING"), 22}, {str_dup("UDP_AUTOBINDING"), 15}};
    233197        measured_string_ref configuration;
    234198        size_t count = sizeof(names) / sizeof(measured_string_t);
     
    237201        fibril_rwlock_initialize(&udp_globals.lock);
    238202        fibril_rwlock_write_lock(&udp_globals.lock);
    239 
    240         udp_globals.icmp_phone = icmp_connect_module(SERVICE_ICMP,
    241             ICMP_CONNECT_TIMEOUT);
    242         udp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_UDP,
    243             SERVICE_UDP, client_connection);
    244         if (udp_globals.ip_phone < 0)
     203        udp_globals.icmp_phone = icmp_connect_module(SERVICE_ICMP, ICMP_CONNECT_TIMEOUT);
     204        udp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_UDP, SERVICE_UDP, client_connection, udp_received_msg);
     205        if(udp_globals.ip_phone < 0){
    245206                return udp_globals.ip_phone;
    246 
     207        }
    247208        // read default packet dimensions
    248         ERROR_PROPAGATE(ip_packet_size_req(udp_globals.ip_phone, -1,
    249             &udp_globals.packet_dimension));
     209        ERROR_PROPAGATE(ip_packet_size_req(udp_globals.ip_phone, -1, &udp_globals.packet_dimension));
    250210        ERROR_PROPAGATE(socket_ports_initialize(&udp_globals.sockets));
    251         if (ERROR_OCCURRED(packet_dimensions_initialize(
    252             &udp_globals.dimensions))) {
     211        if(ERROR_OCCURRED(packet_dimensions_initialize(&udp_globals.dimensions))){
    253212                socket_ports_destroy(&udp_globals.sockets);
    254213                return ERROR_CODE;
     
    257216        udp_globals.packet_dimension.content -= sizeof(udp_header_t);
    258217        udp_globals.last_used_port = UDP_FREE_PORTS_START - 1;
    259 
    260218        // get configuration
    261219        udp_globals.checksum_computing = NET_DEFAULT_UDP_CHECKSUM_COMPUTING;
    262220        udp_globals.autobinding = NET_DEFAULT_UDP_AUTOBINDING;
    263221        configuration = &names[0];
    264         ERROR_PROPAGATE(net_get_conf_req(udp_globals.net_phone, &configuration,
    265             count, &data));
    266         if (configuration) {
    267                 if (configuration[0].value)
    268                         udp_globals.checksum_computing =
    269                             (configuration[0].value[0] == 'y');
    270                
    271                 if (configuration[1].value)
    272                         udp_globals.autobinding =
    273                             (configuration[1].value[0] == 'y');
    274 
     222        ERROR_PROPAGATE(net_get_conf_req(udp_globals.net_phone, &configuration, count, &data));
     223        if(configuration){
     224                if(configuration[0].value){
     225                        udp_globals.checksum_computing = (configuration[0].value[0] == 'y');
     226                }
     227                if(configuration[1].value){
     228                        udp_globals.autobinding = (configuration[1].value[0] == 'y');
     229                }
    275230                net_free_settings(configuration, data);
    276231        }
    277 
    278232        fibril_rwlock_write_unlock(&udp_globals.lock);
    279233        return EOK;
    280234}
    281235
    282 int
    283 udp_received_msg(device_id_t device_id, packet_t packet, services_t receiver,
    284     services_t error)
    285 {
     236int udp_received_msg(device_id_t device_id, packet_t packet, services_t receiver, services_t error){
    286237        int result;
    287238
    288239        fibril_rwlock_write_lock(&udp_globals.lock);
    289240        result = udp_process_packet(device_id, packet, error);
    290         if (result != EOK)
     241        if(result != EOK){
    291242                fibril_rwlock_write_unlock(&udp_globals.lock);
     243        }
    292244
    293245        return result;
    294246}
    295247
    296 int udp_process_packet(device_id_t device_id, packet_t packet, services_t error)
    297 {
     248int udp_process_packet(device_id_t device_id, packet_t packet, services_t error){
    298249        ERROR_DECLARE;
    299250
     
    311262        icmp_code_t code;
    312263        void *ip_header;
    313         struct sockaddr *src;
    314         struct sockaddr *dest;
     264        struct sockaddr * src;
     265        struct sockaddr * dest;
    315266        packet_dimension_ref packet_dimension;
    316267
    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                 }
    335         }
    336 
     268        if(error){
     269                switch(error){
     270                        case SERVICE_ICMP:
     271                                // ignore error
     272                                // length = icmp_client_header_length(packet);
     273                                // process error
     274                                result = icmp_client_process_packet(packet, &type, &code, NULL, NULL);
     275                                if(result < 0){
     276                                        return udp_release_and_return(packet, result);
     277                                }
     278                                length = (size_t) result;
     279                                if(ERROR_OCCURRED(packet_trim(packet, length, 0))){
     280                                        return udp_release_and_return(packet, ERROR_CODE);
     281                                }
     282                                break;
     283                        default:
     284                                return udp_release_and_return(packet, ENOTSUP);
     285                }
     286        }
    337287        // TODO process received ipopts?
    338288        result = ip_client_process_packet(packet, NULL, NULL, NULL, NULL, NULL);
    339         if (result < 0)
     289        if(result < 0){
    340290                return udp_release_and_return(packet, result);
     291        }
    341292        offset = (size_t) result;
    342293
    343294        length = packet_get_data_length(packet);
    344         if (length <= 0)
     295        if(length <= 0){
    345296                return udp_release_and_return(packet, EINVAL);
    346         if (length < UDP_HEADER_SIZE + offset)
     297        }
     298        if(length < UDP_HEADER_SIZE + offset){
    347299                return udp_release_and_return(packet, NO_DATA);
     300        }
    348301
    349302        // trim all but UDP header
    350         if (ERROR_OCCURRED(packet_trim(packet, offset, 0)))
     303        if(ERROR_OCCURRED(packet_trim(packet, offset, 0))){
    351304                return udp_release_and_return(packet, ERROR_CODE);
     305        }
    352306
    353307        // get udp header
    354308        header = (udp_header_ref) packet_get_data(packet);
    355         if (!header)
     309        if(! header){
    356310                return udp_release_and_return(packet, NO_DATA);
    357 
     311        }
    358312        // find the destination socket
    359         socket = socket_port_find(&udp_globals.sockets,
    360         ntohs(header->destination_port), SOCKET_MAP_KEY_LISTENING, 0);
    361         if (!socket) {
    362                 if (tl_prepare_icmp_packet(udp_globals.net_phone,
    363                     udp_globals.icmp_phone, packet, error) == EOK) {
    364                         icmp_destination_unreachable_msg(udp_globals.icmp_phone,
    365                             ICMP_PORT_UNREACH, 0, packet);
     313        socket = socket_port_find(&udp_globals.sockets, ntohs(header->destination_port), SOCKET_MAP_KEY_LISTENING, 0);
     314        if(! socket){
     315                if(tl_prepare_icmp_packet(udp_globals.net_phone, udp_globals.icmp_phone, packet, error) == EOK){
     316                        icmp_destination_unreachable_msg(udp_globals.icmp_phone, ICMP_PORT_UNREACH, 0, packet);
    366317                }
    367318                return EADDRNOTAVAIL;
     
    372323        fragments = 0;
    373324        total_length = ntohs(header->total_length);
    374 
    375325        // compute header checksum if set
    376         if (header->checksum && (!error)) {
    377                 result = packet_get_addr(packet, (uint8_t **) &src,
    378                     (uint8_t **) &dest);
    379                 if( result <= 0)
     326        if(header->checksum && (! error)){
     327                result = packet_get_addr(packet, (uint8_t **) &src, (uint8_t **) &dest);
     328                if(result <= 0){
    380329                        return udp_release_and_return(packet, result);
    381 
    382                 if (ERROR_OCCURRED(ip_client_get_pseudo_header(IPPROTO_UDP,
    383                     src, result, dest, result, total_length, &ip_header,
    384                     &length))) {
     330                }
     331                if(ERROR_OCCURRED(ip_client_get_pseudo_header(IPPROTO_UDP, src, result, dest, result, total_length, &ip_header, &length))){
    385332                        return udp_release_and_return(packet, ERROR_CODE);
    386                 } else {
     333                }else{
    387334                        checksum = compute_checksum(0, ip_header, length);
    388                         // the udp header checksum will be added with the first
    389                         // fragment later
     335                        // the udp header checksum will be added with the first fragment later
    390336                        free(ip_header);
    391337                }
    392         } else {
     338        }else{
    393339                header->checksum = 0;
    394340                checksum = 0;
    395341        }
    396342
    397         do {
     343        do{
    398344                ++ fragments;
    399345                length = packet_get_data_length(next_packet);
    400                 if (length <= 0)
     346                if(length <= 0){
    401347                        return udp_release_and_return(packet, NO_DATA);
    402 
    403                 if (total_length < length) {
    404                         if (ERROR_OCCURRED(packet_trim(next_packet, 0,
    405                             length - total_length))) {
    406                                 return udp_release_and_return(packet,
    407                                     ERROR_CODE);
     348                }
     349                if(total_length < length){
     350                        if(ERROR_OCCURRED(packet_trim(next_packet, 0, length - total_length))){
     351                                return udp_release_and_return(packet, ERROR_CODE);
    408352                        }
    409 
    410353                        // add partial checksum if set
    411                         if (header->checksum) {
    412                                 checksum = compute_checksum(checksum,
    413                                     packet_get_data(packet),
    414                                     packet_get_data_length(packet));
     354                        if(header->checksum){
     355                                checksum = compute_checksum(checksum, packet_get_data(packet), packet_get_data_length(packet));
    415356                        }
    416 
    417357                        // relese the rest of the packet fragments
    418358                        tmp_packet = pq_next(next_packet);
    419                         while (tmp_packet) {
     359                        while(tmp_packet){
    420360                                next_packet = pq_detach(tmp_packet);
    421                                 pq_release_remote(udp_globals.net_phone,
    422                                     packet_get_id(tmp_packet));
     361                                pq_release_remote(udp_globals.net_phone, packet_get_id(tmp_packet));
    423362                                tmp_packet = next_packet;
    424363                        }
    425 
    426364                        // exit the loop
    427365                        break;
    428366                }
    429367                total_length -= length;
    430 
    431368                // add partial checksum if set
    432                 if (header->checksum) {
    433                         checksum = compute_checksum(checksum,
    434                             packet_get_data(packet),
    435                             packet_get_data_length(packet));
    436                 }
    437 
    438         } while ((next_packet = pq_next(next_packet)) && (total_length > 0));
     369                if(header->checksum){
     370                        checksum = compute_checksum(checksum, packet_get_data(packet), packet_get_data_length(packet));
     371                }
     372        }while((next_packet = pq_next(next_packet)) && (total_length > 0));
    439373
    440374        // check checksum
    441         if (header->checksum) {
    442                 if (flip_checksum(compact_checksum(checksum)) !=
    443                     IP_CHECKSUM_ZERO) {
    444                         if (tl_prepare_icmp_packet(udp_globals.net_phone,
    445                             udp_globals.icmp_phone, packet, error) == EOK) {
     375        if(header->checksum){
     376                if(flip_checksum(compact_checksum(checksum)) != IP_CHECKSUM_ZERO){
     377                        if(tl_prepare_icmp_packet(udp_globals.net_phone, udp_globals.icmp_phone, packet, error) == EOK){
    446378                                // checksum error ICMP
    447                                 icmp_parameter_problem_msg(
    448                                     udp_globals.icmp_phone, ICMP_PARAM_POINTER,
    449                                     ((size_t) ((void *) &header->checksum)) -
    450                                     ((size_t) ((void *) header)), packet);
     379                                icmp_parameter_problem_msg(udp_globals.icmp_phone, ICMP_PARAM_POINTER, ((size_t) ((void *) &header->checksum)) - ((size_t) ((void *) header)), packet);
    451380                        }
    452381                        return EINVAL;
     
    455384
    456385        // queue the received packet
    457         if (ERROR_OCCURRED(dyn_fifo_push(&socket->received,
    458             packet_get_id(packet), SOCKET_MAX_RECEIVED_SIZE)) ||
    459             ERROR_OCCURRED(tl_get_ip_packet_dimension(udp_globals.ip_phone,
    460             &udp_globals.dimensions, device_id, &packet_dimension))) {
     386        if(ERROR_OCCURRED(dyn_fifo_push(&socket->received, packet_get_id(packet), SOCKET_MAX_RECEIVED_SIZE))
     387            || ERROR_OCCURRED(tl_get_ip_packet_dimension(udp_globals.ip_phone, &udp_globals.dimensions, device_id, &packet_dimension))){
    461388                return udp_release_and_return(packet, ERROR_CODE);
    462389        }
     
    464391        // notify the destination socket
    465392        fibril_rwlock_write_unlock(&udp_globals.lock);
    466         async_msg_5(socket->phone, NET_SOCKET_RECEIVED,
    467             (ipcarg_t) socket->socket_id, packet_dimension->content, 0, 0,
    468             (ipcarg_t) fragments);
    469 
     393        async_msg_5(socket->phone, NET_SOCKET_RECEIVED, (ipcarg_t) socket->socket_id, packet_dimension->content, 0, 0, (ipcarg_t) fragments);
    470394        return EOK;
    471395}
    472396
    473 int
    474 udp_message_standalone(ipc_callid_t callid, ipc_call_t * call,
    475     ipc_call_t * answer, int * answer_count)
    476 {
     397int udp_message_standalone(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
    477398        ERROR_DECLARE;
    478399
     
    480401
    481402        *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 
     403        switch(IPC_GET_METHOD(*call)){
     404                case NET_TL_RECEIVED:
     405                        if(! ERROR_OCCURRED(packet_translate_remote(udp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){
     406                                ERROR_CODE = udp_received_msg(IPC_GET_DEVICE(call), packet, SERVICE_UDP, IPC_GET_ERROR(call));
     407                        }
     408                        return ERROR_CODE;
     409                case IPC_M_CONNECT_TO_ME:
     410                        return udp_process_client_messages(callid, * call);
     411        }
    496412        return ENOTSUP;
    497413}
    498414
    499 int udp_process_client_messages(ipc_callid_t callid, ipc_call_t call)
    500 {
     415int udp_process_client_messages(ipc_callid_t callid, ipc_call_t call){
    501416        int res;
    502417        bool keep_on_going = true;
    503418        socket_cores_t local_sockets;
    504419        int app_phone = IPC_GET_PHONE(&call);
    505         struct sockaddr *addr;
     420        struct sockaddr * addr;
    506421        int socket_id;
    507422        size_t addrlen;
     
    518433        answer_count = 0;
    519434
    520         // The client connection is only in one fibril and therefore no
    521         // additional locks are needed.
     435        // The client connection is only in one fibril and therefore no additional locks are needed.
    522436
    523437        socket_cores_initialize(&local_sockets);
    524438
    525         while (keep_on_going) {
     439        while(keep_on_going){
    526440
    527441                // answer the call
     
    535449
    536450                // 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)
     451                switch(IPC_GET_METHOD(call)){
     452                        case IPC_M_PHONE_HUNGUP:
     453                                keep_on_going = false;
     454                                res = EHANGUP;
    550455                                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)
     456                        case NET_SOCKET:
     457                                socket_id = SOCKET_GET_SOCKET_ID(call);
     458                                res = socket_create(&local_sockets, app_phone, NULL, &socket_id);
     459                                SOCKET_SET_SOCKET_ID(answer, socket_id);
     460
     461                                if(res == EOK){
     462                                        if (tl_get_ip_packet_dimension(udp_globals.ip_phone, &udp_globals.dimensions, DEVICE_INVALID_ID, &packet_dimension) == EOK){
     463                                                SOCKET_SET_DATA_FRAGMENT_SIZE(answer, packet_dimension->content);
     464                                        }
     465//                                      SOCKET_SET_DATA_FRAGMENT_SIZE(answer, MAX_UDP_FRAGMENT_SIZE);
     466                                        SOCKET_SET_HEADER_SIZE(answer, UDP_HEADER_SIZE);
     467                                        answer_count = 3;
     468                                }
    568469                                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)
     470                        case NET_SOCKET_BIND:
     471                                res = data_receive((void **) &addr, &addrlen);
     472                                if(res == EOK){
     473                                        fibril_rwlock_write_lock(&udp_globals.lock);
     474                                        res = socket_bind(&local_sockets, &udp_globals.sockets, SOCKET_GET_SOCKET_ID(call), addr, addrlen, UDP_FREE_PORTS_START, UDP_FREE_PORTS_END, udp_globals.last_used_port);
     475                                        fibril_rwlock_write_unlock(&udp_globals.lock);
     476                                        free(addr);
     477                                }
    581478                                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)
     479                        case NET_SOCKET_SENDTO:
     480                                res = data_receive((void **) &addr, &addrlen);
     481                                if(res == EOK){
     482                                        fibril_rwlock_write_lock(&udp_globals.lock);
     483                                        res = udp_sendto_message(&local_sockets, SOCKET_GET_SOCKET_ID(call), addr, addrlen, SOCKET_GET_DATA_FRAGMENTS(call), &size, SOCKET_GET_FLAGS(call));
     484                                        SOCKET_SET_DATA_FRAGMENT_SIZE(answer, size);
     485                                        if(res != EOK){
     486                                                fibril_rwlock_write_unlock(&udp_globals.lock);
     487                                        }else{
     488                                                answer_count = 2;
     489                                        }
     490                                        free(addr);
     491                                }
     492                                break;
     493                        case NET_SOCKET_RECVFROM:
     494                                fibril_rwlock_write_lock(&udp_globals.lock);
     495                                res = udp_recvfrom_message(&local_sockets, SOCKET_GET_SOCKET_ID(call), SOCKET_GET_FLAGS(call), &addrlen);
    591496                                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)
     497                                if(res > 0){
     498                                        SOCKET_SET_READ_DATA_LENGTH(answer, res);
     499                                        SOCKET_SET_ADDRESS_LENGTH(answer, addrlen);
     500                                        answer_count = 3;
     501                                        res = EOK;
     502                                }
    606503                                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;
     504                        case NET_SOCKET_CLOSE:
     505                                fibril_rwlock_write_lock(&udp_globals.lock);
     506                                res = socket_destroy(udp_globals.net_phone, SOCKET_GET_SOCKET_ID(call), &local_sockets, &udp_globals.sockets, NULL);
     507                                fibril_rwlock_write_unlock(&udp_globals.lock);
     508                                break;
     509                        case NET_SOCKET_GETSOCKOPT:
     510                        case NET_SOCKET_SETSOCKOPT:
     511                        default:
     512                                res = ENOTSUP;
     513                                break;
    627514                }
    628515        }
     
    632519
    633520        // release all local sockets
    634         socket_cores_release(udp_globals.net_phone, &local_sockets,
    635             &udp_globals.sockets, NULL);
     521        socket_cores_release(udp_globals.net_phone, &local_sockets, &udp_globals.sockets, NULL);
    636522
    637523        return res;
    638524}
    639525
    640 int
    641 udp_sendto_message(socket_cores_ref local_sockets, int socket_id,
    642     const struct sockaddr *addr, socklen_t addrlen, int fragments,
    643     size_t *data_fragment_size, int flags)
    644 {
     526int udp_sendto_message(socket_cores_ref local_sockets, int socket_id, const struct sockaddr * addr, socklen_t addrlen, int fragments, size_t * data_fragment_size, int flags){
    645527        ERROR_DECLARE;
    646528
     
    662544
    663545        socket = socket_cores_find(local_sockets, socket_id);
    664         if (!socket)
     546        if(! socket){
    665547                return ENOTSOCK;
    666 
    667         if ((socket->port <= 0) && udp_globals.autobinding) {
     548        }
     549
     550        if((socket->port <= 0) && udp_globals.autobinding){
    668551                // bind the socket to a random free port if not bound
    669 //              do {
     552//              do{
    670553                        // try to find a free port
    671554//                      fibril_rwlock_read_unlock(&udp_globals.lock);
    672555//                      fibril_rwlock_write_lock(&udp_globals.lock);
    673556                        // might be changed in the meantime
    674 //                      if (socket->port <= 0) {
    675                                 if (ERROR_OCCURRED(socket_bind_free_port(
    676                                     &udp_globals.sockets, socket,
    677                                     UDP_FREE_PORTS_START, UDP_FREE_PORTS_END,
    678                                     udp_globals.last_used_port))) {
    679 //                                      fibril_rwlock_write_unlock(
    680 //                                          &udp_globals.lock);
    681 //                                      fibril_rwlock_read_lock(
    682 //                                          &udp_globals.lock);
     557//                      if(socket->port <= 0){
     558                                if(ERROR_OCCURRED(socket_bind_free_port(&udp_globals.sockets, socket, UDP_FREE_PORTS_START, UDP_FREE_PORTS_END, udp_globals.last_used_port))){
     559//                                      fibril_rwlock_write_unlock(&udp_globals.lock);
     560//                                      fibril_rwlock_read_lock(&udp_globals.lock);
    683561                                        return ERROR_CODE;
    684562                                }
    685                                 // set the next port as the search starting port
    686                                 // number
     563                                // set the next port as the search starting port number
    687564                                udp_globals.last_used_port = socket->port;
    688565//                      }
     
    690567//                      fibril_rwlock_read_lock(&udp_globals.lock);
    691568                        // might be changed in the meantime
    692 //              } while (socket->port <= 0);
    693         }
    694 
    695         if (udp_globals.checksum_computing) {
    696                 if (ERROR_OCCURRED(ip_get_route_req(udp_globals.ip_phone,
    697                     IPPROTO_UDP, addr, addrlen, &device_id, &ip_header,
    698                     &headerlen))) {
     569//              }while(socket->port <= 0);
     570        }
     571
     572        if(udp_globals.checksum_computing){
     573                if(ERROR_OCCURRED(ip_get_route_req(udp_globals.ip_phone, IPPROTO_UDP, addr, addrlen, &device_id, &ip_header, &headerlen))){
    699574                        return udp_release_and_return(packet, ERROR_CODE);
    700575                }
    701576                // get the device packet dimension
    702 //              ERROR_PROPAGATE(tl_get_ip_packet_dimension(udp_globals.ip_phone,
    703 //                  &udp_globals.dimensions, device_id, &packet_dimension));
    704         }
    705 //      } else {
     577//              ERROR_PROPAGATE(tl_get_ip_packet_dimension(udp_globals.ip_phone, &udp_globals.dimensions, device_id, &packet_dimension));
     578        }
     579//      }else{
    706580                // do not ask all the time
    707                 ERROR_PROPAGATE(ip_packet_size_req(udp_globals.ip_phone, -1,
    708                     &udp_globals.packet_dimension));
     581                ERROR_PROPAGATE(ip_packet_size_req(udp_globals.ip_phone, -1, &udp_globals.packet_dimension));
    709582                packet_dimension = &udp_globals.packet_dimension;
    710583//      }
    711584
    712585        // read the first packet fragment
    713         result = tl_socket_read_packet_data(udp_globals.net_phone, &packet,
    714             UDP_HEADER_SIZE, packet_dimension, addr, addrlen);
    715         if (result < 0)
     586        result = tl_socket_read_packet_data(udp_globals.net_phone, &packet, UDP_HEADER_SIZE, packet_dimension, addr, addrlen);
     587        if(result < 0){
    716588                return result;
    717 
     589        }
    718590        total_length = (size_t) result;
    719         if (udp_globals.checksum_computing)
    720                 checksum = compute_checksum(0, packet_get_data(packet),
    721                     packet_get_data_length(packet));
    722         else
     591        if(udp_globals.checksum_computing){
     592                checksum = compute_checksum(0, packet_get_data(packet), packet_get_data_length(packet));
     593        }else{
    723594                checksum = 0;
    724 
     595        }
    725596        // prefix the udp header
    726597        header = PACKET_PREFIX(packet, udp_header_t);
    727         if(! header)
     598        if(! header){
    728599                return udp_release_and_return(packet, ENOMEM);
    729 
     600        }
    730601        bzero(header, sizeof(*header));
    731602        // read the rest of the packet fragments
    732         for (index = 1; index < fragments; ++ index) {
    733                 result = tl_socket_read_packet_data(udp_globals.net_phone,
    734                     &next_packet, 0, packet_dimension, addr, addrlen);
    735                 if (result < 0)
     603        for(index = 1; index < fragments; ++ index){
     604                result = tl_socket_read_packet_data(udp_globals.net_phone, &next_packet, 0, packet_dimension, addr, addrlen);
     605                if(result < 0){
    736606                        return udp_release_and_return(packet, result);
    737 
    738                 if (ERROR_OCCURRED(pq_add(&packet, next_packet, index, 0)))
     607                }
     608                if(ERROR_OCCURRED(pq_add(&packet, next_packet, index, 0))){
    739609                        return udp_release_and_return(packet, ERROR_CODE);
    740 
     610                }
    741611                total_length += (size_t) result;
    742                 if (udp_globals.checksum_computing) {
    743                         checksum = compute_checksum(checksum,
    744                             packet_get_data(next_packet),
    745                             packet_get_data_length(next_packet));
    746                 }
    747         }
    748 
     612                if(udp_globals.checksum_computing){
     613                        checksum = compute_checksum(checksum, packet_get_data(next_packet), packet_get_data_length(next_packet));
     614                }
     615        }
    749616        // set the udp header
    750617        header->source_port = htons((socket->port > 0) ? socket->port : 0);
     
    752619        header->total_length = htons(total_length + sizeof(*header));
    753620        header->checksum = 0;
    754         if (udp_globals.checksum_computing) {
     621        if(udp_globals.checksum_computing){
    755622                // update the pseudo header
    756                 if (ERROR_OCCURRED(ip_client_set_pseudo_header_data_length(
    757                     ip_header, headerlen, total_length + UDP_HEADER_SIZE))) {
     623                if(ERROR_OCCURRED(ip_client_set_pseudo_header_data_length(ip_header, headerlen, total_length + UDP_HEADER_SIZE))){
    758624                        free(ip_header);
    759625                        return udp_release_and_return(packet, ERROR_CODE);
    760626                }
    761 
    762627                // finish the checksum computation
    763628                checksum = compute_checksum(checksum, ip_header, headerlen);
    764                 checksum = compute_checksum(checksum, (uint8_t *) header,
    765                     sizeof(*header));
    766                 header->checksum =
    767                     htons(flip_checksum(compact_checksum(checksum)));
     629                checksum = compute_checksum(checksum, (uint8_t *) header, sizeof(*header));
     630                header->checksum = htons(flip_checksum(compact_checksum(checksum)));
    768631                free(ip_header);
    769         } else {
     632        }else{
    770633                device_id = DEVICE_INVALID_ID;
    771634        }
    772 
    773635        // prepare the first packet fragment
    774         if (ERROR_OCCURRED(ip_client_prepare_packet(packet, IPPROTO_UDP, 0, 0,
    775             0, 0))) {
     636        if(ERROR_OCCURRED(ip_client_prepare_packet(packet, IPPROTO_UDP, 0, 0, 0, 0))){
    776637                return udp_release_and_return(packet, ERROR_CODE);
    777638        }
    778 
    779639        // send the packet
    780640        fibril_rwlock_write_unlock(&udp_globals.lock);
    781641        ip_send_msg(udp_globals.ip_phone, device_id, packet, SERVICE_UDP, 0);
    782 
    783642        return EOK;
    784643}
    785644
    786 int
    787 udp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, int flags,
    788     size_t *addrlen)
    789 {
     645int udp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, int flags, size_t * addrlen){
    790646        ERROR_DECLARE;
    791647
     
    794650        packet_t packet;
    795651        udp_header_ref header;
    796         struct sockaddr *addr;
     652        struct sockaddr * addr;
    797653        size_t length;
    798         uint8_t *data;
     654        uint8_t * data;
    799655        int result;
    800656
    801657        // find the socket
    802658        socket = socket_cores_find(local_sockets, socket_id);
    803         if (!socket)
     659        if(! socket){
    804660                return ENOTSOCK;
    805 
     661        }
    806662        // get the next received packet
    807663        packet_id = dyn_fifo_value(&socket->received);
    808         if (packet_id < 0)
     664        if(packet_id < 0){
    809665                return NO_DATA;
    810 
    811         ERROR_PROPAGATE(packet_translate_remote(udp_globals.net_phone, &packet,
    812             packet_id));
    813 
     666        }
     667        ERROR_PROPAGATE(packet_translate_remote(udp_globals.net_phone, &packet, packet_id));
    814668        // get udp header
    815669        data = packet_get_data(packet);
    816         if (!data) {
     670        if(! data){
    817671                pq_release_remote(udp_globals.net_phone, packet_id);
    818672                return NO_DATA;
     
    822676        // set the source address port
    823677        result = packet_get_addr(packet, (uint8_t **) &addr, NULL);
    824         if (ERROR_OCCURRED(tl_set_address_port(addr, result,
    825             ntohs(header->source_port)))) {
     678        if(ERROR_OCCURRED(tl_set_address_port(addr, result, ntohs(header->source_port)))){
    826679                pq_release_remote(udp_globals.net_phone, packet_id);
    827680                return ERROR_CODE;
    828681        }
    829682        *addrlen = (size_t) result;
    830 
    831683        // send the source address
    832684        ERROR_PROPAGATE(data_reply(addr, * addrlen));
     
    841693        dyn_fifo_pop(&socket->received);
    842694        pq_release_remote(udp_globals.net_phone, packet_get_id(packet));
    843 
    844695        // return the total length
    845696        return (int) length;
    846697}
    847698
    848 int udp_release_and_return(packet_t packet, int result)
    849 {
     699int udp_release_and_return(packet_t packet, int result){
    850700        pq_release_remote(udp_globals.net_phone, packet_get_id(packet));
    851701        return result;
     
    854704/** Default thread for new connections.
    855705 *
    856  *  @param[in] iid      The initial message identifier.
    857  *  @param[in] icall    The initial message call structure.
     706 *  @param[in] iid The initial message identifier.
     707 *  @param[in] icall The initial message call structure.
    858708 *
    859709 */
     
    866716        ipc_answer_0(iid, EOK);
    867717       
    868         while (true) {
     718        while(true) {
    869719                ipc_call_t answer;
    870720                int answer_count;
     
    881731                    &answer_count);
    882732               
    883                 /*
    884                  * End if said to either by the message or the processing result
    885                  */
    886                 if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) ||
    887                     (res == EHANGUP))
     733                /* End if said to either by the message or the processing result */
     734                if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) || (res == EHANGUP))
    888735                        return;
    889736               
     
    895742/** Starts the module.
    896743 *
    897  *  @param argc         The count of the command line arguments. Ignored
    898  *                      parameter.
    899  *  @param argv         The command line parameters. Ignored parameter.
     744 *  @param argc The count of the command line arguments. Ignored parameter.
     745 *  @param argv The command line parameters. Ignored parameter.
    900746 *
    901  *  @returns            EOK on success.
    902  *  @returns            Other error codes as defined for each specific module
    903  *                      start function.
     747 *  @returns EOK on success.
     748 *  @returns Other error codes as defined for each specific module start function.
     749 *
    904750 */
    905751int main(int argc, char *argv[])
Note: See TracChangeset for help on using the changeset viewer.