Changeset efedee77 in mainline for uspace/srv/net/tl/udp/udp.c


Ignore:
Timestamp:
2010-11-02T22:38:46Z (13 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
af894a21
Parents:
aab02fb (diff), e06ef614 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes

File:
1 edited

Legend:

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

    raab02fb refedee77  
    4242#include <ipc/ipc.h>
    4343#include <ipc/services.h>
    44 
    45 #include <net_err.h>
    46 #include <net_messages.h>
    47 #include <net_modules.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
    4857#include <adt/dynamic_fifo.h>
    49 #include <packet/packet_client.h>
     58#include <packet_client.h>
    5059#include <packet_remote.h>
    5160#include <net_checksum.h>
    52 #include <in.h>
    53 #include <in6.h>
    54 #include <inet.h>
    5561#include <ip_client.h>
    5662#include <ip_interface.h>
    57 #include <ip_protocols.h>
    5863#include <icmp_client.h>
    5964#include <icmp_interface.h>
    6065#include <net_interface.h>
    61 #include <socket_codes.h>
    62 #include <socket_errno.h>
    6366#include <socket_core.h>
    64 #include <socket_messages.h>
    6567#include <tl_common.h>
    6668#include <tl_local.h>
    6769#include <tl_interface.h>
    68 #include <tl_messages.h>
    6970
    7071#include "udp.h"
     
    7273#include "udp_module.h"
    7374
    74 /** UDP module name.
    75  */
     75/** UDP module name. */
    7676#define NAME    "UDP protocol"
    7777
    78 /** Default UDP checksum computing.
    79  */
     78/** Default UDP checksum computing. */
    8079#define NET_DEFAULT_UDP_CHECKSUM_COMPUTING      true
    8180
    82 /** Default UDP autobind when sending via unbound sockets.
    83  */
     81/** Default UDP autobind when sending via unbound sockets. */
    8482#define NET_DEFAULT_UDP_AUTOBINDING     true
    8583
    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  */
     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. */
    9691#define UDP_FREE_PORTS_END              65535
    9792
    9893/** Processes the received UDP packet queue.
     94 *
    9995 *  Is used as an entry point from the underlying IP module.
    10096 *  Locks the global lock and calls udp_process_packet() function.
     97 *
    10198 *  @param[in] device_id The receiving device identifier.
    10299 *  @param[in,out] packet The received packet queue.
    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  */
    108 int udp_received_msg(device_id_t device_id, packet_t packet, services_t receiver, services_t error);
     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);
    109110
    110111/** Processes the received UDP packet queue.
     112 *
    111113 *  Notifies the destination socket application.
    112  *  Releases the packet on error or sends an ICMP error notification..
     114 *  Releases the packet on error or sends an ICMP error notification.
     115 *
    113116 *  @param[in] device_id The receiving device identifier.
    114117 *  @param[in,out] packet The received packet queue.
    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  */
    125 int udp_process_packet(device_id_t device_id, packet_t packet, services_t error);
     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);
    126134
    127135/** Releases the packet and returns the result.
    128  *  @param[in] packet The packet queue to be released.
    129  *  @param[in] result The result to be returned.
    130  *  @return The result parameter.
     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.
    131140 */
    132141int udp_release_and_return(packet_t packet, int result);
     
    137146
    138147/** Processes the socket client messages.
     148 *
    139149 *  Runs until the client module disconnects.
    140  *  @param[in] callid The message identifier.
    141  *  @param[in] call The message parameters.
    142  *  @returns EOK on success.
    143  *  @see socket.h
     150 *
     151 *  @param[in] callid   The message identifier.
     152 *  @param[in] call     The message parameters.
     153 *  @returns            EOK on success.
     154 *  @see                socket.h
    144155 */
    145156int udp_process_client_messages(ipc_callid_t callid, ipc_call_t call);
    146157
    147158/** Sends data from the socket to the remote address.
     159 *
    148160 *  Binds the socket to a free port if not already connected/bound.
    149161 *  Handles the NET_SOCKET_SENDTO message.
    150162 *  Supports AF_INET and AF_INET6 address families.
     163 *
    151164 *  @param[in,out] local_sockets The application local sockets.
    152165 *  @param[in] socket_id Socket identifier.
    153  *  @param[in] addr The destination address.
    154  *  @param[in] addrlen The address length.
     166 *  @param[in] addr     The destination address.
     167 *  @param[in] addrlen  The address length.
    155168 *  @param[in] fragments The number of data fragments.
    156169 *  @param[out] data_fragment_size The data fragment size in bytes.
    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  */
    168 int 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);
     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);
    169189
    170190/** Receives data to the socket.
     191 *
    171192 *  Handles the NET_SOCKET_RECVFROM message.
    172193 *  Replies the source address as well.
     194 *
    173195 *  @param[in] local_sockets The application local sockets.
    174196 *  @param[in] socket_id Socket identifier.
    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  */
    185 int udp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, int flags, size_t * addrlen);
     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);
    186212
    187213/*@}*/
     
    189215/** UDP global data.
    190216 */
    191 udp_globals_t   udp_globals;
    192 
    193 int udp_initialize(async_client_conn_t client_connection){
     217udp_globals_t udp_globals;
     218
     219int udp_initialize(async_client_conn_t client_connection)
     220{
    194221        ERROR_DECLARE;
    195222
    196         measured_string_t names[] = {{str_dup("UDP_CHECKSUM_COMPUTING"), 22}, {str_dup("UDP_AUTOBINDING"), 15}};
     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        };
    197233        measured_string_ref configuration;
    198234        size_t count = sizeof(names) / sizeof(measured_string_t);
     
    201237        fibril_rwlock_initialize(&udp_globals.lock);
    202238        fibril_rwlock_write_lock(&udp_globals.lock);
    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){
     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)
    206245                return udp_globals.ip_phone;
    207         }
     246
    208247        // read default packet dimensions
    209         ERROR_PROPAGATE(ip_packet_size_req(udp_globals.ip_phone, -1, &udp_globals.packet_dimension));
     248        ERROR_PROPAGATE(ip_packet_size_req(udp_globals.ip_phone, -1,
     249            &udp_globals.packet_dimension));
    210250        ERROR_PROPAGATE(socket_ports_initialize(&udp_globals.sockets));
    211         if(ERROR_OCCURRED(packet_dimensions_initialize(&udp_globals.dimensions))){
     251        if (ERROR_OCCURRED(packet_dimensions_initialize(
     252            &udp_globals.dimensions))) {
    212253                socket_ports_destroy(&udp_globals.sockets);
    213254                return ERROR_CODE;
     
    216257        udp_globals.packet_dimension.content -= sizeof(udp_header_t);
    217258        udp_globals.last_used_port = UDP_FREE_PORTS_START - 1;
     259
    218260        // get configuration
    219261        udp_globals.checksum_computing = NET_DEFAULT_UDP_CHECKSUM_COMPUTING;
    220262        udp_globals.autobinding = NET_DEFAULT_UDP_AUTOBINDING;
    221263        configuration = &names[0];
    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                 }
     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
    230275                net_free_settings(configuration, data);
    231276        }
     277
    232278        fibril_rwlock_write_unlock(&udp_globals.lock);
    233279        return EOK;
    234280}
    235281
    236 int udp_received_msg(device_id_t device_id, packet_t packet, services_t receiver, services_t error){
     282int
     283udp_received_msg(device_id_t device_id, packet_t packet, services_t receiver,
     284    services_t error)
     285{
    237286        int result;
    238287
    239288        fibril_rwlock_write_lock(&udp_globals.lock);
    240289        result = udp_process_packet(device_id, packet, error);
    241         if(result != EOK){
     290        if (result != EOK)
    242291                fibril_rwlock_write_unlock(&udp_globals.lock);
    243         }
    244292
    245293        return result;
    246294}
    247295
    248 int 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)
     297{
    249298        ERROR_DECLARE;
    250299
     
    262311        icmp_code_t code;
    263312        void *ip_header;
    264         struct sockaddr * src;
    265         struct sockaddr * dest;
     313        struct sockaddr *src;
     314        struct sockaddr *dest;
    266315        packet_dimension_ref packet_dimension;
    267316
    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         }
     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
    287337        // TODO process received ipopts?
    288338        result = ip_client_process_packet(packet, NULL, NULL, NULL, NULL, NULL);
    289         if(result < 0){
     339        if (result < 0)
    290340                return udp_release_and_return(packet, result);
    291         }
    292341        offset = (size_t) result;
    293342
    294343        length = packet_get_data_length(packet);
    295         if(length <= 0){
     344        if (length <= 0)
    296345                return udp_release_and_return(packet, EINVAL);
    297         }
    298         if(length < UDP_HEADER_SIZE + offset){
     346        if (length < UDP_HEADER_SIZE + offset)
    299347                return udp_release_and_return(packet, NO_DATA);
    300         }
    301348
    302349        // trim all but UDP header
    303         if(ERROR_OCCURRED(packet_trim(packet, offset, 0))){
     350        if (ERROR_OCCURRED(packet_trim(packet, offset, 0)))
    304351                return udp_release_and_return(packet, ERROR_CODE);
    305         }
    306352
    307353        // get udp header
    308354        header = (udp_header_ref) packet_get_data(packet);
    309         if(! header){
     355        if (!header)
    310356                return udp_release_and_return(packet, NO_DATA);
    311         }
     357
    312358        // find the destination socket
    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);
     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);
    317366                }
    318367                return EADDRNOTAVAIL;
     
    323372        fragments = 0;
    324373        total_length = ntohs(header->total_length);
     374
    325375        // compute header checksum if set
    326         if(header->checksum && (! error)){
    327                 result = packet_get_addr(packet, (uint8_t **) &src, (uint8_t **) &dest);
    328                 if(result <= 0){
     376        if (header->checksum && (!error)) {
     377                result = packet_get_addr(packet, (uint8_t **) &src,
     378                    (uint8_t **) &dest);
     379                if( result <= 0)
    329380                        return udp_release_and_return(packet, result);
    330                 }
    331                 if(ERROR_OCCURRED(ip_client_get_pseudo_header(IPPROTO_UDP, src, result, dest, result, total_length, &ip_header, &length))){
     381
     382                if (ERROR_OCCURRED(ip_client_get_pseudo_header(IPPROTO_UDP,
     383                    src, result, dest, result, total_length, &ip_header,
     384                    &length))) {
    332385                        return udp_release_and_return(packet, ERROR_CODE);
    333                 }else{
     386                } else {
    334387                        checksum = compute_checksum(0, ip_header, length);
    335                         // the udp header checksum will be added with the first fragment later
     388                        // the udp header checksum will be added with the first
     389                        // fragment later
    336390                        free(ip_header);
    337391                }
    338         }else{
     392        } else {
    339393                header->checksum = 0;
    340394                checksum = 0;
    341395        }
    342396
    343         do{
     397        do {
    344398                ++ fragments;
    345399                length = packet_get_data_length(next_packet);
    346                 if(length <= 0){
     400                if (length <= 0)
    347401                        return udp_release_and_return(packet, NO_DATA);
    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);
     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);
    352408                        }
     409
    353410                        // add partial checksum if set
    354                         if(header->checksum){
    355                                 checksum = compute_checksum(checksum, packet_get_data(packet), packet_get_data_length(packet));
     411                        if (header->checksum) {
     412                                checksum = compute_checksum(checksum,
     413                                    packet_get_data(packet),
     414                                    packet_get_data_length(packet));
    356415                        }
     416
    357417                        // relese the rest of the packet fragments
    358418                        tmp_packet = pq_next(next_packet);
    359                         while(tmp_packet){
     419                        while (tmp_packet) {
    360420                                next_packet = pq_detach(tmp_packet);
    361                                 pq_release_remote(udp_globals.net_phone, packet_get_id(tmp_packet));
     421                                pq_release_remote(udp_globals.net_phone,
     422                                    packet_get_id(tmp_packet));
    362423                                tmp_packet = next_packet;
    363424                        }
     425
    364426                        // exit the loop
    365427                        break;
    366428                }
    367429                total_length -= length;
     430
    368431                // add partial checksum if set
    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));
     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));
    373439
    374440        // check checksum
    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){
     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) {
    378446                                // checksum error ICMP
    379                                 icmp_parameter_problem_msg(udp_globals.icmp_phone, ICMP_PARAM_POINTER, ((size_t) ((void *) &header->checksum)) - ((size_t) ((void *) header)), packet);
     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);
    380451                        }
    381452                        return EINVAL;
     
    384455
    385456        // queue the received packet
    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))){
     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))) {
    388461                return udp_release_and_return(packet, ERROR_CODE);
    389462        }
     
    391464        // notify the destination socket
    392465        fibril_rwlock_write_unlock(&udp_globals.lock);
    393         async_msg_5(socket->phone, NET_SOCKET_RECEIVED, (ipcarg_t) socket->socket_id, packet_dimension->content, 0, 0, (ipcarg_t) fragments);
     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
    394470        return EOK;
    395471}
    396472
    397 int udp_message_standalone(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
     473int
     474udp_message_standalone(ipc_callid_t callid, ipc_call_t * call,
     475    ipc_call_t * answer, int * answer_count)
     476{
    398477        ERROR_DECLARE;
    399478
     
    401480
    402481        *answer_count = 0;
    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         }
     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
    412496        return ENOTSUP;
    413497}
    414498
    415 int udp_process_client_messages(ipc_callid_t callid, ipc_call_t call){
     499int udp_process_client_messages(ipc_callid_t callid, ipc_call_t call)
     500{
    416501        int res;
    417502        bool keep_on_going = true;
    418503        socket_cores_t local_sockets;
    419504        int app_phone = IPC_GET_PHONE(&call);
    420         struct sockaddr * addr;
     505        struct sockaddr *addr;
    421506        int socket_id;
    422507        size_t addrlen;
     
    433518        answer_count = 0;
    434519
    435         // The client connection is only in one fibril and therefore no additional locks are needed.
     520        // The client connection is only in one fibril and therefore no
     521        // additional locks are needed.
    436522
    437523        socket_cores_initialize(&local_sockets);
    438524
    439         while(keep_on_going){
     525        while (keep_on_going) {
    440526
    441527                // answer the call
     
    449535
    450536                // process the call
    451                 switch(IPC_GET_METHOD(call)){
    452                         case IPC_M_PHONE_HUNGUP:
    453                                 keep_on_going = false;
    454                                 res = EHANGUP;
     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)
    455550                                break;
    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                                 }
     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)
    469568                                break;
    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                                 }
     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)
    478581                                break;
    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                                 }
     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)
    492606                                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);
    496                                 fibril_rwlock_write_unlock(&udp_globals.lock);
    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                                 }
    503                                 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;
     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;
    514627                }
    515628        }
     
    519632
    520633        // release all local sockets
    521         socket_cores_release(udp_globals.net_phone, &local_sockets, &udp_globals.sockets, NULL);
     634        socket_cores_release(udp_globals.net_phone, &local_sockets,
     635            &udp_globals.sockets, NULL);
    522636
    523637        return res;
    524638}
    525639
    526 int 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){
     640int
     641udp_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{
    527645        ERROR_DECLARE;
    528646
     
    544662
    545663        socket = socket_cores_find(local_sockets, socket_id);
    546         if(! socket){
     664        if (!socket)
    547665                return ENOTSOCK;
    548         }
    549 
    550         if((socket->port <= 0) && udp_globals.autobinding){
     666
     667        if ((socket->port <= 0) && udp_globals.autobinding) {
    551668                // bind the socket to a random free port if not bound
    552 //              do{
     669//              do {
    553670                        // try to find a free port
    554671//                      fibril_rwlock_read_unlock(&udp_globals.lock);
    555672//                      fibril_rwlock_write_lock(&udp_globals.lock);
    556673                        // might be changed in the meantime
    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);
     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);
    561683                                        return ERROR_CODE;
    562684                                }
    563                                 // set the next port as the search starting port number
     685                                // set the next port as the search starting port
     686                                // number
    564687                                udp_globals.last_used_port = socket->port;
    565688//                      }
     
    567690//                      fibril_rwlock_read_lock(&udp_globals.lock);
    568691                        // might be changed in the meantime
    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))){
     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))) {
    574699                        return udp_release_and_return(packet, ERROR_CODE);
    575700                }
    576701                // get the device packet dimension
    577 //              ERROR_PROPAGATE(tl_get_ip_packet_dimension(udp_globals.ip_phone, &udp_globals.dimensions, device_id, &packet_dimension));
    578         }
    579 //      }else{
     702//              ERROR_PROPAGATE(tl_get_ip_packet_dimension(udp_globals.ip_phone,
     703//                  &udp_globals.dimensions, device_id, &packet_dimension));
     704        }
     705//      } else {
    580706                // do not ask all the time
    581                 ERROR_PROPAGATE(ip_packet_size_req(udp_globals.ip_phone, -1, &udp_globals.packet_dimension));
     707                ERROR_PROPAGATE(ip_packet_size_req(udp_globals.ip_phone, -1,
     708                    &udp_globals.packet_dimension));
    582709                packet_dimension = &udp_globals.packet_dimension;
    583710//      }
    584711
    585712        // read the first packet fragment
    586         result = tl_socket_read_packet_data(udp_globals.net_phone, &packet, UDP_HEADER_SIZE, packet_dimension, addr, addrlen);
    587         if(result < 0){
     713        result = tl_socket_read_packet_data(udp_globals.net_phone, &packet,
     714            UDP_HEADER_SIZE, packet_dimension, addr, addrlen);
     715        if (result < 0)
    588716                return result;
    589         }
     717
    590718        total_length = (size_t) result;
    591         if(udp_globals.checksum_computing){
    592                 checksum = compute_checksum(0, packet_get_data(packet), packet_get_data_length(packet));
    593         }else{
     719        if (udp_globals.checksum_computing)
     720                checksum = compute_checksum(0, packet_get_data(packet),
     721                    packet_get_data_length(packet));
     722        else
    594723                checksum = 0;
    595         }
     724
    596725        // prefix the udp header
    597726        header = PACKET_PREFIX(packet, udp_header_t);
    598         if(! header){
     727        if(! header)
    599728                return udp_release_and_return(packet, ENOMEM);
    600         }
     729
    601730        bzero(header, sizeof(*header));
    602731        // read the rest of the packet fragments
    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){
     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)
    606736                        return udp_release_and_return(packet, result);
    607                 }
    608                 if(ERROR_OCCURRED(pq_add(&packet, next_packet, index, 0))){
     737
     738                if (ERROR_OCCURRED(pq_add(&packet, next_packet, index, 0)))
    609739                        return udp_release_and_return(packet, ERROR_CODE);
    610                 }
     740
    611741                total_length += (size_t) result;
    612                 if(udp_globals.checksum_computing){
    613                         checksum = compute_checksum(checksum, packet_get_data(next_packet), packet_get_data_length(next_packet));
    614                 }
    615         }
     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
    616749        // set the udp header
    617750        header->source_port = htons((socket->port > 0) ? socket->port : 0);
     
    619752        header->total_length = htons(total_length + sizeof(*header));
    620753        header->checksum = 0;
    621         if(udp_globals.checksum_computing){
     754        if (udp_globals.checksum_computing) {
    622755                // update the pseudo header
    623                 if(ERROR_OCCURRED(ip_client_set_pseudo_header_data_length(ip_header, headerlen, total_length + UDP_HEADER_SIZE))){
     756                if (ERROR_OCCURRED(ip_client_set_pseudo_header_data_length(
     757                    ip_header, headerlen, total_length + UDP_HEADER_SIZE))) {
    624758                        free(ip_header);
    625759                        return udp_release_and_return(packet, ERROR_CODE);
    626760                }
     761
    627762                // finish the checksum computation
    628763                checksum = compute_checksum(checksum, ip_header, headerlen);
    629                 checksum = compute_checksum(checksum, (uint8_t *) header, sizeof(*header));
    630                 header->checksum = htons(flip_checksum(compact_checksum(checksum)));
     764                checksum = compute_checksum(checksum, (uint8_t *) header,
     765                    sizeof(*header));
     766                header->checksum =
     767                    htons(flip_checksum(compact_checksum(checksum)));
    631768                free(ip_header);
    632         }else{
     769        } else {
    633770                device_id = DEVICE_INVALID_ID;
    634771        }
     772
    635773        // prepare the first packet fragment
    636         if(ERROR_OCCURRED(ip_client_prepare_packet(packet, IPPROTO_UDP, 0, 0, 0, 0))){
     774        if (ERROR_OCCURRED(ip_client_prepare_packet(packet, IPPROTO_UDP, 0, 0,
     775            0, 0))) {
    637776                return udp_release_and_return(packet, ERROR_CODE);
    638777        }
     778
    639779        // send the packet
    640780        fibril_rwlock_write_unlock(&udp_globals.lock);
    641781        ip_send_msg(udp_globals.ip_phone, device_id, packet, SERVICE_UDP, 0);
     782
    642783        return EOK;
    643784}
    644785
    645 int udp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, int flags, size_t * addrlen){
     786int
     787udp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, int flags,
     788    size_t *addrlen)
     789{
    646790        ERROR_DECLARE;
    647791
     
    650794        packet_t packet;
    651795        udp_header_ref header;
    652         struct sockaddr * addr;
     796        struct sockaddr *addr;
    653797        size_t length;
    654         uint8_t * data;
     798        uint8_t *data;
    655799        int result;
    656800
    657801        // find the socket
    658802        socket = socket_cores_find(local_sockets, socket_id);
    659         if(! socket){
     803        if (!socket)
    660804                return ENOTSOCK;
    661         }
     805
    662806        // get the next received packet
    663807        packet_id = dyn_fifo_value(&socket->received);
    664         if(packet_id < 0){
     808        if (packet_id < 0)
    665809                return NO_DATA;
    666         }
    667         ERROR_PROPAGATE(packet_translate_remote(udp_globals.net_phone, &packet, packet_id));
     810
     811        ERROR_PROPAGATE(packet_translate_remote(udp_globals.net_phone, &packet,
     812            packet_id));
     813
    668814        // get udp header
    669815        data = packet_get_data(packet);
    670         if(! data){
     816        if (!data) {
    671817                pq_release_remote(udp_globals.net_phone, packet_id);
    672818                return NO_DATA;
     
    676822        // set the source address port
    677823        result = packet_get_addr(packet, (uint8_t **) &addr, NULL);
    678         if(ERROR_OCCURRED(tl_set_address_port(addr, result, ntohs(header->source_port)))){
     824        if (ERROR_OCCURRED(tl_set_address_port(addr, result,
     825            ntohs(header->source_port)))) {
    679826                pq_release_remote(udp_globals.net_phone, packet_id);
    680827                return ERROR_CODE;
    681828        }
    682829        *addrlen = (size_t) result;
     830
    683831        // send the source address
    684832        ERROR_PROPAGATE(data_reply(addr, * addrlen));
     
    693841        dyn_fifo_pop(&socket->received);
    694842        pq_release_remote(udp_globals.net_phone, packet_get_id(packet));
     843
    695844        // return the total length
    696845        return (int) length;
    697846}
    698847
    699 int udp_release_and_return(packet_t packet, int result){
     848int udp_release_and_return(packet_t packet, int result)
     849{
    700850        pq_release_remote(udp_globals.net_phone, packet_get_id(packet));
    701851        return result;
     
    704854/** Default thread for new connections.
    705855 *
    706  *  @param[in] iid The initial message identifier.
    707  *  @param[in] icall The initial message call structure.
     856 *  @param[in] iid      The initial message identifier.
     857 *  @param[in] icall    The initial message call structure.
    708858 *
    709859 */
     
    716866        ipc_answer_0(iid, EOK);
    717867       
    718         while(true) {
     868        while (true) {
    719869                ipc_call_t answer;
    720870                int answer_count;
     
    731881                    &answer_count);
    732882               
    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))
     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))
    735888                        return;
    736889               
     
    742895/** Starts the module.
    743896 *
    744  *  @param argc The count of the command line arguments. Ignored parameter.
    745  *  @param argv The command line parameters. Ignored parameter.
    746  *
    747  *  @returns EOK on success.
    748  *  @returns Other error codes as defined for each specific module start function.
    749  *
     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
     903 *                      start function.
    750904 */
    751905int main(int argc, char *argv[])
Note: See TracChangeset for help on using the changeset viewer.