Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 137f8aa in mainline


Ignore:
Timestamp:
2010-10-15T20:53:02Z (10 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
master
Children:
b01f878
Parents:
25d2de69
Message:

Cleanup socket_core.[ch].

Location:
uspace/lib/net
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/net/generic/socket_core.c

    r25d2de69 r137f8aa  
    2727 */
    2828
    29 /** @addtogroup socket
    30  *  @{
     29/** @addtogroup libnet
     30 * @{
    3131 */
    3232
    3333/** @file
    34  *  Socket common core implementation.
    35  */
     34 * Socket common core implementation.
     35 */
     36
     37#include <socket_core.h>
     38#include <packet_client.h>
     39#include <packet_remote.h>
    3640
    3741#include <net/socket_codes.h>
    3842#include <net/in.h>
    3943#include <net/inet.h>
     44#include <net/packet.h>
     45#include <net/modules.h>
    4046
    4147#include <stdint.h>
     
    4652#include <adt/dynamic_fifo.h>
    4753#include <adt/int_map.h>
    48 #include <net/packet.h>
    49 #include <packet_client.h>
    50 #include <packet_remote.h>
    51 #include <net/modules.h>
    52 #include <socket_core.h>
    53 
    54 /** Maximum number of random attempts to find a new socket identifier before switching to the sequence.
    55  */
    56 #define SOCKET_ID_TRIES                                 100
    57 
    58 /** Bound port sockets.
    59  */
    60 struct socket_port{
    61         /** The bound sockets map.
    62          */
     54
     55/**
     56 * Maximum number of random attempts to find a new socket identifier before
     57 * switching to the sequence.
     58 */
     59#define SOCKET_ID_TRIES 100
     60
     61/** Bound port sockets.*/
     62struct socket_port {
     63        /** The bound sockets map. */
    6364        socket_port_map_t map;
    64         /** The bound sockets count.
    65          */
     65        /** The bound sockets count. */
    6666        int count;
    6767};
     
    7474
    7575/** Destroys the socket.
    76  *  If the socket is bound, the port is released.
    77  *  Releases all buffered packets, calls the release function and removes the socket from the local sockets.
    78  *  @param[in] packet_phone The packet server phone to release buffered packets.
    79  *  @param[in] socket The socket to be destroyed.
    80  *  @param[in,out] local_sockets The local sockets to be updated.
    81  *  @param[in,out] global_sockets The global sockets to be updated.
    82  *  @param[in] socket_release The client release callback function.
    83  */
    84 static void socket_destroy_core(int packet_phone, socket_core_ref socket, socket_cores_ref local_sockets, socket_ports_ref global_sockets, void (*socket_release)(socket_core_ref socket)){
     76 *
     77 * If the socket is bound, the port is released.
     78 * Releases all buffered packets, calls the release function and removes the
     79 * socket from the local sockets.
     80 *
     81 * @param[in] packet_phone The packet server phone to release buffered packets.
     82 * @param[in] socket    The socket to be destroyed.
     83 * @param[in,out] local_sockets The local sockets to be updated.
     84 * @param[in,out] global_sockets The global sockets to be updated.
     85 * @param[in] socket_release The client release callback function.
     86 */
     87static void
     88socket_destroy_core(int packet_phone, socket_core_ref socket,
     89    socket_cores_ref local_sockets, socket_ports_ref global_sockets,
     90    void (* socket_release)(socket_core_ref socket))
     91{
    8592        int packet_id;
    8693
    8794        // if bound
    88         if(socket->port){
     95        if (socket->port) {
    8996                // release the port
    9097                socket_port_release(global_sockets, socket);
    9198        }
     99       
    92100        // release all received packets
    93         while((packet_id = dyn_fifo_pop(&socket->received)) >= 0){
     101        while ((packet_id = dyn_fifo_pop(&socket->received)) >= 0)
    94102                pq_release_remote(packet_phone, packet_id);
    95         }
     103
    96104        dyn_fifo_destroy(&socket->received);
    97105        dyn_fifo_destroy(&socket->accepted);
    98         if(socket_release){
     106
     107        if (socket_release)
    99108                socket_release(socket);
    100         }
     109
    101110        socket_cores_exclude(local_sockets, socket->socket_id);
    102111}
    103112
    104 void socket_cores_release(int packet_phone, socket_cores_ref local_sockets, socket_ports_ref global_sockets, void (*socket_release)(socket_core_ref socket)){
    105         if(socket_cores_is_valid(local_sockets)){
    106                 int index;
    107 
    108                 local_sockets->magic = 0;
    109                 for(index = 0; index < local_sockets->next; ++ index){
    110                         if(socket_cores_item_is_valid(&(local_sockets->items[index]))){
    111                                 local_sockets->items[index].magic = 0;
    112                                 if(local_sockets->items[index].value){
    113                                         socket_destroy_core(packet_phone, local_sockets->items[index].value, local_sockets, global_sockets, socket_release);
    114                                         free(local_sockets->items[index].value);
    115                                         local_sockets->items[index].value = NULL;
    116                                 }
     113/** Destroys local sockets.
     114 *
     115 * Releases all buffered packets and calls the release function for each of the
     116 * sockets.
     117 *
     118 * @param[in] packet_phone The packet server phone to release buffered packets.
     119 * @param[in] local_sockets The local sockets to be destroyed.
     120 * @param[in,out] global_sockets The global sockets to be updated.
     121 * @param[in] socket_release The client release callback function.
     122 */
     123void
     124socket_cores_release(int packet_phone, socket_cores_ref local_sockets,
     125    socket_ports_ref global_sockets,
     126    void (* socket_release)(socket_core_ref socket))
     127{
     128        int index;
     129
     130        if (!socket_cores_is_valid(local_sockets))
     131                return;
     132
     133        local_sockets->magic = 0;
     134
     135        for (index = 0; index < local_sockets->next; ++index) {
     136                if (socket_cores_item_is_valid(&local_sockets->items[index])) {
     137                        local_sockets->items[index].magic = 0;
     138
     139                        if (local_sockets->items[index].value) {
     140                                socket_destroy_core(packet_phone,
     141                                    local_sockets->items[index].value,
     142                                    local_sockets, global_sockets,
     143                                    socket_release);
     144                                free(local_sockets->items[index].value);
     145                                local_sockets->items[index].value = NULL;
    117146                        }
    118147                }
    119                 free(local_sockets->items);
    120         }
     148        }
     149
     150        free(local_sockets->items);
    121151}
    122152
    123153/** Adds the socket to a socket port.
    124  *  @param[in,out] socket_port The socket port structure.
    125  *  @param[in] socket The socket to be added.
    126  *  @param[in] key The socket key identifier.
    127  *  @param[in] key_length The socket key length.
    128  *  @returns EOK on success.
    129  *  @returns ENOMEM if there is not enough memory left.
    130  */
    131 static int socket_port_add_core(socket_port_ref socket_port, socket_core_ref socket, const char * key, size_t key_length){
     154 *
     155 * @param[in,out] socket_port The socket port structure.
     156 * @param[in] socket    The socket to be added.
     157 * @param[in] key       The socket key identifier.
     158 * @param[in] key_length The socket key length.
     159 * @returns             EOK on success.
     160 * @returns             ENOMEM if there is not enough memory left.
     161 */
     162static int
     163socket_port_add_core(socket_port_ref socket_port, socket_core_ref socket,
     164    const char *key, size_t key_length)
     165{
    132166        ERROR_DECLARE;
    133167
    134         socket_core_ref * socket_ref;
     168        socket_core_ref *socket_ref;
    135169
    136170        // create a wrapper
    137171        socket_ref = malloc(sizeof(*socket_ref));
    138         if(! socket_ref){
     172        if (!socket_ref)
    139173                return ENOMEM;
    140         }
     174
    141175        *socket_ref = socket;
    142176        // add the wrapper
    143         if(ERROR_OCCURRED(socket_port_map_add(&socket_port->map, key, key_length, socket_ref))){
     177        if (ERROR_OCCURRED(socket_port_map_add(&socket_port->map, key,
     178            key_length, socket_ref))) {
    144179                free(socket_ref);
    145180                return ERROR_CODE;
    146181        }
    147         ++ socket_port->count;
     182       
     183        ++socket_port->count;
    148184        socket->key = key;
    149185        socket->key_length = key_length;
     186       
    150187        return EOK;
    151188}
    152189
    153190/** Binds the socket to the port.
    154  *  The SOCKET_MAP_KEY_LISTENING key identifier is used.
    155  *  @param[in] global_sockets The global sockets to be updated.
    156  *  @param[in] socket The socket to be added.
    157  *  @param[in] port The port number to be bound to.
    158  *  @returns EOK on success.
    159  *  @returns ENOMEM if there is not enough memory left.
    160  *  @returns Other error codes as defined for the socket_ports_add() function.
    161  */
    162 static int socket_bind_insert(socket_ports_ref global_sockets, socket_core_ref socket, int port){
     191 *
     192 * The SOCKET_MAP_KEY_LISTENING key identifier is used.
     193 *
     194 * @param[in] global_sockets The global sockets to be updated.
     195 * @param[in] socket    The socket to be added.
     196 * @param[in] port      The port number to be bound to.
     197 * @returns             EOK on success.
     198 * @returns             ENOMEM if there is not enough memory left.
     199 * @returns             Other error codes as defined for the
     200 *                       socket_ports_add() function.
     201 */
     202static int
     203socket_bind_insert(socket_ports_ref global_sockets, socket_core_ref socket,
     204    int port)
     205{
    163206        ERROR_DECLARE;
    164207
     
    167210        // create a wrapper
    168211        socket_port = malloc(sizeof(*socket_port));
    169         if(! socket_port){
     212        if (!socket_port)
    170213                return ENOMEM;
    171         }
     214
    172215        socket_port->count = 0;
    173         if(ERROR_OCCURRED(socket_port_map_initialize(&socket_port->map))
    174                 || ERROR_OCCURRED(socket_port_add_core(socket_port, socket, SOCKET_MAP_KEY_LISTENING, 0))){
     216        if (ERROR_OCCURRED(socket_port_map_initialize(&socket_port->map)) ||
     217            ERROR_OCCURRED(socket_port_add_core(socket_port, socket,
     218            SOCKET_MAP_KEY_LISTENING, 0))) {
    175219                socket_port_map_destroy(&socket_port->map);
    176220                free(socket_port);
    177221                return ERROR_CODE;
    178222        }
     223       
    179224        // register the incomming port
    180225        ERROR_CODE = socket_ports_add(global_sockets, port, socket_port);
    181         if(ERROR_CODE < 0){
     226        if (ERROR_CODE < 0) {
    182227                socket_port_map_destroy(&socket_port->map);
    183228                free(socket_port);
    184229                return ERROR_CODE;
    185230        }
     231       
    186232        socket->port = port;
    187233        return EOK;
    188234}
    189235
    190 int socket_bind(socket_cores_ref local_sockets, socket_ports_ref global_sockets, int socket_id, void * addr, size_t addrlen, int free_ports_start, int free_ports_end, int last_used_port){
     236/** Binds the socket to the port.
     237 *
     238 * The address port is used if set, a free port is used if not.
     239 *
     240 * @param[in] local_sockets The local sockets to be searched.
     241 * @param[in,out] global_sockets The global sockets to be updated.
     242 * @param[in] socket_id The new socket identifier.
     243 * @param[in] addr      The address to be bound to.
     244 * @param[in] addrlen   The address length.
     245 * @param[in] free_ports_start The minimum free port.
     246 * @param[in] free_ports_end The maximum free port.
     247 * @param[in] last_used_port The last used free port.
     248 * @returns             EOK on success.
     249 * @returns             ENOTSOCK if the socket was not found.
     250 * @returns             EAFNOSUPPORT if the address family is not supported.
     251 * @returns             EADDRINUSE if the port is already in use.
     252 * @returns             Other error codes as defined for the
     253 *                      socket_bind_free_port() function.
     254 * @returns             Other error codes as defined for the
     255 *                      socket_bind_insert() function.
     256 */
     257int
     258socket_bind(socket_cores_ref local_sockets, socket_ports_ref global_sockets,
     259    int socket_id, void *addr, size_t addrlen, int free_ports_start,
     260    int free_ports_end, int last_used_port)
     261{
    191262        socket_core_ref socket;
    192263        socket_port_ref socket_port;
    193         struct sockaddr * address;
    194         struct sockaddr_in * address_in;
    195 
    196         if(addrlen < sizeof(struct sockaddr)){
     264        struct sockaddr *address;
     265        struct sockaddr_in *address_in;
     266
     267        if (addrlen < sizeof(struct sockaddr))
    197268                return EINVAL;
    198         }
     269
    199270        address = (struct sockaddr *) addr;
    200         switch(address->sa_family){
    201                 case AF_INET:
    202                         if(addrlen != sizeof(struct sockaddr_in)){
    203                                 return EINVAL;
    204                         }
    205                         address_in = (struct sockaddr_in *) addr;
    206                         // find the socket
    207                         socket = socket_cores_find(local_sockets, socket_id);
    208                         if(! socket){
    209                                 return ENOTSOCK;
    210                         }
    211                         // bind a free port?
    212                         if(address_in->sin_port <= 0){
    213                                 return socket_bind_free_port(global_sockets, socket, free_ports_start, free_ports_end, last_used_port);
    214                         }
    215                         // try to find the port
    216                         socket_port = socket_ports_find(global_sockets, ntohs(address_in->sin_port));
    217                         if(socket_port){
    218                                 // already used
    219                                 return EADDRINUSE;
    220                         }
    221                         // if bound
    222                         if(socket->port){
    223                                 // release the port
    224                                 socket_port_release(global_sockets, socket);
    225                         }
    226                         socket->port = -1;
    227                         return socket_bind_insert(global_sockets, socket, ntohs(address_in->sin_port));
    228                         break;
     271        switch (address->sa_family) {
     272        case AF_INET:
     273                if (addrlen != sizeof(struct sockaddr_in))
     274                        return EINVAL;
     275               
     276                address_in = (struct sockaddr_in *) addr;
     277                // find the socket
     278                socket = socket_cores_find(local_sockets, socket_id);
     279                if (!socket)
     280                        return ENOTSOCK;
     281               
     282                // bind a free port?
     283                if (address_in->sin_port <= 0)
     284                        return socket_bind_free_port(global_sockets, socket,
     285                             free_ports_start, free_ports_end, last_used_port);
     286               
     287                // try to find the port
     288                socket_port = socket_ports_find(global_sockets,
     289                    ntohs(address_in->sin_port));
     290                if (socket_port) {
     291                        // already used
     292                        return EADDRINUSE;
     293                }
     294               
     295                // if bound
     296                if (socket->port) {
     297                        // release the port
     298                        socket_port_release(global_sockets, socket);
     299                }
     300                socket->port = -1;
     301               
     302                return socket_bind_insert(global_sockets, socket,
     303                    ntohs(address_in->sin_port));
     304               
     305        case AF_INET6:
    229306                // TODO IPv6
    230         }
     307                break;
     308        }
     309       
    231310        return EAFNOSUPPORT;
    232311}
    233312
    234 int socket_bind_free_port(socket_ports_ref global_sockets, socket_core_ref socket, int free_ports_start, int free_ports_end, int last_used_port){
     313/** Binds the socket to a free port.
     314 *
     315 * The first free port is used.
     316 *
     317 * @param[in,out] global_sockets The global sockets to be updated.
     318 * @param[in,out] socket The socket to be bound.
     319 * @param[in] free_ports_start The minimum free port.
     320 * @param[in] free_ports_end The maximum free port.
     321 * @param[in] last_used_port The last used free port.
     322 * @returns             EOK on success.
     323 * @returns             ENOTCONN if no free port was found.
     324 * @returns             Other error codes as defined for the
     325 *                      socket_bind_insert() function.
     326 */
     327int
     328socket_bind_free_port(socket_ports_ref global_sockets, socket_core_ref socket,
     329    int free_ports_start, int free_ports_end, int last_used_port)
     330{
    235331        int index;
    236332
    237333        // from the last used one
    238334        index = last_used_port;
    239         do{
    240                 ++ index;
     335       
     336        do {
     337                ++index;
     338               
    241339                // til the range end
    242                 if(index >= free_ports_end){
     340                if (index >= free_ports_end) {
    243341                        // start from the range beginning
    244342                        index = free_ports_start - 1;
    245                         do{
    246                                 ++ index;
     343                        do {
     344                                ++index;
    247345                                // til the last used one
    248                                 if(index >= last_used_port){
     346                                if (index >= last_used_port) {
    249347                                        // none found
    250348                                        return ENOTCONN;
    251349                                }
    252                         }while(socket_ports_find(global_sockets, index) != NULL);
     350                        } while (socket_ports_find(global_sockets, index));
     351                       
    253352                        // found, break immediately
    254353                        break;
    255354                }
    256         }while(socket_ports_find(global_sockets, index) != NULL);
     355               
     356        } while (socket_ports_find(global_sockets, index));
     357       
    257358        return socket_bind_insert(global_sockets, socket, index);
    258359}
    259360
    260361/** Tries to find a new free socket identifier.
    261  *  @param[in] local_sockets The local sockets to be searched.
    262  *  @param[in] positive A value indicating whether a positive identifier is requested. A negative identifier is requested if set to false.
    263  *      @returns The new socket identifier.
    264  *  @returns ELIMIT if there is no socket identifier available.
    265  */
    266 static int socket_generate_new_id(socket_cores_ref local_sockets, int positive){
     362 *
     363 * @param[in] local_sockets The local sockets to be searched.
     364 * @param[in] positive  A value indicating whether a positive identifier is
     365 *                      requested. A negative identifier is requested if set to
     366 *                      false.
     367 * @returns             The new socket identifier.
     368 * @returns             ELIMIT if there is no socket identifier available.
     369 */
     370static int socket_generate_new_id(socket_cores_ref local_sockets, int positive)
     371{
    267372        int socket_id;
    268373        int count;
     
    270375        count = 0;
    271376//      socket_id = socket_globals.last_id;
    272         do{
    273                 if(count < SOCKET_ID_TRIES){
     377        do {
     378                if (count < SOCKET_ID_TRIES) {
    274379                        socket_id = rand() % INT_MAX;
    275                         ++ count;
    276                 }else if(count == SOCKET_ID_TRIES){
     380                        ++count;
     381                } else if (count == SOCKET_ID_TRIES) {
    277382                        socket_id = 1;
    278                         ++ count;
     383                        ++count;
    279384                // only this branch for last_id
    280                 }else{
    281                         if(socket_id < INT_MAX){
     385                } else {
     386                        if (socket_id < INT_MAX) {
    282387                                ++ socket_id;
    283 /*                      }else if(socket_globals.last_id){
     388/*                      } else if(socket_globals.last_id) {
    284389*                               socket_globals.last_id = 0;
    285390*                               socket_id = 1;
    286 */                      }else{
     391*/                      } else {
    287392                                return ELIMIT;
    288393                        }
    289394                }
    290         }while(socket_cores_find(local_sockets, ((positive ? 1 : -1) * socket_id)));
     395        } while (socket_cores_find(local_sockets,
     396            ((positive ? 1 : -1) * socket_id)));
     397       
    291398//      last_id = socket_id
    292399        return socket_id;
    293400}
    294401
    295 int socket_create(socket_cores_ref local_sockets, int app_phone, void * specific_data, int * socket_id){
     402/** Creates a new socket.
     403 *
     404 * @param[in,out] local_sockets The local sockets to be updated.
     405 * @param[in] app_phone The application phone.
     406 * @param[in] specific_data The socket specific data.
     407 * @param[in,out] socket_id The new socket identifier. A new identifier is
     408 *                      chosen if set to zero or negative. A negative identifier
     409 *                      is chosen if set to negative.
     410 * @returns             EOK on success.
     411 * @returns             EINVAL if the socket_id parameter is NULL.
     412 * @returns             ENOMEM if there is not enough memory left.
     413 */
     414int
     415socket_create(socket_cores_ref local_sockets, int app_phone,
     416    void *specific_data, int *socket_id)
     417{
    296418        ERROR_DECLARE;
    297419
     
    300422        int positive;
    301423
    302         if(! socket_id){
     424        if (!socket_id)
    303425                return EINVAL;
    304         }
     426       
    305427        // store the socket
    306         if(*socket_id <= 0){
     428        if (*socket_id <= 0) {
    307429                positive = (*socket_id == 0);
    308430                *socket_id = socket_generate_new_id(local_sockets, positive);
    309                 if(*socket_id <= 0){
    310                         return * socket_id;
    311                 }
    312                 if(! positive){
     431                if (*socket_id <= 0)
     432                        return *socket_id;
     433                if (!positive)
    313434                        *socket_id *= -1;
    314                 }
    315         }else if(socket_cores_find(local_sockets, * socket_id)){
     435        } else if(socket_cores_find(local_sockets, *socket_id)) {
    316436                return EEXIST;
    317437        }
     438       
    318439        socket = (socket_core_ref) malloc(sizeof(*socket));
    319         if(! socket){
     440        if (!socket)
    320441                return ENOMEM;
    321         }
     442       
    322443        // initialize
    323444        socket->phone = app_phone;
     
    326447        socket->key_length = 0;
    327448        socket->specific_data = specific_data;
    328         if(ERROR_OCCURRED(dyn_fifo_initialize(&socket->received, SOCKET_INITIAL_RECEIVED_SIZE))){
     449        if (ERROR_OCCURRED(dyn_fifo_initialize(&socket->received,
     450            SOCKET_INITIAL_RECEIVED_SIZE))) {
    329451                free(socket);
    330452                return ERROR_CODE;
    331453        }
    332         if(ERROR_OCCURRED(dyn_fifo_initialize(&socket->accepted, SOCKET_INITIAL_ACCEPTED_SIZE))){
     454        if (ERROR_OCCURRED(dyn_fifo_initialize(&socket->accepted,
     455            SOCKET_INITIAL_ACCEPTED_SIZE))) {
    333456                dyn_fifo_destroy(&socket->received);
    334457                free(socket);
    335458                return ERROR_CODE;
    336459        }
    337         socket->socket_id = * socket_id;
     460        socket->socket_id = *socket_id;
    338461        res = socket_cores_add(local_sockets, socket->socket_id, socket);
    339         if(res < 0){
     462        if (res < 0) {
    340463                dyn_fifo_destroy(&socket->received);
    341464                dyn_fifo_destroy(&socket->accepted);
     
    343466                return res;
    344467        }
     468       
    345469        return EOK;
    346470}
    347471
    348 int socket_destroy(int packet_phone, int socket_id, socket_cores_ref local_sockets, socket_ports_ref global_sockets, void (*socket_release)(socket_core_ref socket)){
     472/** Destroys the socket.
     473 *
     474 * If the socket is bound, the port is released.
     475 * Releases all buffered packets, calls the release function and removes the
     476 * socket from the local sockets.
     477 *
     478 * @param[in] packet_phone The packet server phone to release buffered packets.
     479 * @param[in] socket_id The socket identifier.
     480 * @param[in,out] local_sockets The local sockets to be updated.
     481 * @param[in,out] global_sockets The global sockets to be updated.
     482 * @param[in] socket_release The client release callback function.
     483 * @returns             EOK on success.
     484 * @returns             ENOTSOCK if the socket is not found.
     485 */
     486int
     487socket_destroy(int packet_phone, int socket_id, socket_cores_ref local_sockets,
     488    socket_ports_ref global_sockets,
     489    void (*socket_release)(socket_core_ref socket))
     490{
    349491        socket_core_ref socket;
    350492        int accepted_id;
     
    352494        // find the socket
    353495        socket = socket_cores_find(local_sockets, socket_id);
    354         if(! socket){
     496        if (!socket)
    355497                return ENOTSOCK;
    356         }
     498       
    357499        // destroy all accepted sockets
    358         while((accepted_id = dyn_fifo_pop(&socket->accepted)) >= 0){
    359                 socket_destroy(packet_phone, accepted_id, local_sockets, global_sockets, socket_release);
    360         }
    361         socket_destroy_core(packet_phone, socket, local_sockets, global_sockets, socket_release);
     500        while ((accepted_id = dyn_fifo_pop(&socket->accepted)) >= 0)
     501                socket_destroy(packet_phone, accepted_id, local_sockets,
     502                    global_sockets, socket_release);
     503       
     504        socket_destroy_core(packet_phone, socket, local_sockets, global_sockets,
     505            socket_release);
     506       
    362507        return EOK;
    363508}
    364509
    365 int socket_reply_packets(packet_t packet, size_t * length){
     510/** Replies the packet or the packet queue data to the application via the
     511 * socket.
     512 *
     513 * Uses the current message processing fibril.
     514 *
     515 * @param[in] packet    The packet to be transfered.
     516 * @param[out] length   The total data length.
     517 * @returns             EOK on success.
     518 * @returns             EBADMEM if the length parameter is NULL.
     519 * @returns             ENOMEM if there is not enough memory left.
     520 * @returns             Other error codes as defined for the data_reply()
     521 *                      function.
     522 */
     523int socket_reply_packets(packet_t packet, size_t *length)
     524{
    366525        ERROR_DECLARE;
    367526
    368527        packet_t next_packet;
    369528        size_t fragments;
    370         size_t * lengths;
     529        size_t *lengths;
    371530        size_t index;
    372531
    373         if(! length){
     532        if (!length)
    374533                return EBADMEM;
    375         }
     534
    376535        next_packet = pq_next(packet);
    377         if(! next_packet){
     536        if (!next_packet) {
    378537                // write all if only one fragment
    379                 ERROR_PROPAGATE(data_reply(packet_get_data(packet), packet_get_data_length(packet)));
     538                ERROR_PROPAGATE(data_reply(packet_get_data(packet),
     539                    packet_get_data_length(packet)));
    380540                // store the total length
    381541                *length = packet_get_data_length(packet);
    382         }else{
     542        } else {
    383543                // count the packet fragments
    384544                fragments = 1;
    385545                next_packet = pq_next(packet);
    386                 while((next_packet = pq_next(next_packet))){
    387                         ++ fragments;
    388                 }
     546                while ((next_packet = pq_next(next_packet)))
     547                        ++fragments;
     548               
    389549                // compute and store the fragment lengths
    390                 lengths = (size_t *) malloc(sizeof(size_t) * fragments + sizeof(size_t));
    391                 if(! lengths){
     550                lengths = (size_t *) malloc(sizeof(size_t) * fragments +
     551                    sizeof(size_t));
     552                if (!lengths)
    392553                        return ENOMEM;
    393                 }
     554               
    394555                lengths[0] = packet_get_data_length(packet);
    395556                lengths[fragments] = lengths[0];
    396557                next_packet = pq_next(packet);
    397                 for(index = 1; index < fragments; ++ index){
     558               
     559                for (index = 1; index < fragments; ++index) {
    398560                        lengths[index] = packet_get_data_length(next_packet);
    399561                        lengths[fragments] += lengths[index];
    400562                        next_packet = pq_next(packet);
    401                 }while(next_packet);
     563                }
     564               
    402565                // write the fragment lengths
    403                 ERROR_PROPAGATE(data_reply(lengths, sizeof(int) * (fragments + 1)));
     566                ERROR_PROPAGATE(data_reply(lengths,
     567                    sizeof(int) * (fragments + 1)));
    404568                next_packet = packet;
     569               
    405570                // write the fragments
    406                 for(index = 0; index < fragments; ++ index){
    407                         ERROR_PROPAGATE(data_reply(packet_get_data(next_packet), lengths[index]));
     571                for (index = 0; index < fragments; ++index) {
     572                        ERROR_PROPAGATE(data_reply(packet_get_data(next_packet),
     573                            lengths[index]));
    408574                        next_packet = pq_next(next_packet);
    409                 }while(next_packet);
     575                }
     576               
    410577                // store the total length
    411578                *length = lengths[fragments];
    412579                free(lengths);
    413580        }
     581       
    414582        return EOK;
    415583}
    416584
    417 socket_core_ref socket_port_find(socket_ports_ref global_sockets, int port, const char * key, size_t key_length){
     585/** Finds the bound port socket.
     586 *
     587 * @param[in] global_sockets The global sockets to be searched.
     588 * @param[in] port      The port number.
     589 * @param[in] key       The socket key identifier.
     590 * @param[in] key_length The socket key length.
     591 * @returns             The found socket.
     592 * @returns             NULL if no socket was found.
     593 */
     594socket_core_ref
     595socket_port_find(socket_ports_ref global_sockets, int port, const char *key,
     596    size_t key_length)
     597{
    418598        socket_port_ref socket_port;
    419         socket_core_ref * socket_ref;
     599        socket_core_ref *socket_ref;
    420600
    421601        socket_port = socket_ports_find(global_sockets, port);
    422         if(socket_port && (socket_port->count > 0)){
    423                 socket_ref = socket_port_map_find(&socket_port->map, key, key_length);
    424                 if(socket_ref){
    425                         return * socket_ref;
    426                 }
    427         }
     602        if (socket_port && (socket_port->count > 0)) {
     603                socket_ref = socket_port_map_find(&socket_port->map, key,
     604                    key_length);
     605                if (socket_ref)
     606                        return *socket_ref;
     607        }
     608       
    428609        return NULL;
    429610}
    430611
    431 void socket_port_release(socket_ports_ref global_sockets, socket_core_ref socket){
     612/** Releases the socket port.
     613 *
     614 * If the socket is bound the port entry is released.
     615 * If there are no more port entries the port is release.
     616 *
     617 * @param[in] global_sockets The global sockets to be updated.
     618 * @param[in] socket    The socket to be unbound.
     619 */
     620void
     621socket_port_release(socket_ports_ref global_sockets, socket_core_ref socket)
     622{
    432623        socket_port_ref socket_port;
    433         socket_core_ref * socket_ref;
    434 
    435         if(socket->port){
    436                 // find ports
    437                 socket_port = socket_ports_find(global_sockets, socket->port);
    438                 if(socket_port){
    439                         // find the socket
    440                         socket_ref = socket_port_map_find(&socket_port->map, socket->key, socket->key_length);
    441                         if(socket_ref){
    442                                 -- socket_port->count;
    443                                 // release if empty
    444                                 if(socket_port->count <= 0){
    445                                         // destroy the map
    446                                         socket_port_map_destroy(&socket_port->map);
    447                                         // release the port
    448                                         socket_ports_exclude(global_sockets, socket->port);
    449                                 }else{
    450                                         // remove
    451                                         socket_port_map_exclude(&socket_port->map, socket->key, socket->key_length);
    452                                 }
     624        socket_core_ref *socket_ref;
     625
     626        if (!socket->port)
     627                return;
     628       
     629        // find ports
     630        socket_port = socket_ports_find(global_sockets, socket->port);
     631        if (socket_port) {
     632                // find the socket
     633                socket_ref = socket_port_map_find(&socket_port->map,
     634                    socket->key, socket->key_length);
     635               
     636                if (socket_ref) {
     637                        --socket_port->count;
     638                       
     639                        // release if empty
     640                        if (socket_port->count <= 0) {
     641                                // destroy the map
     642                                socket_port_map_destroy(&socket_port->map);
     643                                // release the port
     644                                socket_ports_exclude(global_sockets,
     645                                    socket->port);
     646                        } else {
     647                                // remove
     648                                socket_port_map_exclude(&socket_port->map,
     649                                    socket->key, socket->key_length);
    453650                        }
    454651                }
    455                 socket->port = 0;
    456                 socket->key = NULL;
    457                 socket->key_length = 0;
    458         }
    459 }
    460 
    461 int socket_port_add(socket_ports_ref global_sockets, int port, socket_core_ref socket, const char * key, size_t key_length){
     652        }
     653       
     654        socket->port = 0;
     655        socket->key = NULL;
     656        socket->key_length = 0;
     657}
     658
     659/** Adds the socket to an already bound port.
     660 *
     661 * @param[in] global_sockets The global sockets to be updated.
     662 * @param[in] port      The port number to be bound to.
     663 * @param[in] socket    The socket to be added.
     664 * @param[in] key       The socket key identifier.
     665 * @param[in] key_length The socket key length.
     666 * @returns             EOK on success.
     667 * @returns             ENOENT if the port is not already used.
     668 * @returns             Other error codes as defined for the
     669 *                      socket_port_add_core() function.
     670 */
     671int
     672socket_port_add(socket_ports_ref global_sockets, int port,
     673    socket_core_ref socket, const char *key, size_t key_length)
     674{
    462675        ERROR_DECLARE;
    463676
     
    466679        // find ports
    467680        socket_port = socket_ports_find(global_sockets, port);
    468         if(! socket_port){
     681        if (!socket_port)
    469682                return ENOENT;
    470         }
     683       
    471684        // add the socket
    472         ERROR_PROPAGATE(socket_port_add_core(socket_port, socket, key, key_length));
     685        ERROR_PROPAGATE(socket_port_add_core(socket_port, socket, key,
     686            key_length));
     687       
    473688        socket->port = port;
    474689        return EOK;
  • uspace/lib/net/include/socket_core.h

    r25d2de69 r137f8aa  
    2727 */
    2828
    29 /** @addtogroup socket
     29/** @addtogroup libnet
    3030 *  @{
    3131 */
    3232
    3333/** @file
    34  *  Socket common core.
     34 * Socket common core.
    3535 */
    3636
    37 #ifndef __NET_SOCKET_CORE_H__
    38 #define __NET_SOCKET_CORE_H__
     37#ifndef LIBNET_SOCKET_CORE_H_
     38#define LIBNET_SOCKET_CORE_H_
    3939
    4040#include <sys/types.h>
    41 
    42 #include <net/in.h>
    43 #include <net/device.h>
    4441#include <adt/generic_char_map.h>
    4542#include <adt/dynamic_fifo.h>
    4643#include <adt/int_map.h>
     44#include <net/in.h>
     45#include <net/device.h>
    4746#include <net/packet.h>
    4847
    49 /** Initial size of the received packet queue.
    50  */
     48/** Initial size of the received packet queue. */
    5149#define SOCKET_INITIAL_RECEIVED_SIZE    4
    5250
    53 /** Maximum size of the received packet queue.
    54  */
    55 #define SOCKET_MAX_RECEIVED_SIZE                0
     51/** Maximum size of the received packet queue. */
     52#define SOCKET_MAX_RECEIVED_SIZE        0
    5653
    57 /** Initial size of the sockets for acceptance queue.
    58  */
     54/** Initial size of the sockets for acceptance queue. */
    5955#define SOCKET_INITIAL_ACCEPTED_SIZE    1
    6056
    61 /** Maximum size of the sockets for acceptance queue.
    62  */
    63 #define SOCKET_MAX_ACCEPTEDED_SIZE              0
     57/** Maximum size of the sockets for acceptance queue. */
     58#define SOCKET_MAX_ACCEPTEDED_SIZE      0
    6459
    65 /** Listening sockets' port map key.
    66  */
     60/** Listening sockets' port map key. */
    6761#define SOCKET_MAP_KEY_LISTENING        "L"
    6862
    6963/** Type definition of the socket core.
    70  *  @see socket_core
     64 * @see socket_core
    7165 */
    72 typedef struct socket_core      socket_core_t;
     66typedef struct socket_core socket_core_t;
    7367
    7468/** Type definition of the socket core pointer.
    75  *  @see socket_core
     69 * @see socket_core
    7670 */
    77 typedef socket_core_t * socket_core_ref;
     71typedef socket_core_t *socket_core_ref;
    7872
    7973/** Type definition of the socket port.
    80  *  @see socket_port
     74 * @see socket_port
    8175 */
    82 typedef struct socket_port      socket_port_t;
     76typedef struct socket_port socket_port_t;
    8377
    8478/** Type definition of the socket port pointer.
    85  *  @see socket_port
     79 * @see socket_port
    8680 */
    87 typedef socket_port_t * socket_port_ref;
     81typedef socket_port_t *socket_port_ref;
    8882
    89 /** Socket core.
    90  */
    91 struct socket_core{
    92         /** Socket identifier.
    93          */
     83/** Socket core. */
     84struct socket_core {
     85        /** Socket identifier. */
    9486        int socket_id;
    95         /** Client application phone.
    96          */
     87        /** Client application phone. */
    9788        int phone;
    98         /** Bound port.
    99          */
     89        /** Bound port. */
    10090        int port;
    101         /** Received packets queue.
    102          */
     91        /** Received packets queue. */
    10392        dyn_fifo_t received;
    104         /** Sockets for acceptance queue.
    105          */
     93        /** Sockets for acceptance queue. */
    10694        dyn_fifo_t accepted;
    107         /** Protocol specific data.
    108          */
    109         void * specific_data;
    110         /** Socket ports map key.
    111          */
    112         const char * key;
    113         /** Length of the Socket ports map key.
    114          */
     95        /** Protocol specific data. */
     96        void *specific_data;
     97        /** Socket ports map key. */
     98        const char *key;
     99        /** Length of the Socket ports map key. */
    115100        size_t key_length;
    116101};
    117102
    118103/** Sockets map.
    119  *  The key is the socket identifier.
     104 * The key is the socket identifier.
    120105 */
    121106INT_MAP_DECLARE(socket_cores, socket_core_t);
    122107
    123108/** Bount port sockets map.
    124  *  The listening socket has the SOCKET_MAP_KEY_LISTENING key identifier whereas the other use the remote addresses.
     109 *
     110 * The listening socket has the SOCKET_MAP_KEY_LISTENING key identifier whereas
     111 * the other use the remote addresses.
    125112 */
    126113GENERIC_CHAR_MAP_DECLARE(socket_port_map, socket_core_ref);
    127114
    128115/** Ports map.
    129  *  The key is the port number.
     116 * The key is the port number.
    130117 */
    131118INT_MAP_DECLARE(socket_ports, socket_port_t);
    132119
    133 /** Destroys local sockets.
    134  *  Releases all buffered packets and calls the release function for each of the sockets.
    135  *  @param[in] packet_phone The packet server phone to release buffered packets.
    136  *  @param[in] local_sockets The local sockets to be destroyed.
    137  *  @param[in,out] global_sockets The global sockets to be updated.
    138  *  @param[in] socket_release The client release callback function.
    139  */
    140 extern void socket_cores_release(int packet_phone, socket_cores_ref local_sockets, socket_ports_ref global_sockets, void (*socket_release)(socket_core_ref socket));
    141 
    142 /** Binds the socket to the port.
    143  *  The address port is used if set, a free port is used if not.
    144  *  @param[in] local_sockets The local sockets to be searched.
    145  *  @param[in,out] global_sockets The global sockets to be updated.
    146  *  @param[in] socket_id The new socket identifier.
    147  *  @param[in] addr The address to be bound to.
    148  *  @param[in] addrlen The address length.
    149  *  @param[in] free_ports_start The minimum free port.
    150  *  @param[in] free_ports_end The maximum free port.
    151  *  @param[in] last_used_port The last used free port.
    152  *  @returns EOK on success.
    153  *  @returns ENOTSOCK if the socket was not found.
    154  *  @returns EAFNOSUPPORT if the address family is not supported.
    155  *  @returns EADDRINUSE if the port is already in use.
    156  *  @returns Other error codes as defined for the socket_bind_free_port() function.
    157  *  @returns Other error codes as defined for the socket_bind_insert() function.
    158  */
    159 extern int socket_bind(socket_cores_ref local_sockets, socket_ports_ref global_sockets, int socket_id, void * addr, size_t addrlen, int free_ports_start, int free_ports_end, int last_used_port);
    160 
    161 /** Binds the socket to a free port.
    162  *  The first free port is used.
    163  *  @param[in,out] global_sockets The global sockets to be updated.
    164  *  @param[in,out] socket The socket to be bound.
    165  *  @param[in] free_ports_start The minimum free port.
    166  *  @param[in] free_ports_end The maximum free port.
    167  *  @param[in] last_used_port The last used free port.
    168  *  @returns EOK on success.
    169  *  @returns ENOTCONN if no free port was found.
    170  *  @returns Other error codes as defined for the socket_bind_insert() function.
    171  */
    172 extern int socket_bind_free_port(socket_ports_ref global_sockets, socket_core_ref socket, int free_ports_start, int free_ports_end, int last_used_port);
    173 
    174 /** Creates a new socket.
    175  *  @param[in,out] local_sockets The local sockets to be updated.
    176  *  @param[in] app_phone The application phone.
    177  *  @param[in] specific_data The socket specific data.
    178  *  @param[in,out] socket_id The new socket identifier. A new identifier is chosen if set to zero (0) or negative. A negative identifier is chosen if set to negative.
    179  *  @returns EOK on success.
    180  *  @returns EINVAL if the socket_id parameter is NULL.
    181  *  @returns ENOMEM if there is not enough memory left.
    182  */
    183 extern int socket_create(socket_cores_ref local_sockets, int app_phone, void * specific_data, int * socket_id);
    184 
    185 /** Destroys the socket.
    186  *  If the socket is bound, the port is released.
    187  *  Releases all buffered packets, calls the release function and removes the socket from the local sockets.
    188  *  @param[in] packet_phone The packet server phone to release buffered packets.
    189  *  @param[in] socket_id The socket identifier.
    190  *  @param[in,out] local_sockets The local sockets to be updated.
    191  *  @param[in,out] global_sockets The global sockets to be updated.
    192  *  @param[in] socket_release The client release callback function.
    193  *  @returns EOK on success.
    194  *  @returns ENOTSOCK if the socket is not found.
    195  */
    196 extern int socket_destroy(int packet_phone, int socket_id, socket_cores_ref local_sockets, socket_ports_ref global_sockets, void (*socket_release)(socket_core_ref socket));
    197 
    198 /** Replies the packet or the packet queue data to the application via the socket.
    199  *  Uses the current message processing fibril.
    200  *  @param[in] packet The packet to be transfered.
    201  *  @param[out] length The total data length.
    202  *  @returns EOK on success.
    203  *  @returns EBADMEM if the length parameter is NULL.
    204  *  @returns ENOMEM if there is not enough memory left.
    205  *  @returns Other error codes as defined for the data_reply() function.
    206  */
    207 extern int socket_reply_packets(packet_t packet, size_t * length);
    208 
    209 /** Finds the bound port socket.
    210  *  @param[in] global_sockets The global sockets to be searched.
    211  *  @param[in] port The port number.
    212  *  @param[in] key The socket key identifier.
    213  *  @param[in] key_length The socket key length.
    214  *  @returns The found socket.
    215  *  @returns NULL if no socket was found.
    216  */
    217 extern socket_core_ref socket_port_find(socket_ports_ref global_sockets, int port, const char * key, size_t key_length);
    218 
    219 /** Releases the socket port.
    220  *  If the socket is bound the port entry is released.
    221  *  If there are no more port entries the port is release.
    222  *  @param[in] global_sockets The global sockets to be updated.
    223  *  @param[in] socket The socket to be unbound.
    224  */
    225 extern void socket_port_release(socket_ports_ref global_sockets, socket_core_ref socket);
    226 
    227 /** Adds the socket to an already bound port.
    228  *  @param[in] global_sockets The global sockets to be updated.
    229  *  @param[in] port The port number to be bound to.
    230  *  @param[in] socket The socket to be added.
    231  *  @param[in] key The socket key identifier.
    232  *  @param[in] key_length The socket key length.
    233  *  @returns EOK on success.
    234  *  @returns ENOENT if the port is not already used.
    235  *  @returns Other error codes as defined for the socket_port_add_core() function.
    236  */
    237 extern int socket_port_add(socket_ports_ref global_sockets, int port, socket_core_ref socket, const char * key, size_t key_length);
     120extern void socket_cores_release(int, socket_cores_ref, socket_ports_ref,
     121    void (*)(socket_core_ref));
     122extern int socket_bind(socket_cores_ref, socket_ports_ref, int, void *, size_t,
     123    int, int, int);
     124extern int socket_bind_free_port(socket_ports_ref, socket_core_ref, int, int,
     125    int);
     126extern int socket_create(socket_cores_ref, int, void *, int *);
     127extern int socket_destroy(int, int, socket_cores_ref, socket_ports_ref,
     128    void (*)(socket_core_ref));
     129extern int socket_reply_packets(packet_t, size_t *);
     130extern socket_core_ref socket_port_find(socket_ports_ref, int, const char *,
     131    size_t);
     132extern void socket_port_release(socket_ports_ref, socket_core_ref);
     133extern int socket_port_add(socket_ports_ref, int, socket_core_ref,
     134    const char *, size_t);
    238135
    239136#endif
Note: See TracChangeset for help on using the changeset viewer.