/branches/network/uspace/srv/net/tl/tcp/Makefile |
---|
49,6 → 49,7 |
$(NET_BASE)tl/icmp/icmp_common.c \ |
$(NET_BASE)tl/icmp/icmp_remote.c \ |
$(NET_BASE)tl/tl_common.c \ |
$(STRUCTURES)char_map.c \ |
$(STRUCTURES)dynamic_fifo.c \ |
$(STRUCTURES)measured_strings.c \ |
$(STRUCTURES)packet/packet.c \ |
/branches/network/uspace/srv/net/tl/tl_common.c |
---|
61,12 → 61,12 |
case AF_INET: |
if( addrlen != sizeof( struct sockaddr_in )) return EINVAL; |
address_in = ( struct sockaddr_in * ) addr; |
* port = address_in->sin_port; |
* port = ntohs( address_in->sin_port ); |
break; |
case AF_INET6: |
if( addrlen != sizeof( struct sockaddr_in6 )) return EINVAL; |
address_in6 = ( struct sockaddr_in6 * ) addr; |
* port = address_in6->sin6_port; |
* port = ntohs( address_in6->sin6_port ); |
break; |
default: |
return EAFNOSUPPORT; |
74,7 → 74,6 |
return EOK; |
} |
int tl_set_address_port( struct sockaddr * addr, int addrlen, uint16_t port ){ |
struct sockaddr_in * address_in; |
struct sockaddr_in6 * address_in6; |
87,12 → 86,12 |
case AF_INET: |
if( length != sizeof( struct sockaddr_in )) return EINVAL; |
address_in = ( struct sockaddr_in * ) addr; |
address_in->sin_port = port; |
address_in->sin_port = htons( port ); |
return EOK; |
case AF_INET6: |
if( length != sizeof( struct sockaddr_in6 )) return EINVAL; |
address_in6 = ( struct sockaddr_in6 * ) addr; |
address_in6->sin6_port = port; |
address_in6->sin6_port = htons( port ); |
return EOK; |
default: |
return EAFNOSUPPORT; |
/branches/network/uspace/srv/net/tl/udp/udp.c |
---|
230,9 → 230,9 |
int udp_received_msg( device_id_t device_id, packet_t packet, services_t receiver, services_t error ){ |
int result; |
fibril_rwlock_read_lock( & udp_globals.lock ); |
fibril_rwlock_write_lock( & udp_globals.lock ); |
result = udp_process_packet( packet, error ); |
fibril_rwlock_read_unlock( & udp_globals.lock ); |
fibril_rwlock_write_unlock( & udp_globals.lock ); |
return result; |
} |
244,7 → 244,7 |
size_t offset; |
int result; |
udp_header_ref header; |
socket_core_ref * socket; |
socket_core_ref socket; |
packet_t next_packet; |
size_t total_length; |
uint32_t checksum; |
301,7 → 301,7 |
return udp_release_and_return( packet, NO_DATA ); |
} |
// find the destination socket |
socket = socket_ports_find( & udp_globals.sockets, ntohs( header->destination_port )); |
socket = socket_port_find( & udp_globals.sockets, ntohs( header->destination_port ), SOCKET_MAP_KEY_LISTENING, 0 ); |
if( ! socket ){ |
if( tl_prepare_icmp_packet( udp_globals.net_phone, udp_globals.icmp_phone, packet, error ) == EOK ){ |
icmp_destination_unreachable_msg( udp_globals.icmp_phone, ICMP_PORT_UNREACH, 0, packet ); |
374,12 → 374,12 |
} |
// queue the received packet |
if( ERROR_OCCURRED( dyn_fifo_push( &( ** socket ).received, packet_get_id( packet ), SOCKET_MAX_RECEIVED_SIZE ))){ |
if( ERROR_OCCURRED( dyn_fifo_push( & socket->received, packet_get_id( packet ), SOCKET_MAX_RECEIVED_SIZE ))){ |
return udp_release_and_return( packet, ERROR_CODE ); |
} |
// notify the destination socket |
async_msg_5(( ** socket ).phone, NET_SOCKET_RECEIVED, ( ipcarg_t ) ( ** socket ).socket_id, 0, 0, 0, ( ipcarg_t ) fragments ); |
async_msg_5( socket->phone, NET_SOCKET_RECEIVED, ( ipcarg_t ) socket->socket_id, 0, 0, 0, ( ipcarg_t ) fragments ); |
return EOK; |
} |
408,7 → 408,7 |
int app_phone = IPC_GET_PHONE( & call ); |
struct sockaddr * addr; |
size_t addrlen; |
// fibril_rwlock_t lock; |
fibril_rwlock_t lock; |
ipc_call_t answer; |
int answer_count; |
421,7 → 421,7 |
// The client connection is only in one fibril and therefore no additional locks are needed. |
socket_cores_initialize( & local_sockets ); |
// fibril_rwlock_initialize( & lock ); |
fibril_rwlock_initialize( & lock ); |
while( keep_on_going ){ |
// refresh data |
436,9 → 436,9 |
res = EOK; |
break; |
case NET_SOCKET: |
// fibril_rwlock_write_lock( & lock ); |
fibril_rwlock_write_lock( & lock ); |
res = socket_create( & local_sockets, app_phone, NULL, SOCKET_SET_SOCKET_ID( answer )); |
// fibril_rwlock_write_unlock( & lock ); |
fibril_rwlock_write_unlock( & lock ); |
// TODO max fragment size |
* SOCKET_SET_DATA_FRAGMENT_SIZE( answer ) = MAX_UDP_FRAGMENT_SIZE; |
* SOCKET_SET_HEADER_SIZE( answer ) = sizeof( udp_header_t ); |
447,11 → 447,11 |
case NET_SOCKET_BIND: |
res = data_receive(( void ** ) & addr, & addrlen ); |
if( res == EOK ){ |
// fibril_rwlock_write_lock( & lock ); |
fibril_rwlock_read_lock( & lock ); |
fibril_rwlock_write_lock( & udp_globals.lock ); |
res = socket_bind( & local_sockets, & udp_globals.sockets, SOCKET_GET_SOCKET_ID( call ), addr, addrlen, UDP_FREE_PORTS_START, UDP_FREE_PORTS_END, udp_globals.last_used_port ); |
fibril_rwlock_write_unlock( & udp_globals.lock ); |
// fibril_rwlock_write_unlock( & lock ); |
fibril_rwlock_read_unlock( & lock ); |
free( addr ); |
} |
break; |
458,20 → 458,20 |
case NET_SOCKET_SENDTO: |
res = data_receive(( void ** ) & addr, & addrlen ); |
if( res == EOK ){ |
// fibril_rwlock_read_lock( & lock ); |
fibril_rwlock_read_lock( & udp_globals.lock ); |
fibril_rwlock_read_lock( & lock ); |
fibril_rwlock_write_lock( & udp_globals.lock ); |
res = udp_sendto_message( & local_sockets, SOCKET_GET_SOCKET_ID( call ), addr, addrlen, SOCKET_GET_DATA_FRAGMENTS( call ), SOCKET_GET_DATA_FRAGMENT_SIZE( call ), SOCKET_GET_FLAGS( call )); |
fibril_rwlock_read_unlock( & udp_globals.lock ); |
// fibril_rwlock_read_unlock( & lock ); |
fibril_rwlock_write_unlock( & udp_globals.lock ); |
fibril_rwlock_read_unlock( & lock ); |
free( addr ); |
} |
break; |
case NET_SOCKET_RECVFROM: |
// fibril_rwlock_read_lock( & lock ); |
fibril_rwlock_read_lock( & udp_globals.lock ); |
fibril_rwlock_read_lock( & lock ); |
fibril_rwlock_write_lock( & udp_globals.lock ); |
res = udp_recvfrom_message( & local_sockets, SOCKET_GET_SOCKET_ID( call ), SOCKET_GET_FLAGS( call ), & addrlen ); |
fibril_rwlock_read_unlock( & udp_globals.lock ); |
// fibril_rwlock_read_unlock( & lock ); |
fibril_rwlock_write_unlock( & udp_globals.lock ); |
fibril_rwlock_read_unlock( & lock ); |
if( res > 0 ){ |
* SOCKET_SET_READ_DATA_LENGTH( answer ) = res; |
* SOCKET_SET_ADDRESS_LENGTH( answer ) = addrlen; |
480,11 → 480,11 |
} |
break; |
case NET_SOCKET_CLOSE: |
// fibril_rwlock_write_lock( & lock ); |
fibril_rwlock_write_lock( & lock ); |
fibril_rwlock_write_lock( & udp_globals.lock ); |
res = socket_destroy( udp_globals.net_phone, SOCKET_GET_SOCKET_ID( call ), & local_sockets, & udp_globals.sockets ); |
res = socket_destroy( udp_globals.net_phone, SOCKET_GET_SOCKET_ID( call ), & local_sockets, & udp_globals.sockets, NULL ); |
fibril_rwlock_write_unlock( & udp_globals.lock ); |
// fibril_rwlock_write_unlock( & lock ); |
fibril_rwlock_write_unlock( & lock ); |
break; |
case NET_SOCKET_GETSOCKOPT: |
case NET_SOCKET_SETSOCKOPT: |
498,8 → 498,8 |
answer_call( callid, res, & answer, answer_count ); |
} |
// TODO call socket_destroy() on all bound! |
socket_cores_destroy( & local_sockets ); |
// release all local sockets |
socket_cores_release( udp_globals.net_phone, & local_sockets, & udp_globals.sockets, NULL ); |
return EOK; |
} |
529,16 → 529,20 |
// bind the socket to a random free port if not bound |
do{ |
// try to find a free port |
fibril_rwlock_read_unlock( & udp_globals.lock ); |
fibril_rwlock_write_lock( & udp_globals.lock ); |
// fibril_rwlock_read_unlock( & udp_globals.lock ); |
// fibril_rwlock_write_lock( & udp_globals.lock ); |
// might be changed in the meantime |
if( socket->port <= 0 ){ |
ERROR_PROPAGATE( socket_bind_free_port( & udp_globals.sockets, socket, UDP_FREE_PORTS_START, UDP_FREE_PORTS_END, udp_globals.last_used_port )); |
if( ERROR_OCCURRED( socket_bind_free_port( & udp_globals.sockets, socket, UDP_FREE_PORTS_START, UDP_FREE_PORTS_END, udp_globals.last_used_port ))){ |
fibril_rwlock_write_unlock( & udp_globals.lock ); |
fibril_rwlock_read_lock( & udp_globals.lock ); |
return ERROR_CODE; |
} |
// set the next port as the search starting port number |
udp_globals.last_used_port = socket->port; |
} |
fibril_rwlock_write_unlock( & udp_globals.lock ); |
fibril_rwlock_read_lock( & udp_globals.lock ); |
// fibril_rwlock_write_unlock( & udp_globals.lock ); |
// fibril_rwlock_read_lock( & udp_globals.lock ); |
// might be changed in the meantime |
}while( socket->port <= 0 ); |
} |
610,11 → 614,7 |
udp_header_ref header; |
struct sockaddr * addr; |
size_t length; |
packet_t next_packet; |
uint8_t * data; |
size_t fragments; |
size_t * lengths; |
size_t index; |
int result; |
// find the socket |
642,44 → 642,12 |
// send the source address |
ERROR_PROPAGATE( data_reply( addr, * addrlen )); |
next_packet = pq_next( packet ); |
if( ! next_packet ){ |
// write all if only one fragment |
ERROR_PROPAGATE( data_reply( data + sizeof( udp_header_t ), packet_get_data_length( packet ) - sizeof( udp_header_t ))); |
// store the total length |
length = packet_get_data_length( packet ) - sizeof( udp_header_t ); |
}else{ |
// count the packet fragments |
fragments = 1; |
next_packet = pq_next( packet ); |
while(( next_packet = pq_next( next_packet ))){ |
++ fragments; |
} |
// compute and store the fragment lengths |
lengths = ( size_t * ) malloc( sizeof( size_t ) * fragments + sizeof( size_t )); |
if( ! lengths ) return ENOMEM; |
lengths[ 0 ] = packet_get_data_length( packet ) - sizeof( udp_header_t ); |
lengths[ fragments ] = lengths[ 0 ]; |
next_packet = pq_next( packet ); |
for( index = 1; index < fragments; ++ index ){ |
lengths[ index ] = packet_get_data_length( next_packet ); |
lengths[ fragments ] += lengths[ index ]; |
next_packet = pq_next( packet ); |
}while( next_packet ); |
// write the fragment lengths |
ERROR_PROPAGATE( data_reply( lengths, sizeof( int ) * ( fragments + 1 ))); |
// write the first fragment |
ERROR_PROPAGATE( data_reply( data + sizeof( udp_header_t ), lengths[ 0 ] )); |
next_packet = pq_next( packet ); |
// write the rest of the fragments |
for( index = 1; index < fragments; ++ index ){ |
ERROR_PROPAGATE( data_reply( packet_get_data( next_packet ), lengths[ index ] )); |
next_packet = pq_next( packet ); |
}while( next_packet ); |
// store the total length |
length = lengths[ fragments ]; |
free( lengths ); |
} |
// trim the header |
ERROR_PROPAGATE( packet_trim( packet, sizeof( udp_header_t ), 0 )); |
// reply the packets |
ERROR_PROPAGATE( socket_reply_packets( packet, & length )); |
// release the packet |
dyn_fifo_pop( & socket->received ); |
pq_release( udp_globals.net_phone, packet_get_id( packet )); |
/branches/network/uspace/srv/net/tl/udp/Makefile |
---|
49,6 → 49,7 |
$(NET_BASE)tl/icmp/icmp_common.c \ |
$(NET_BASE)tl/icmp/icmp_remote.c \ |
$(NET_BASE)tl/tl_common.c \ |
$(STRUCTURES)char_map.c \ |
$(STRUCTURES)dynamic_fifo.c \ |
$(STRUCTURES)measured_strings.c \ |
$(STRUCTURES)packet/packet.c \ |
/branches/network/uspace/srv/net/socket/socket_core.c |
---|
47,17 → 47,77 |
#include "../structures/packet/packet.h" |
#include "../structures/packet/packet_client.h" |
#include "../modules.h" |
#include "socket_core.h" |
/** \todo |
*/ |
struct socket_port{ |
socket_port_map_t map; |
int count; |
}; |
/** \todo |
*/ |
int socket_bind_insert( socket_ports_ref global_sockets, socket_core_ref socket, int port ); |
/** \todo |
*/ |
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 )); |
/** \todo |
*/ |
int socket_port_add_core( socket_port_ref socket_port, socket_core_ref socket, const char * key, size_t key_length ); |
INT_MAP_IMPLEMENT( socket_cores, socket_core_t ); |
INT_MAP_IMPLEMENT( socket_ports, socket_core_ref ); |
GENERIC_CHAR_MAP_IMPLEMENT( socket_port_map, socket_core_ref ); |
INT_MAP_IMPLEMENT( socket_ports, socket_port_t ); |
void socket_cores_release( int packet_phone, socket_cores_ref local_sockets, socket_ports_ref global_sockets, void ( * socket_release )( socket_core_ref socket )){ |
if( socket_cores_is_valid( local_sockets )){ |
int index; |
local_sockets->magic = 0; |
for( index = 0; index < local_sockets->next; ++ index ){ |
if( socket_cores_item_is_valid( &( local_sockets->items[ index ] ))){ |
local_sockets->items[ index ].magic = 0; |
if( local_sockets->items[ index ].value ){ |
socket_destroy_core( packet_phone, local_sockets->items[ index ].value, local_sockets, global_sockets, socket_release ); |
free( local_sockets->items[ index ].value ); |
local_sockets->items[ index ].value = NULL; |
} |
} |
} |
free( local_sockets->items ); |
} |
} |
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 )){ |
int packet_id; |
// if bound |
if( socket->port ){ |
// release the port |
socket_port_release( global_sockets, socket ); |
} |
// release all received packets |
while(( packet_id = dyn_fifo_pop( & socket->received )) >= 0 ){ |
pq_release( packet_phone, packet_id ); |
} |
dyn_fifo_destroy( & socket->received ); |
dyn_fifo_destroy( & socket->accepted ); |
if( socket_release ){ |
socket_release( socket ); |
} |
socket_cores_exclude( local_sockets, socket->socket_id ); |
} |
int socket_bind( socket_cores_ref local_sockets, socket_ports_ref global_sockets, int socket_id, void * addr, size_t addrlen, int free_ports_start, int free_ports_end, int last_used_port ){ |
socket_core_ref socket; |
socket_core_ref * socket_pointer; |
socket_port_ref socket_port; |
struct sockaddr * address; |
struct sockaddr_in * address_in; |
75,15 → 135,18 |
return socket_bind_free_port( global_sockets, socket, free_ports_start, free_ports_end, last_used_port ); |
} |
// try to find the port |
socket_pointer = socket_ports_find( global_sockets, address_in->sin_port ); |
if( socket_pointer ){ |
socket_port = socket_ports_find( global_sockets, ntohs( address_in->sin_port )); |
if( socket_port ){ |
// already used |
return EADDRINUSE; |
} |
// unbind if bound |
socket_ports_exclude( global_sockets, socket->port ); |
// if bound |
if( socket->port ){ |
// release the port |
socket_port_release( global_sockets, socket ); |
} |
socket->port = -1; |
return socket_bind_insert( global_sockets, socket, address_in->sin_port ); |
return socket_bind_insert( global_sockets, socket, ntohs( address_in->sin_port )); |
break; |
// TODO IPv6 |
} |
119,16 → 182,23 |
int socket_bind_insert( socket_ports_ref global_sockets, socket_core_ref socket, int port ){ |
ERROR_DECLARE; |
socket_core_ref * socket_pointer; |
socket_port_ref socket_port; |
// create a wrapper |
socket_pointer = ( socket_core_ref * ) malloc( sizeof( socket_core_ref )); |
if( ! socket_pointer ) return ENOMEM; |
* socket_pointer = socket; |
socket_port = malloc( sizeof( * socket_port )); |
if( ! socket_port ) return ENOMEM; |
socket_port->count = 0; |
if( ERROR_OCCURRED( socket_port_map_initialize( & socket_port->map )) |
|| ERROR_OCCURRED( socket_port_add_core( socket_port, socket, SOCKET_MAP_KEY_LISTENING, 0 ))){ |
socket_port_map_destroy( & socket_port->map ); |
free( socket_port ); |
return ERROR_CODE; |
} |
// register the incomming port |
ERROR_CODE = socket_ports_add( global_sockets, port, socket_pointer ); |
ERROR_CODE = socket_ports_add( global_sockets, port, socket_port ); |
if( ERROR_CODE < 0 ){ |
free( socket_pointer ); |
socket_port_map_destroy( & socket_port->map ); |
free( socket_port ); |
return ERROR_CODE; |
} |
socket->port = port; |
147,6 → 217,8 |
// initialize |
socket->phone = app_phone; |
socket->port = -1; |
socket->key = NULL; |
socket->key_length = 0; |
socket->specific_data = specific_data; |
if( ERROR_OCCURRED( dyn_fifo_initialize( & socket->received, SOCKET_INITIAL_RECEIVED_SIZE ))){ |
free( socket ); |
172,28 → 244,148 |
return EOK; |
} |
int socket_destroy( int packet_phone, int socket_id, socket_cores_ref local_sockets, socket_ports_ref global_sockets ){ |
int socket_destroy( int packet_phone, int socket_id, socket_cores_ref local_sockets, socket_ports_ref global_sockets, void ( * socket_release )( socket_core_ref socket )){ |
socket_core_ref socket; |
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 ); |
// destroy all accepted sockets |
while(( accepted_id = dyn_fifo_pop( & socket->accepted )) >= 0 ){ |
socket_destroy( packet_phone, accepted_id, local_sockets, global_sockets ); |
socket_destroy( packet_phone, accepted_id, local_sockets, global_sockets, socket_release ); |
} |
// release all received packets |
while(( packet_id = dyn_fifo_pop( & socket->received )) >= 0 ){ |
pq_release( packet_phone, packet_id ); |
socket_destroy_core( packet_phone, socket, local_sockets, global_sockets, socket_release ); |
return EOK; |
} |
dyn_fifo_destroy( & socket->received ); |
dyn_fifo_destroy( & socket->accepted ); |
socket_cores_exclude( local_sockets, socket_id ); |
int socket_reply_packets( packet_t packet, size_t * length ){ |
ERROR_DECLARE; |
packet_t next_packet; |
size_t fragments; |
size_t * lengths; |
size_t index; |
if( ! length ){ |
return EINVAL; |
} |
next_packet = pq_next( packet ); |
if( ! next_packet ){ |
// write all if only one fragment |
ERROR_PROPAGATE( data_reply( packet_get_data( packet ), packet_get_data_length( packet ))); |
// store the total length |
* length = packet_get_data_length( packet ); |
}else{ |
// count the packet fragments |
fragments = 1; |
next_packet = pq_next( packet ); |
while(( next_packet = pq_next( next_packet ))){ |
++ fragments; |
} |
// compute and store the fragment lengths |
lengths = ( size_t * ) malloc( sizeof( size_t ) * fragments + sizeof( size_t )); |
if( ! lengths ) return ENOMEM; |
lengths[ 0 ] = packet_get_data_length( packet ); |
lengths[ fragments ] = lengths[ 0 ]; |
next_packet = pq_next( packet ); |
for( index = 1; index < fragments; ++ index ){ |
lengths[ index ] = packet_get_data_length( next_packet ); |
lengths[ fragments ] += lengths[ index ]; |
next_packet = pq_next( packet ); |
}while( next_packet ); |
// write the fragment lengths |
ERROR_PROPAGATE( data_reply( lengths, sizeof( int ) * ( fragments + 1 ))); |
next_packet = packet; |
// write the fragments |
for( index = 0; index < fragments; ++ index ){ |
ERROR_PROPAGATE( data_reply( packet_get_data( next_packet ), lengths[ index ] )); |
next_packet = pq_next( next_packet ); |
}while( next_packet ); |
// store the total length |
* length = lengths[ fragments ]; |
free( lengths ); |
} |
return EOK; |
} |
socket_core_ref socket_port_find( socket_ports_ref global_sockets, int port, const char * key, size_t key_length ){ |
socket_port_ref socket_port; |
socket_core_ref * socket_ref; |
socket_port = socket_ports_find( global_sockets, port ); |
if( socket_port && ( socket_port->count > 0 )){ |
socket_ref = socket_port_map_find( & socket_port->map, key, key_length ); |
if( socket_ref ){ |
return * socket_ref; |
} |
} |
return NULL; |
} |
void socket_port_release( socket_ports_ref global_sockets, socket_core_ref socket ){ |
socket_port_ref socket_port; |
socket_core_ref * socket_ref; |
if( socket->port ){ |
// find ports |
socket_port = socket_ports_find( global_sockets, socket->port ); |
if( socket_port ){ |
// find the socket |
socket_ref = socket_port_map_find( & socket_port->map, socket->key, socket->key_length ); |
if( socket_ref ){ |
-- socket_port->count; |
// release if empty |
if( socket_port->count <= 0 ){ |
// destroy the map |
socket_port_map_destroy( & socket_port->map ); |
// release the port |
socket_ports_exclude( global_sockets, socket->port ); |
}else{ |
// remove |
socket_port_map_exclude( & socket_port->map, socket->key, socket->key_length ); |
} |
} |
} |
socket->port = 0; |
socket->key = NULL; |
socket->key_length = 0; |
} |
} |
int socket_port_add( socket_ports_ref global_sockets, int port, socket_core_ref socket, const char * key, size_t key_length ){ |
ERROR_DECLARE; |
socket_port_ref socket_port; |
// find ports |
socket_port = socket_ports_find( global_sockets, port ); |
if( ! socket_port ) return ENOENT; |
// add the socket |
ERROR_PROPAGATE( socket_port_add_core( socket_port, socket, key, key_length )); |
socket->port = port; |
return EOK; |
} |
int socket_port_add_core( socket_port_ref socket_port, socket_core_ref socket, const char * key, size_t key_length ){ |
ERROR_DECLARE; |
socket_core_ref * socket_ref; |
// create a wrapper |
socket_ref = malloc( sizeof( * socket_ref )); |
if( ! socket_ref ) return ENOMEM; |
* socket_ref = socket; |
// add the wrapper |
if( ERROR_OCCURRED( socket_port_map_add( & socket_port->map, key, key_length, socket_ref ))){ |
free( socket_ref ); |
return ERROR_CODE; |
} |
++ socket_port->count; |
socket->key = key; |
socket->key_length = key_length; |
return EOK; |
} |
/** @} |
*/ |
/branches/network/uspace/srv/net/socket/socket_core.h |
---|
42,6 → 42,7 |
#include "../include/in.h" |
#include "../include/device.h" |
#include "../structures/generic_char_map.h" |
#include "../structures/dynamic_fifo.h" |
#include "../structures/int_map.h" |
#include "../structures/packet/packet.h" |
52,9 → 53,16 |
#define SOCKET_INITIAL_ACCEPTED_SIZE 1 |
#define SOCKET_MAX_ACCEPTEDED_SIZE 64 |
/** \todo |
*/ |
#define SOCKET_MAP_KEY_LISTENING "L" |
typedef struct socket_core socket_core_t; |
typedef socket_core_t * socket_core_ref; |
typedef struct socket_port socket_port_t; |
typedef socket_port_t * socket_port_ref; |
struct socket_core{ |
int socket_id; |
int phone; |
62,16 → 70,26 |
dyn_fifo_t received; |
dyn_fifo_t accepted; |
void * specific_data; |
const char * key; |
size_t key_length; |
}; |
INT_MAP_DECLARE( socket_cores, socket_core_t ); |
INT_MAP_DECLARE( socket_ports, socket_core_ref ); |
GENERIC_CHAR_MAP_DECLARE( socket_port_map, socket_core_ref ); |
INT_MAP_DECLARE( socket_ports, socket_port_t ); |
void socket_cores_release( int packet_phone, socket_cores_ref local_sockets, socket_ports_ref global_sockets, void ( * socket_release )( socket_core_ref socket )); |
int socket_bind( socket_cores_ref local_sockets, socket_ports_ref global_sockets, int socket_id, void * addr, size_t addrlen, int free_ports_start, int free_ports_end, int last_used_port ); |
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 ); |
int socket_create( socket_cores_ref local_sockets, int app_phone, void * specific_data, int * socket_id ); |
int socket_destroy( int packet_phone, int socket_id, socket_cores_ref local_sockets, socket_ports_ref global_sockets ); |
int socket_destroy( int packet_phone, int socket_id, socket_cores_ref local_sockets, socket_ports_ref global_sockets, void ( * socket_release )( socket_core_ref socket )); |
int socket_reply_packets( packet_t packet, size_t * length ); |
socket_core_ref socket_port_find( socket_ports_ref global_sockets, int port, const char * key, size_t key_length ); |
void socket_port_release( socket_ports_ref global_sockets, socket_core_ref socket ); |
int socket_port_add( socket_ports_ref global_sockets, int port, socket_core_ref socket, const char * key, size_t key_length ); |
#endif |