Changeset 849ed54 in mainline for uspace/lib/socket/generic


Ignore:
Timestamp:
2010-03-30T18:39:04Z (16 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
7553689
Parents:
7d6fe4db
Message:

Networking work:
Split the networking stack into end-user library (libsocket) and two helper libraries (libnet and libnetif).
Don't use over-the-hand compiling and linking, but rather separation of conserns.
There might be still some issues and the non-modular networking architecture is currently broken, but this will be fixed soon.

Location:
uspace/lib/socket/generic
Files:
6 moved

Legend:

Unmodified
Added
Removed
  • uspace/lib/socket/generic/icmp_api.c

    r7d6fe4db r849ed54  
    4343#include <sys/types.h>
    4444
    45 #include "../../modules.h"
    46 
    47 #include "../../include/icmp_api.h"
    48 #include "../../include/inet.h"
    49 #include "../../include/ip_codes.h"
    50 #include "../../include/socket_codes.h"
    51 
    52 #include "icmp_messages.h"
     45#include <net_modules.h>
     46#include <icmp_api.h>
     47#include <inet.h>
     48#include <ip_codes.h>
     49#include <socket_codes.h>
     50#include <icmp_messages.h>
    5351
    5452int icmp_echo_msg(int icmp_phone, size_t size, mseconds_t timeout, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, const struct sockaddr * addr, socklen_t addrlen){
  • uspace/lib/socket/generic/icmp_common.c

    r7d6fe4db r849ed54  
    3939#include <ipc/services.h>
    4040
    41 #include "../../modules.h"
    42 
    43 #include "../../include/icmp_common.h"
    44 
    45 #include "icmp_messages.h"
     41#include <net_modules.h>
     42#include <icmp_common.h>
     43#include <icmp_messages.h>
    4644
    4745int icmp_connect_module(services_t service, suseconds_t timeout){
  • uspace/lib/socket/generic/inet.c

    r7d6fe4db r849ed54  
    4040#include <str.h>
    4141
    42 #include "include/in.h"
    43 #include "include/in6.h"
    44 #include "include/inet.h"
    45 #include "include/socket_codes.h"
     42#include <in.h>
     43#include <in6.h>
     44#include <inet.h>
     45#include <socket_codes.h>
    4646
    4747int inet_ntop(uint16_t family, const uint8_t * data, char * address, size_t length){
  • uspace/lib/socket/generic/net_modules.c

    r7d6fe4db r849ed54  
    4343#include <sys/time.h>
    4444
    45 #include "err.h"
    46 #include "modules.h"
     45#include <net_err.h>
     46#include <net_modules.h>
    4747
    4848/** The time between connect requests in microseconds.
  • uspace/lib/socket/generic/socket_client.c

    r7d6fe4db r849ed54  
    4545#include <ipc/services.h>
    4646
    47 #include "../err.h"
    48 #include "../modules.h"
    49 
    50 #include "../include/in.h"
    51 #include "../include/socket.h"
    52 #include "../include/socket_errno.h"
    53 
    54 #include "../structures/dynamic_fifo.h"
    55 #include "../structures/int_map.h"
    56 
    57 #include "socket_messages.h"
     47#include <net_err.h>
     48#include <net_modules.h>
     49#include <in.h>
     50#include <socket.h>
     51#include <socket_errno.h>
     52#include <adt/dynamic_fifo.h>
     53#include <adt/int_map.h>
     54#include <socket_messages.h>
    5855
    5956/** Initial received packet queue size.
     
    191188INT_MAP_IMPLEMENT(sockets, socket_t);
    192189
    193 /** Returns the TCP module phone.
    194  *  Connects to the TCP module if necessary.
    195  *  @returns The TCP module phone.
    196  *  @returns Other error codes as defined for the bind_service_timeout() function.
    197  */
    198 static int socket_get_tcp_phone(void);
    199 
    200 /** Returns the UDP module phone.
    201  *  Connects to the UDP module if necessary.
    202  *  @returns The UDP module phone.
    203  *  @returns Other error codes as defined for the bind_service_timeout() function.
    204  */
    205 static int socket_get_udp_phone(void);
    206 
    207190/** Returns the active sockets.
    208191 *  @returns The active sockets.
    209192 */
    210 static sockets_ref socket_get_sockets(void);
    211 
    212 /** Tries to find a new free socket identifier.
    213  *      @returns The new socket identifier.
    214  *  @returns ELIMIT if there is no socket identifier available.
    215  */
    216 static int socket_generate_new_id(void);
    217 
    218 /** Default thread for new connections.
    219  *  @param[in] iid The initial message identifier.
    220  *  @param[in] icall The initial message call structure.
    221  */
    222 void socket_connection(ipc_callid_t iid, ipc_call_t * icall);
    223 
    224 /** Sends message to the socket parent module with specified data.
    225  *  @param[in] socket_id Socket identifier.
    226  *  @param[in] message The action message.
    227  *  @param[in] arg2 The second message parameter.
    228  *  @param[in] data The data to be sent.
    229  *  @param[in] datalength The data length.
    230  *  @returns EOK on success.
    231  *  @returns ENOTSOCK if the socket is not found.
    232  *  @returns EBADMEM if the data parameter is NULL.
    233  *  @returns NO_DATA if the datalength parameter is zero (0).
    234  *  @returns Other error codes as defined for the spcific message.
    235  */
    236 int socket_send_data(int socket_id, ipcarg_t message, ipcarg_t arg2, const void * data, size_t datalength);
    237 
    238 /** Initializes a new socket specific data.
    239  *  @param[in,out] socket The socket to be initialized.
    240  *  @param[in] socket_id The new socket identifier.
    241  *  @param[in] phone The parent module phone.
    242  *  @param[in] service The parent module service.
    243  */
    244 void socket_initialize(socket_ref socket, int socket_id, int phone, services_t service);
    245 
    246 /** Clears and destroys the socket.
    247  *  @param[in] socket The socket to be destroyed.
    248  */
    249 void socket_destroy(socket_ref socket);
    250 
    251 /** Receives data via the socket.
    252  *  @param[in] message The action message.
    253  *  @param[in] socket_id Socket identifier.
    254  *  @param[out] data The data buffer to be filled.
    255  *  @param[in] datalength The data length.
    256  *  @param[in] flags Various receive flags.
    257  *  @param[out] fromaddr The source address. May be NULL for connected sockets.
    258  *  @param[in,out] addrlen The address length. The maximum address length is read. The actual address length is set. Used only if fromaddr is not NULL.
    259  *  @returns EOK on success.
    260  *  @returns ENOTSOCK if the socket is not found.
    261  *  @returns EBADMEM if the data parameter is NULL.
    262  *  @returns NO_DATA if the datalength or addrlen parameter is zero (0).
    263  *  @returns Other error codes as defined for the spcific message.
    264  */
    265 int recvfrom_core(ipcarg_t message, int socket_id, void * data, size_t datalength, int flags, struct sockaddr * fromaddr, socklen_t * addrlen);
    266 
    267 /** Sends data via the socket to the remote address.
    268  *  Binds the socket to a free port if not already connected/bound.
    269  *  @param[in] message The action message.
    270  *  @param[in] socket_id Socket identifier.
    271  *  @param[in] data The data to be sent.
    272  *  @param[in] datalength The data length.
    273  *  @param[in] flags Various send flags.
    274  *  @param[in] toaddr The destination address. May be NULL for connected sockets.
    275  *  @param[in] addrlen The address length. Used only if toaddr is not NULL.
    276  *  @returns EOK on success.
    277  *  @returns ENOTSOCK if the socket is not found.
    278  *  @returns EBADMEM if the data or toaddr parameter is NULL.
    279  *  @returns NO_DATA if the datalength or the addrlen parameter is zero (0).
    280  *  @returns Other error codes as defined for the NET_SOCKET_SENDTO message.
    281  */
    282 int sendto_core(ipcarg_t message, int socket_id, const void * data, size_t datalength, int flags, const struct sockaddr * toaddr, socklen_t addrlen);
    283 
    284 static int socket_get_tcp_phone(void){
    285         if(socket_globals.tcp_phone < 0){
    286                 socket_globals.tcp_phone = bind_service_timeout(SERVICE_TCP, 0, 0, SERVICE_TCP, socket_connection, SOCKET_CONNECT_TIMEOUT);
    287         }
    288         return socket_globals.tcp_phone;
    289 }
    290 
    291 static int socket_get_udp_phone(void){
    292         if(socket_globals.udp_phone < 0){
    293                 socket_globals.udp_phone = bind_service_timeout(SERVICE_UDP, 0, 0, SERVICE_UDP, socket_connection, SOCKET_CONNECT_TIMEOUT);
    294         }
    295         return socket_globals.udp_phone;
    296 }
    297 
    298193static sockets_ref socket_get_sockets(void){
    299194        if(! socket_globals.sockets){
     
    311206}
    312207
    313 static int socket_generate_new_id(void){
    314         sockets_ref sockets;
    315         int socket_id;
    316         int count;
    317 
    318         sockets = socket_get_sockets();
    319         count = 0;
    320 //      socket_id = socket_globals.last_id;
    321         do{
    322                 if(count < SOCKET_ID_TRIES){
    323                         socket_id = rand() % INT_MAX;
    324                         ++ count;
    325                 }else if(count == SOCKET_ID_TRIES){
    326                         socket_id = 1;
    327                         ++ count;
    328                 // only this branch for last_id
    329                 }else{
    330                         if(socket_id < INT_MAX){
    331                                 ++ socket_id;
    332 /*                      }else if(socket_globals.last_id){
    333 *                               socket_globals.last_id = 0;
    334 *                               socket_id = 1;
    335 */                      }else{
    336                                 return ELIMIT;
    337                         }
    338                 }
    339         }while(sockets_find(sockets, socket_id));
    340 //      last_id = socket_id
    341         return socket_id;
    342 }
    343 
    344 void socket_initialize(socket_ref socket, int socket_id, int phone, services_t service){
    345         socket->socket_id = socket_id;
    346         socket->phone = phone;
    347         socket->service = service;
    348         dyn_fifo_initialize(&socket->received, SOCKET_INITIAL_RECEIVED_SIZE);
    349         dyn_fifo_initialize(&socket->accepted, SOCKET_INITIAL_ACCEPTED_SIZE);
    350         fibril_mutex_initialize(&socket->receive_lock);
    351         fibril_condvar_initialize(&socket->receive_signal);
    352         fibril_mutex_initialize(&socket->accept_lock);
    353         fibril_condvar_initialize(&socket->accept_signal);
    354         fibril_rwlock_initialize(&socket->sending_lock);
    355 }
    356 
    357 void socket_connection(ipc_callid_t iid, ipc_call_t * icall){
     208/** Default thread for new connections.
     209 *  @param[in] iid The initial message identifier.
     210 *  @param[in] icall The initial message call structure.
     211 */
     212static void socket_connection(ipc_callid_t iid, ipc_call_t * icall){
    358213        ERROR_DECLARE;
    359214
     
    414269}
    415270
     271/** Returns the TCP module phone.
     272 *  Connects to the TCP module if necessary.
     273 *  @returns The TCP module phone.
     274 *  @returns Other error codes as defined for the bind_service_timeout() function.
     275 */
     276static int socket_get_tcp_phone(void){
     277        if(socket_globals.tcp_phone < 0){
     278                socket_globals.tcp_phone = bind_service_timeout(SERVICE_TCP, 0, 0, SERVICE_TCP, socket_connection, SOCKET_CONNECT_TIMEOUT);
     279        }
     280        return socket_globals.tcp_phone;
     281}
     282
     283/** Returns the UDP module phone.
     284 *  Connects to the UDP module if necessary.
     285 *  @returns The UDP module phone.
     286 *  @returns Other error codes as defined for the bind_service_timeout() function.
     287 */
     288static int socket_get_udp_phone(void){
     289        if(socket_globals.udp_phone < 0){
     290                socket_globals.udp_phone = bind_service_timeout(SERVICE_UDP, 0, 0, SERVICE_UDP, socket_connection, SOCKET_CONNECT_TIMEOUT);
     291        }
     292        return socket_globals.udp_phone;
     293}
     294
     295/** Tries to find a new free socket identifier.
     296 *      @returns The new socket identifier.
     297 *  @returns ELIMIT if there is no socket identifier available.
     298 */
     299static int socket_generate_new_id(void){
     300        sockets_ref sockets;
     301        int socket_id;
     302        int count;
     303
     304        sockets = socket_get_sockets();
     305        count = 0;
     306//      socket_id = socket_globals.last_id;
     307        do{
     308                if(count < SOCKET_ID_TRIES){
     309                        socket_id = rand() % INT_MAX;
     310                        ++ count;
     311                }else if(count == SOCKET_ID_TRIES){
     312                        socket_id = 1;
     313                        ++ count;
     314                // only this branch for last_id
     315                }else{
     316                        if(socket_id < INT_MAX){
     317                                ++ socket_id;
     318/*                      }else if(socket_globals.last_id){
     319*                               socket_globals.last_id = 0;
     320*                               socket_id = 1;
     321*/                      }else{
     322                                return ELIMIT;
     323                        }
     324                }
     325        }while(sockets_find(sockets, socket_id));
     326//      last_id = socket_id
     327        return socket_id;
     328}
     329
     330/** Initializes a new socket specific data.
     331 *  @param[in,out] socket The socket to be initialized.
     332 *  @param[in] socket_id The new socket identifier.
     333 *  @param[in] phone The parent module phone.
     334 *  @param[in] service The parent module service.
     335 */
     336static void socket_initialize(socket_ref socket, int socket_id, int phone, services_t service){
     337        socket->socket_id = socket_id;
     338        socket->phone = phone;
     339        socket->service = service;
     340        dyn_fifo_initialize(&socket->received, SOCKET_INITIAL_RECEIVED_SIZE);
     341        dyn_fifo_initialize(&socket->accepted, SOCKET_INITIAL_ACCEPTED_SIZE);
     342        fibril_mutex_initialize(&socket->receive_lock);
     343        fibril_condvar_initialize(&socket->receive_signal);
     344        fibril_mutex_initialize(&socket->accept_lock);
     345        fibril_condvar_initialize(&socket->accept_signal);
     346        fibril_rwlock_initialize(&socket->sending_lock);
     347}
     348
    416349int socket(int domain, int type, int protocol){
    417350        ERROR_DECLARE;
     
    503436}
    504437
    505 int socket_send_data(int socket_id, ipcarg_t message, ipcarg_t arg2, const void * data, size_t datalength){
     438/** Sends message to the socket parent module with specified data.
     439 *  @param[in] socket_id Socket identifier.
     440 *  @param[in] message The action message.
     441 *  @param[in] arg2 The second message parameter.
     442 *  @param[in] data The data to be sent.
     443 *  @param[in] datalength The data length.
     444 *  @returns EOK on success.
     445 *  @returns ENOTSOCK if the socket is not found.
     446 *  @returns EBADMEM if the data parameter is NULL.
     447 *  @returns NO_DATA if the datalength parameter is zero (0).
     448 *  @returns Other error codes as defined for the spcific message.
     449 */
     450static int socket_send_data(int socket_id, ipcarg_t message, ipcarg_t arg2, const void * data, size_t datalength){
    506451        socket_ref socket;
    507452        aid_t message_id;
     
    650595}
    651596
     597/** Clears and destroys the socket.
     598 *  @param[in] socket The socket to be destroyed.
     599 */
     600static void socket_destroy(socket_ref socket){
     601        int accepted_id;
     602
     603        // destroy all accepted sockets
     604        while((accepted_id = dyn_fifo_pop(&socket->accepted)) >= 0){
     605                socket_destroy(sockets_find(socket_get_sockets(), accepted_id));
     606        }
     607        dyn_fifo_destroy(&socket->received);
     608        dyn_fifo_destroy(&socket->accepted);
     609        sockets_exclude(socket_get_sockets(), socket->socket_id);
     610}
     611
    652612int closesocket(int socket_id){
    653613        ERROR_DECLARE;
     
    673633}
    674634
    675 void socket_destroy(socket_ref socket){
    676         int accepted_id;
    677 
    678         // destroy all accepted sockets
    679         while((accepted_id = dyn_fifo_pop(&socket->accepted)) >= 0){
    680                 socket_destroy(sockets_find(socket_get_sockets(), accepted_id));
    681         }
    682         dyn_fifo_destroy(&socket->received);
    683         dyn_fifo_destroy(&socket->accepted);
    684         sockets_exclude(socket_get_sockets(), socket->socket_id);
    685 }
    686 
    687 int send(int socket_id, void * data, size_t datalength, int flags){
    688         // without the address
    689         return sendto_core(NET_SOCKET_SEND, socket_id, data, datalength, flags, NULL, 0);
    690 }
    691 
    692 int sendto(int socket_id, const void * data, size_t datalength, int flags, const struct sockaddr * toaddr, socklen_t addrlen){
    693         if(! toaddr){
    694                 return EDESTADDRREQ;
    695         }
    696         if(! addrlen){
    697                 return EDESTADDRREQ;
    698         }
    699         // with the address
    700         return sendto_core(NET_SOCKET_SENDTO, socket_id, data, datalength, flags, toaddr, addrlen);
    701 }
    702 
    703 int sendto_core(ipcarg_t message, int socket_id, const void * data, size_t datalength, int flags, const struct sockaddr * toaddr, socklen_t addrlen){
     635/** Sends data via the socket to the remote address.
     636 *  Binds the socket to a free port if not already connected/bound.
     637 *  @param[in] message The action message.
     638 *  @param[in] socket_id Socket identifier.
     639 *  @param[in] data The data to be sent.
     640 *  @param[in] datalength The data length.
     641 *  @param[in] flags Various send flags.
     642 *  @param[in] toaddr The destination address. May be NULL for connected sockets.
     643 *  @param[in] addrlen The address length. Used only if toaddr is not NULL.
     644 *  @returns EOK on success.
     645 *  @returns ENOTSOCK if the socket is not found.
     646 *  @returns EBADMEM if the data or toaddr parameter is NULL.
     647 *  @returns NO_DATA if the datalength or the addrlen parameter is zero (0).
     648 *  @returns Other error codes as defined for the NET_SOCKET_SENDTO message.
     649 */
     650static int sendto_core(ipcarg_t message, int socket_id, const void * data, size_t datalength, int flags, const struct sockaddr * toaddr, socklen_t addrlen){
    704651        socket_ref socket;
    705652        aid_t message_id;
     
    760707}
    761708
    762 int recv(int socket_id, void * data, size_t datalength, int flags){
     709int send(int socket_id, void * data, size_t datalength, int flags){
    763710        // without the address
    764         return recvfrom_core(NET_SOCKET_RECV, socket_id, data, datalength, flags, NULL, NULL);
    765 }
    766 
    767 int recvfrom(int socket_id, void * data, size_t datalength, int flags, struct sockaddr * fromaddr, socklen_t * addrlen){
    768         if(! fromaddr){
    769                 return EBADMEM;
     711        return sendto_core(NET_SOCKET_SEND, socket_id, data, datalength, flags, NULL, 0);
     712}
     713
     714int sendto(int socket_id, const void * data, size_t datalength, int flags, const struct sockaddr * toaddr, socklen_t addrlen){
     715        if(! toaddr){
     716                return EDESTADDRREQ;
    770717        }
    771718        if(! addrlen){
    772                 return NO_DATA;
     719                return EDESTADDRREQ;
    773720        }
    774721        // with the address
    775         return recvfrom_core(NET_SOCKET_RECVFROM, socket_id, data, datalength, flags, fromaddr, addrlen);
    776 }
    777 
    778 int recvfrom_core(ipcarg_t message, int socket_id, void * data, size_t datalength, int flags, struct sockaddr * fromaddr, socklen_t * addrlen){
     722        return sendto_core(NET_SOCKET_SENDTO, socket_id, data, datalength, flags, toaddr, addrlen);
     723}
     724
     725/** Receives data via the socket.
     726 *  @param[in] message The action message.
     727 *  @param[in] socket_id Socket identifier.
     728 *  @param[out] data The data buffer to be filled.
     729 *  @param[in] datalength The data length.
     730 *  @param[in] flags Various receive flags.
     731 *  @param[out] fromaddr The source address. May be NULL for connected sockets.
     732 *  @param[in,out] addrlen The address length. The maximum address length is read. The actual address length is set. Used only if fromaddr is not NULL.
     733 *  @returns EOK on success.
     734 *  @returns ENOTSOCK if the socket is not found.
     735 *  @returns EBADMEM if the data parameter is NULL.
     736 *  @returns NO_DATA if the datalength or addrlen parameter is zero (0).
     737 *  @returns Other error codes as defined for the spcific message.
     738 */
     739static int recvfrom_core(ipcarg_t message, int socket_id, void * data, size_t datalength, int flags, struct sockaddr * fromaddr, socklen_t * addrlen){
    779740        socket_ref socket;
    780741        aid_t message_id;
     
    866827}
    867828
     829int recv(int socket_id, void * data, size_t datalength, int flags){
     830        // without the address
     831        return recvfrom_core(NET_SOCKET_RECV, socket_id, data, datalength, flags, NULL, NULL);
     832}
     833
     834int recvfrom(int socket_id, void * data, size_t datalength, int flags, struct sockaddr * fromaddr, socklen_t * addrlen){
     835        if(! fromaddr){
     836                return EBADMEM;
     837        }
     838        if(! addrlen){
     839                return NO_DATA;
     840        }
     841        // with the address
     842        return recvfrom_core(NET_SOCKET_RECVFROM, socket_id, data, datalength, flags, fromaddr, addrlen);
     843}
     844
    868845int getsockopt(int socket_id, int level, int optname, void * value, size_t * optlen){
    869846        socket_ref socket;
  • uspace/lib/socket/generic/socket_core.c

    r7d6fe4db r849ed54  
    3838#include <stdlib.h>
    3939
    40 #include "../err.h"
    41 
    42 #include "../include/in.h"
    43 #include "../include/inet.h"
    44 
    45 #include "../include/socket_codes.h"
    46 #include "../include/socket_errno.h"
    47 
    48 #include "../structures/dynamic_fifo.h"
    49 #include "../structures/int_map.h"
    50 #include "../structures/packet/packet.h"
    51 #include "../structures/packet/packet_client.h"
    52 
    53 #include "../modules.h"
    54 
    55 #include "socket_core.h"
     40#include <net_err.h>
     41#include <in.h>
     42#include <inet.h>
     43#include <socket_codes.h>
     44#include <socket_errno.h>
     45#include <adt/dynamic_fifo.h>
     46#include <adt/int_map.h>
     47#include <packet/packet.h>
     48#include <packet/packet_client.h>
     49#include <net_modules.h>
     50#include <socket_core.h>
    5651
    5752/** Maximum number of random attempts to find a new socket identifier before switching to the sequence.
     
    7065};
    7166
    72 /** Binds the socket to the port.
    73  *  The SOCKET_MAP_KEY_LISTENING key identifier is used.
    74  *  @param[in] global_sockets The global sockets to be updated.
    75  *  @param[in] socket The socket to be added.
    76  *  @param[in] port The port number to be bound to.
    77  *  @returns EOK on success.
    78  *  @returns ENOMEM if there is not enough memory left.
    79  *  @returns Other error codes as defined for the socket_ports_add() function.
    80  */
    81 int socket_bind_insert(socket_ports_ref global_sockets, socket_core_ref socket, int port);
     67INT_MAP_IMPLEMENT(socket_cores, socket_core_t);
     68
     69GENERIC_CHAR_MAP_IMPLEMENT(socket_port_map, socket_core_ref);
     70
     71INT_MAP_IMPLEMENT(socket_ports, socket_port_t);
    8272
    8373/** Destroys the socket.
     
    9080 *  @param[in] socket_release The client release callback function.
    9181 */
    92 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));
    93 
    94 /** Adds the socket to a socket port.
    95  *  @param[in,out] socket_port The socket port structure.
    96  *  @param[in] socket The socket to be added.
    97  *  @param[in] key The socket key identifier.
    98  *  @param[in] key_length The socket key length.
    99  *  @returns EOK on success.
    100  *  @returns ENOMEM if there is not enough memory left.
    101  */
    102 int socket_port_add_core(socket_port_ref socket_port, socket_core_ref socket, const char * key, size_t key_length);
    103 
    104 /** Tries to find a new free socket identifier.
    105  *  @param[in] local_sockets The local sockets to be searched.
    106  *  @param[in] positive A value indicating whether a positive identifier is requested. A negative identifier is requested if set to false.
    107  *      @returns The new socket identifier.
    108  *  @returns ELIMIT if there is no socket identifier available.
    109  */
    110 static int socket_generate_new_id(socket_cores_ref local_sockets, int positive);
    111 
    112 INT_MAP_IMPLEMENT(socket_cores, socket_core_t);
    113 
    114 GENERIC_CHAR_MAP_IMPLEMENT(socket_port_map, socket_core_ref);
    115 
    116 INT_MAP_IMPLEMENT(socket_ports, socket_port_t);
     82static 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)){
     83        int packet_id;
     84
     85        // if bound
     86        if(socket->port){
     87                // release the port
     88                socket_port_release(global_sockets, socket);
     89        }
     90        // release all received packets
     91        while((packet_id = dyn_fifo_pop(&socket->received)) >= 0){
     92                pq_release(packet_phone, packet_id);
     93        }
     94        dyn_fifo_destroy(&socket->received);
     95        dyn_fifo_destroy(&socket->accepted);
     96        if(socket_release){
     97                socket_release(socket);
     98        }
     99        socket_cores_exclude(local_sockets, socket->socket_id);
     100}
    117101
    118102void socket_cores_release(int packet_phone, socket_cores_ref local_sockets, socket_ports_ref global_sockets, void (*socket_release)(socket_core_ref socket)){
     
    135119}
    136120
    137 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)){
    138         int packet_id;
    139 
    140         // if bound
    141         if(socket->port){
    142                 // release the port
    143                 socket_port_release(global_sockets, socket);
    144         }
    145         // release all received packets
    146         while((packet_id = dyn_fifo_pop(&socket->received)) >= 0){
    147                 pq_release(packet_phone, packet_id);
    148         }
    149         dyn_fifo_destroy(&socket->received);
    150         dyn_fifo_destroy(&socket->accepted);
    151         if(socket_release){
    152                 socket_release(socket);
    153         }
    154         socket_cores_exclude(local_sockets, socket->socket_id);
     121/** Adds the socket to a socket port.
     122 *  @param[in,out] socket_port The socket port structure.
     123 *  @param[in] socket The socket to be added.
     124 *  @param[in] key The socket key identifier.
     125 *  @param[in] key_length The socket key length.
     126 *  @returns EOK on success.
     127 *  @returns ENOMEM if there is not enough memory left.
     128 */
     129static int socket_port_add_core(socket_port_ref socket_port, socket_core_ref socket, const char * key, size_t key_length){
     130        ERROR_DECLARE;
     131
     132        socket_core_ref * socket_ref;
     133
     134        // create a wrapper
     135        socket_ref = malloc(sizeof(*socket_ref));
     136        if(! socket_ref){
     137                return ENOMEM;
     138        }
     139        *socket_ref = socket;
     140        // add the wrapper
     141        if(ERROR_OCCURRED(socket_port_map_add(&socket_port->map, key, key_length, socket_ref))){
     142                free(socket_ref);
     143                return ERROR_CODE;
     144        }
     145        ++ socket_port->count;
     146        socket->key = key;
     147        socket->key_length = key_length;
     148        return EOK;
     149}
     150
     151/** Binds the socket to the port.
     152 *  The SOCKET_MAP_KEY_LISTENING key identifier is used.
     153 *  @param[in] global_sockets The global sockets to be updated.
     154 *  @param[in] socket The socket to be added.
     155 *  @param[in] port The port number to be bound to.
     156 *  @returns EOK on success.
     157 *  @returns ENOMEM if there is not enough memory left.
     158 *  @returns Other error codes as defined for the socket_ports_add() function.
     159 */
     160static int socket_bind_insert(socket_ports_ref global_sockets, socket_core_ref socket, int port){
     161        ERROR_DECLARE;
     162
     163        socket_port_ref socket_port;
     164
     165        // create a wrapper
     166        socket_port = malloc(sizeof(*socket_port));
     167        if(! socket_port){
     168                return ENOMEM;
     169        }
     170        socket_port->count = 0;
     171        if(ERROR_OCCURRED(socket_port_map_initialize(&socket_port->map))
     172                || ERROR_OCCURRED(socket_port_add_core(socket_port, socket, SOCKET_MAP_KEY_LISTENING, 0))){
     173                socket_port_map_destroy(&socket_port->map);
     174                free(socket_port);
     175                return ERROR_CODE;
     176        }
     177        // register the incomming port
     178        ERROR_CODE = socket_ports_add(global_sockets, port, socket_port);
     179        if(ERROR_CODE < 0){
     180                socket_port_map_destroy(&socket_port->map);
     181                free(socket_port);
     182                return ERROR_CODE;
     183        }
     184        socket->port = port;
     185        return EOK;
    155186}
    156187
     
    225256}
    226257
    227 int socket_bind_insert(socket_ports_ref global_sockets, socket_core_ref socket, int port){
    228         ERROR_DECLARE;
    229 
    230         socket_port_ref socket_port;
    231 
    232         // create a wrapper
    233         socket_port = malloc(sizeof(*socket_port));
    234         if(! socket_port){
    235                 return ENOMEM;
    236         }
    237         socket_port->count = 0;
    238         if(ERROR_OCCURRED(socket_port_map_initialize(&socket_port->map))
    239                 || ERROR_OCCURRED(socket_port_add_core(socket_port, socket, SOCKET_MAP_KEY_LISTENING, 0))){
    240                 socket_port_map_destroy(&socket_port->map);
    241                 free(socket_port);
    242                 return ERROR_CODE;
    243         }
    244         // register the incomming port
    245         ERROR_CODE = socket_ports_add(global_sockets, port, socket_port);
    246         if(ERROR_CODE < 0){
    247                 socket_port_map_destroy(&socket_port->map);
    248                 free(socket_port);
    249                 return ERROR_CODE;
    250         }
    251         socket->port = port;
    252         return EOK;
    253 }
    254 
    255 
     258/** Tries to find a new free socket identifier.
     259 *  @param[in] local_sockets The local sockets to be searched.
     260 *  @param[in] positive A value indicating whether a positive identifier is requested. A negative identifier is requested if set to false.
     261 *      @returns The new socket identifier.
     262 *  @returns ELIMIT if there is no socket identifier available.
     263 */
    256264static int socket_generate_new_id(socket_cores_ref local_sockets, int positive){
    257265        int socket_id;
     
    465473}
    466474
    467 int socket_port_add_core(socket_port_ref socket_port, socket_core_ref socket, const char * key, size_t key_length){
    468         ERROR_DECLARE;
    469 
    470         socket_core_ref * socket_ref;
    471 
    472         // create a wrapper
    473         socket_ref = malloc(sizeof(*socket_ref));
    474         if(! socket_ref){
    475                 return ENOMEM;
    476         }
    477         *socket_ref = socket;
    478         // add the wrapper
    479         if(ERROR_OCCURRED(socket_port_map_add(&socket_port->map, key, key_length, socket_ref))){
    480                 free(socket_ref);
    481                 return ERROR_CODE;
    482         }
    483         ++ socket_port->count;
    484         socket->key = key;
    485         socket->key_length = key_length;
    486         return EOK;
    487 }
    488 
    489475/** @}
    490476 */
Note: See TracChangeset for help on using the changeset viewer.