Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 4707 → Rev 4708

/branches/network/uspace/srv/net/socket/socket_core.c
86,10 → 86,8
return socket_bind_insert( global_sockets, socket, address_in->sin_port );
break;
// TODO IPv6
default:
return EAFNOSUPPORT;
}
return EOK;
return EAFNOSUPPORT;
}
 
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 ){
/branches/network/uspace/srv/net/socket/socket_messages.h
44,6 → 44,8
 
#include "../messages.h"
 
#include "../include/socket.h"
 
typedef enum{
NET_SOCKET = NET_SOCKET_FIRST,
NET_SOCKET_BIND,
77,11 → 79,11
#define SOCKET_GET_OPT_LEVEL( call ) ( int ) IPC_GET_ARG2( call )
#define SOCKET_SET_DATA_FRAGMENTS( call ) ( int * ) & IPC_GET_ARG2( call )
#define SOCKET_GET_DATA_FRAGMENTS( call ) ( int ) IPC_GET_ARG2( call )
#define SOCKET_SET_ADDRESS_LENGTH( call ) ( size_t * ) & IPC_GET_ARG2( call )
#define SOCKET_GET_ADDRESS_LENGTH( call ) ( size_t ) IPC_GET_ARG2( call )
#define SOCKET_SET_ADDRESS_LENGTH( call ) ( socklen_t * ) & IPC_GET_ARG2( call )
#define SOCKET_GET_ADDRESS_LENGTH( call ) ( socklen_t ) IPC_GET_ARG2( call )
 
#define SOCKET_SET_DATA_FRAGMENT_SIZE( call ) ( int * ) & IPC_GET_ARG3( call )
#define SOCKET_GET_DATA_FRAGMENT_SIZE( call ) ( int ) IPC_GET_ARG3( call )
#define SOCKET_SET_DATA_FRAGMENT_SIZE( call ) ( size_t * ) & IPC_GET_ARG3( call )
#define SOCKET_GET_DATA_FRAGMENT_SIZE( call ) ( size_t ) IPC_GET_ARG3( call )
 
#define SOCKET_GET_FLAGS( call ) ( int ) IPC_GET_ARG4( call )
 
/branches/network/uspace/srv/net/socket/socket_client.c
95,11 → 95,11
/** Underlying protocol header size.
* Sending and receiving optimalization.
*/
int header_size;
size_t header_size;
/** Packet data fragment size.
* Sending and receiving optimalization.
*/
int data_fragment_size;
size_t data_fragment_size;
/** Received packets queue.
*/
dyn_fifo_t received;
146,18 → 146,18
* Connects to the TCP module if necessary.
* @returns The TCP module phone.
*/
static int socket_get_tcp_phone();
static int socket_get_tcp_phone( void );
 
/** Returns the UDP module phone.
* Connects to the UDP module if necessary.
* @returns The UDP module phone.
*/
static int socket_get_tcp_phone();
static int socket_get_udp_phone( void );
 
/** Returns the active sockets.
* @returns The active sockets.
*/
static sockets_ref socket_get_sockets();
static sockets_ref socket_get_sockets( void );
 
/** Default thread for new connections.
* @param iid The initial message identifier. Input parameter.
177,7 → 177,7
* @returns NO_DATA if the datalength parameter is zero (0).
* @returns Other error codes as defined for the spcific message.
*/
int socket_send_data( int socket_id, int message, ipcarg_t arg2, const void * data, size_t datalength );
int socket_send_data( int socket_id, ipcarg_t message, ipcarg_t arg2, const void * data, size_t datalength );
 
/** Initializes a new socket specific data.
* @param socket The socket to be initialized. Input/output parameter.
206,7 → 206,7
* @returns NO_DATA if the datalength or addrlen parameter is zero (0).
* @returns Other error codes as defined for the spcific message.
*/
int recvfrom_core( int message, int socket_id, void * data, size_t datalength, int flags, struct sockaddr * fromaddr, socklen_t * addrlen );
int recvfrom_core( ipcarg_t message, int socket_id, void * data, size_t datalength, int flags, struct sockaddr * fromaddr, socklen_t * addrlen );
 
/** Sends data via the socket to the remote address.
* Binds the socket to a free port if not already connected/bound.
223,9 → 223,9
* @returns NO_DATA if the datalength or the addrlen parameter is zero (0).
* @returns Other error codes as defined for the NET_SOCKET_SENDTO message.
*/
int sendto_core( int message, int socket_id, const void * data, size_t datalength, int flags, const struct sockaddr * toaddr, socklen_t addrlen );
int sendto_core( ipcarg_t message, int socket_id, const void * data, size_t datalength, int flags, const struct sockaddr * toaddr, socklen_t addrlen );
 
static int socket_get_tcp_phone(){
static int socket_get_tcp_phone( void ){
if( socket_globals.tcp_phone < 0 ){
socket_globals.tcp_phone = bind_service( SERVICE_TCP, 0, 0, SERVICE_TCP, socket_connection );
}
232,7 → 232,7
return socket_globals.tcp_phone;
}
 
static int socket_get_udp_phone(){
static int socket_get_udp_phone( void ){
if( socket_globals.udp_phone < 0 ){
socket_globals.udp_phone = bind_service( SERVICE_UDP, 0, 0, SERVICE_UDP, socket_connection );
}
239,7 → 239,7
return socket_globals.udp_phone;
}
 
static sockets_ref socket_get_sockets(){
static sockets_ref socket_get_sockets( void ){
if( ! socket_globals.sockets ){
socket_globals.sockets = ( sockets_ref ) malloc( sizeof( sockets_t ));
if( ! socket_globals.sockets ) return NULL;
335,7 → 335,7
default:
ERROR_CODE = ENOTSUP;
}
ipc_answer_0( callid, ERROR_CODE );
ipc_answer_0( callid, ( ipcarg_t ) ERROR_CODE );
}
}
 
395,7 → 395,7
return ERROR_CODE;
}
// request a new socket
if( ERROR_OCCURRED( async_req_3_3( phone, NET_SOCKET, 0, 0, service, ( ipcarg_t * ) & socket_id, ( ipcarg_t * ) & socket->header_size, ( ipcarg_t * ) & socket->data_fragment_size ))){
if( ERROR_OCCURRED(( int ) async_req_3_3( phone, NET_SOCKET, 0, 0, service, ( ipcarg_t * ) & socket_id, ( ipcarg_t * ) & socket->header_size, ( ipcarg_t * ) & socket->data_fragment_size ))){
dyn_fifo_destroy( & socket->received );
dyn_fifo_destroy( & socket->accepted );
free( socket );
409,7 → 409,7
dyn_fifo_destroy( & socket->received );
dyn_fifo_destroy( & socket->accepted );
free( socket );
async_msg_3( phone, NET_SOCKET_CLOSE, socket_id, 0, service );
async_msg_3( phone, NET_SOCKET_CLOSE, ( ipcarg_t ) socket_id, 0, service );
return ERROR_CODE;
}
 
416,7 → 416,7
return socket_id;
}
 
int socket_send_data( int socket_id, int message, ipcarg_t arg2, const void * data, size_t datalength ){
int socket_send_data( int socket_id, ipcarg_t message, ipcarg_t arg2, const void * data, size_t datalength ){
socket_ref socket;
aid_t message_id;
ipcarg_t result;
427,7 → 427,7
socket = sockets_find( socket_get_sockets(), socket_id );
if( ! socket ) return ENOTSOCK;
// request the message
message_id = async_send_3( socket->phone, message, socket->socket_id, arg2, socket->service, NULL );
message_id = async_send_3( socket->phone, message, ( ipcarg_t ) socket->socket_id, arg2, socket->service, NULL );
// send the address
ipc_data_write_start( socket->phone, data, datalength );
async_wait_for( message_id, & result );
435,8 → 435,9
}
 
int bind( int socket_id, const struct sockaddr * my_addr, socklen_t addrlen ){
if( addrlen <= 0 ) return EINVAL;
// send the address
return socket_send_data( socket_id, NET_SOCKET_BIND, 0, my_addr, addrlen );
return socket_send_data( socket_id, NET_SOCKET_BIND, 0, my_addr, ( size_t ) addrlen );
}
 
int listen( int socket_id, int backlog ){
447,7 → 448,7
socket = sockets_find( socket_get_sockets(), socket_id );
if( ! socket ) return ENOTSOCK;
// request listen backlog change
return async_req_3_0( socket->phone, NET_SOCKET_LISTEN, socket->socket_id, backlog, socket->service );
return ( int ) async_req_3_0( socket->phone, NET_SOCKET_LISTEN, ( ipcarg_t ) socket->socket_id, ( ipcarg_t ) backlog, socket->service );
}
 
int accept( int socket_id, struct sockaddr * cliaddr, socklen_t * addrlen ){
465,7 → 466,7
fibril_condvar_wait( & socket->accept_signal, & socket->accept_lock );
}
// request accept
message_id = async_send_3( socket->phone, NET_SOCKET_ACCEPT, socket->socket_id, dyn_fifo_value( & socket->accepted ), socket->service, NULL );
message_id = async_send_3( socket->phone, NET_SOCKET_ACCEPT, ( ipcarg_t ) socket->socket_id, ( ipcarg_t ) dyn_fifo_value( & socket->accepted ), socket->service, NULL );
// read address
ipc_data_read_start( socket->phone, cliaddr, * addrlen );
async_wait_for( message_id, ( ipcarg_t * ) & result );
490,7 → 491,7
socket = sockets_find( socket_get_sockets(), socket_id );
if( ! socket ) return ENOTSOCK;
// request close
ERROR_PROPAGATE( async_req_3_0( socket->phone, NET_SOCKET_CLOSE, socket->socket_id, 0, socket->service ));
ERROR_PROPAGATE(( int ) async_req_3_0( socket->phone, NET_SOCKET_CLOSE, ( ipcarg_t ) socket->socket_id, 0, socket->service ));
// free the socket structure
socket_destroy( socket );
return EOK;
520,11 → 521,11
return sendto_core( NET_SOCKET_SENDTO, socket_id, data, datalength, flags, toaddr, addrlen );
}
 
int sendto_core( int message, int socket_id, const void * data, size_t datalength, int flags, const struct sockaddr * toaddr, socklen_t addrlen ){
int sendto_core( ipcarg_t message, int socket_id, const void * data, size_t datalength, int flags, const struct sockaddr * toaddr, socklen_t addrlen ){
socket_ref socket;
aid_t message_id;
ipcarg_t result;
int fragments;
size_t fragments;
 
if( ! data ) return EBADMEM;
if( ! datalength ) return NO_DATA;
535,7 → 536,7
fragments = ( datalength + socket->header_size ) / socket->data_fragment_size;
if(( datalength + socket->header_size ) % socket->data_fragment_size ) ++ fragments;
// request send
message_id = async_send_4( socket->phone, message, socket->socket_id, fragments, socket->service, flags, NULL );
message_id = async_send_4( socket->phone, message, ( ipcarg_t ) socket->socket_id, fragments, socket->service, ( ipcarg_t ) flags, NULL );
// send the address if given
if(( ! toaddr ) || ( ipc_data_write_start( socket->phone, toaddr, addrlen ) == EOK )){
if( fragments == 1 ){
544,11 → 545,11
}else{
// send the first fragment
ipc_data_write_start( socket->phone, data, socket->data_fragment_size - socket->header_size );
data += socket->data_fragment_size - socket->header_size;
data = (( const uint8_t * ) data ) + socket->data_fragment_size - socket->header_size;
// send the middle fragments
while(( -- fragments ) > 1 ){
ipc_data_write_start( socket->phone, data, socket->data_fragment_size );
data += socket->data_fragment_size;
data = (( const uint8_t * ) data ) + socket->data_fragment_size;
}
// send the last fragment
ipc_data_write_start( socket->phone, data, ( datalength + socket->header_size ) % socket->data_fragment_size );
570,13 → 571,13
return recvfrom_core( NET_SOCKET_RECVFROM, socket_id, data, datalength, flags, fromaddr, addrlen );
}
 
int recvfrom_core( int message, int socket_id, void * data, size_t datalength, int flags, struct sockaddr * fromaddr, socklen_t * addrlen ){
int recvfrom_core( ipcarg_t message, int socket_id, void * data, size_t datalength, int flags, struct sockaddr * fromaddr, socklen_t * addrlen ){
socket_ref socket;
aid_t message_id;
int result;
int fragments;
int * lengths;
int index;
size_t fragments;
size_t * lengths;
size_t index;
ipc_call_t answer;
 
if( ! data ) return EBADMEM;
587,39 → 588,41
if( ! socket ) return ENOTSOCK;
fibril_mutex_lock( & socket->receive_lock );
// wait for a received packet
while(( fragments = dyn_fifo_value( & socket->received )) <= 0 ){
while(( result = dyn_fifo_value( & socket->received )) <= 0 ){
fibril_condvar_wait( & socket->receive_signal, & socket->receive_lock );
}
fragments = ( size_t ) result;
// prepare lengths if more fragments
if( fragments > 1 ){
lengths = ( int * ) malloc( sizeof( int ) * ( fragments + 1 ));
lengths = ( size_t * ) malloc( sizeof( size_t ) * fragments + sizeof( size_t ));
if( ! lengths ){
fibril_mutex_unlock( & socket->receive_lock );
return ENOMEM;
}
}
// request packet data
message_id = async_send_4( socket->phone, message, socket->socket_id, 0, socket->service, flags, & answer );
// read the address if desired
if(( ! fromaddr ) || ( ipc_data_read_start( socket->phone, fromaddr, * addrlen ) == EOK )){
if( fragments == 1 ){
// read all if only one fragment
ipc_data_read_start( socket->phone, data, datalength );
}else{
// request packet data
message_id = async_send_4( socket->phone, message, ( ipcarg_t ) socket->socket_id, 0, socket->service, ( ipcarg_t ) flags, & answer );
// read the address if desired
if(( ! fromaddr ) || ( ipc_data_read_start( socket->phone, fromaddr, * addrlen ) == EOK )){
// read the fragment lengths
if( ipc_data_read_start( socket->phone, lengths, sizeof( int ) * ( fragments + 1 )) == EOK ){
if( lengths[ fragments ] <= datalength ){
// read all fragments if long enough
// read all fragments if long enough
for( index = 0; index < fragments; ++ index ){
ipc_data_read_start( socket->phone, data, lengths[ index ] );
data += lengths[ index ];
data = (( uint8_t * ) data ) + lengths[ index ];
}
}
}
free( lengths );
}
}else if( fragments > 1 ){
free( lengths );
}else{
// request packet data
message_id = async_send_4( socket->phone, message, ( ipcarg_t ) socket->socket_id, 0, socket->service, ( ipcarg_t ) flags, & answer );
// read the address if desired
if(( ! fromaddr ) || ( ipc_data_read_start( socket->phone, fromaddr, * addrlen ) == EOK )){
// read all if only one fragment
ipc_data_read_start( socket->phone, data, datalength );
}
}
async_wait_for( message_id, ( ipcarg_t * ) & result );
// if successful
646,7 → 649,7
socket = sockets_find( socket_get_sockets(), socket_id );
if( ! socket ) return ENOTSOCK;
// request option value
message_id = async_send_3( socket->phone, NET_SOCKET_GETSOCKOPT, socket->socket_id, optname, socket->service, NULL );
message_id = async_send_3( socket->phone, NET_SOCKET_GETSOCKOPT, ( ipcarg_t ) socket->socket_id, ( ipcarg_t ) optname, socket->service, NULL );
// read the length
if( ipc_data_read_start( socket->phone, optlen, sizeof( * optlen )) == EOK ){
// read the value
658,7 → 661,7
 
int setsockopt( int socket_id, int level, int optname, const void * value, size_t optlen ){
// send the value
return socket_send_data( socket_id, NET_SOCKET_SETSOCKOPT, optname, value, optlen );
return socket_send_data( socket_id, NET_SOCKET_SETSOCKOPT, ( ipcarg_t ) optname, value, optlen );
 
}