Ignore:
Timestamp:
2010-04-04T22:07:05Z (14 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
23de644
Parents:
9f10660f (diff), 73060801 (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 moved

Legend:

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

    r9f10660f r3aae4e8  
    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;
Note: See TracChangeset for help on using the changeset viewer.