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; |
} |