Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 4588 → Rev 4589

/branches/network/uspace/srv/net/socket/socket_core.c
41,6 → 41,7
#include "../include/socket.h"
#include "../include/socket_errno.h"
 
#include "../structures/dynamic_fifo.h"
#include "../structures/int_map.h"
#include "../structures/packet/packet.h"
#include "../structures/packet/packet_client.h"
65,17 → 66,26
case AF_INET:
if( addrlen != sizeof( struct sockaddr_in )) return EINVAL;
address_in = ( struct sockaddr_in * ) addr;
// find the socket
socket = socket_cores_find( local_sockets, socket_id );
if( ! socket ) return ENOTSOCK;
// try to find the port
socket_pointer = socket_ports_find( global_sockets, address_in->sin_port );
if( * socket_pointer ){
if( socket_pointer ){
// already used
return EADDRINUSE;
}
// disbind if bound
socket_ports_exclude( global_sockets, socket->port );
// create a wrapper
socket_pointer = ( socket_core_ref * ) malloc( sizeof( * socket_pointer ));
if( ! socket_pointer ) return ENOMEM;
* socket_pointer = socket;
ERROR_PROPAGATE( socket_ports_add( global_sockets, address_in->sin_port, socket_pointer ));
// register the port
ERROR_CODE = socket_ports_add( global_sockets, address_in->sin_port, socket_pointer );
if( ERROR_CODE < 0 ){
free( socket_pointer );
}
socket->port = address_in->sin_port;
break;
// TODO IPv6
85,65 → 95,63
return EOK;
}
 
int socket_create( socket_cores_ref local_sockets, int app_phone ){
int socket_create( socket_cores_ref local_sockets, int app_phone, int * socket_id ){
ERROR_DECLARE;
 
socket_core_ref socket;
int res;
 
if( ! socket_id ) return EBADMEM;
socket = ( socket_core_ref ) malloc( sizeof( * socket ));
if( ! socket ) return ENOMEM;
// initialize
socket->phone = app_phone;
socket->port = -1;
socket->device_id = -1;
socket->peer_addr = NULL;
socket->connect_size = 2;
socket->receive_size = 8;
socket->connected = ( int * ) malloc( sizeof( int ) * socket->connect_size );
if( ! socket->connected ){
if( ERROR_OCCURRED( dyn_fifo_initialize( & socket->received, SOCKET_INITIAL_RECEIVED_SIZE ))){
free( socket );
return ENOMEM;
return ERROR_CODE;
}
bzero( socket->connected, sizeof( int ) * socket->connect_size );
socket->received = ( int * ) malloc( sizeof( int ) * socket->receive_size );
if( ! socket->received ){
free( socket->connected );
if( ERROR_OCCURRED( dyn_fifo_initialize( & socket->accepted, SOCKET_INITIAL_ACCEPTED_SIZE ))){
dyn_fifo_destroy( & socket->received );
free( socket );
return ENOMEM;
return ERROR_CODE;
}
bzero( socket->received, sizeof( int ) * socket->receive_size );
// get a next free socket number
socket->socket_id = socket_cores_count( local_sockets ) + 1;
// store the socket
res = socket_cores_add( local_sockets, socket->socket_id, socket );
if( res < 0 ){
free( socket->received );
free( socket->connected );
dyn_fifo_destroy( & socket->received );
dyn_fifo_destroy( & socket->accepted );
free( socket );
return res;
}
return socket->socket_id;
// return the socket identifier
* socket_id = socket->socket_id;
return EOK;
}
 
int socket_destroy( int packet_phone, int socket_id, socket_cores_ref local_sockets, socket_ports_ref global_sockets ){
socket_core_ref socket;
size_t i;
int accepted_id;
int packet_id;
 
// find the socket
socket = socket_cores_find( local_sockets, socket_id );
if( ! socket ) return ENOTSOCK;
socket_ports_exclude( global_sockets, socket->port );
if( socket->connected ){
for( i = 0; i < socket->connect_size; ++ i ){
if( socket->connected[ i ] ){
socket_destroy( packet_phone, socket->connected[ i ], local_sockets, global_sockets );
}
}
// destroy all accepted sockets
while(( accepted_id = dyn_fifo_pop( & socket->accepted ))){
socket_destroy( packet_phone, accepted_id, local_sockets, global_sockets );
}
if( socket->received ){
for( i = 0; i < socket->receive_size; ++ i ){
if( socket->received[ i ] ){
pq_release( packet_phone, socket->received[ i ] );
}
}
// release all received packets
while(( packet_id = dyn_fifo_pop( & socket->received ))){
pq_release( packet_phone, packet_id );
}
if( socket->connected ) free( socket->connected );
if( socket->received ) free( socket->received );
dyn_fifo_destroy( & socket->received );
dyn_fifo_destroy( & socket->accepted );
socket_cores_exclude( local_sockets, socket_id );
return EOK;
}