Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 4699 → Rev 4700

/branches/network/uspace/srv/net/tl/udp/udp.c
34,6 → 34,7
*/
 
#include <async.h>
#include <fibril_sync.h>
#include <malloc.h>
#include <stdio.h>
 
66,6 → 67,9
 
#define MAX_UDP_FRAGMENT_SIZE 65535
 
#define UDP_FREE_PORTS_START 1025
#define UDP_FREE_PORTS_END 65535
 
int udp_received_msg( device_id_t device_id, packet_t packet, services_t receiver );
int udp_process_packet( packet_t packet );
int process_client_messages( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count );
82,6 → 86,8
int udp_initialize( async_client_conn_t client_connection ){
ERROR_DECLARE;
 
fibril_rwlock_initialize( & udp_globals.lock );
fibril_rwlock_write_lock( & udp_globals.lock );
udp_globals.ip_phone = ip_bind_service( SERVICE_IP, IPPROTO_UDP, SERVICE_UDP, client_connection, udp_received_msg );
if( udp_globals.ip_phone < 0 ){
return udp_globals.ip_phone;
90,6 → 96,8
ERROR_PROPAGATE( socket_ports_initialize( & udp_globals.sockets ));
udp_globals.prefix += sizeof( udp_header_t );
udp_globals.content -= sizeof( udp_header_t );
udp_globals.last_used_port = UDP_FREE_PORTS_START - 1;
fibril_rwlock_write_unlock( & udp_globals.lock );
return EOK;
}
 
183,8 → 191,12
* answer_count = 0;
switch( IPC_GET_METHOD( * call )){
case NET_TL_RECEIVED:
ERROR_PROPAGATE( packet_translate( udp_globals.net_phone, & packet, IPC_GET_PACKET( call )));
return udp_received_msg( IPC_GET_DEVICE( call ), packet, 0 );
fibril_rwlock_read_lock( & udp_globals.lock );
if( ! ERROR_OCCURRED( packet_translate( udp_globals.net_phone, & packet, IPC_GET_PACKET( call )))){
ERROR_CODE = udp_received_msg( IPC_GET_DEVICE( call ), packet, 0 );
}
fibril_rwlock_read_unlock( & udp_globals.lock );
return ERROR_CODE;
case IPC_M_CONNECT_TO_ME:
return process_client_messages( callid, call, answer, answer_count );
}
200,6 → 212,7
int app_phone = IPC_GET_PHONE( call );
void * addr;
size_t addrlen;
fibril_rwlock_t lock;
 
/*
* Accept the connection
208,6 → 221,7
ipc_answer_0( callid, EOK );
 
socket_cores_initialize( & local_sockets );
fibril_rwlock_initialize( & lock );
 
while( keep_on_going ){
// refresh data
230,7 → 244,9
res = EOK;
break;
case NET_SOCKET:
fibril_rwlock_write_lock( & lock );
res = socket_create( & local_sockets, app_phone, SOCKET_SET_SOCKET_ID( answer ));
fibril_rwlock_write_unlock( & lock );
* SOCKET_SET_HEADER_SIZE( answer ) = sizeof( udp_header_t );
* SOCKET_SET_DATA_FRAGMENT_SIZE( answer ) = MAX_UDP_FRAGMENT_SIZE;
* answer_count = 3;
240,7 → 256,11
res = ERROR_CODE;
break;
}
res = socket_bind( & local_sockets, & udp_globals.sockets, SOCKET_GET_SOCKET_ID( call ), addr, addrlen );
fibril_rwlock_write_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 );
free( addr );
break;
case NET_SOCKET_SENDTO:
248,11 → 268,19
res = ERROR_CODE;
break;
}
fibril_rwlock_read_lock( & lock );
fibril_rwlock_read_lock( & udp_globals.lock );
res = udp_sendto_message( & local_sockets, SOCKET_GET_SOCKET_ID( call ), addr, addrlen, SOCKET_GET_DATA_FRAGMENTS( call ), SOCKET_GET_FLAGS( call ));
fibril_rwlock_read_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 );
res = udp_recvfrom_message( & local_sockets, SOCKET_GET_SOCKET_ID( call ), SOCKET_GET_FLAGS( call ));
fibril_rwlock_read_unlock( & udp_globals.lock );
fibril_rwlock_read_unlock( & lock );
if( res > 0 ){
* SOCKET_SET_READ_DATA_LENGTH( answer ) = res;
* SOCKET_SET_ADDRESS_LENGTH( answer ) = sizeof( struct sockaddr_in );
261,7 → 289,11
}
break;
case NET_SOCKET_CLOSE:
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 );
fibril_rwlock_write_unlock( & udp_globals.lock );
fibril_rwlock_write_unlock( & lock );
break;
case NET_SOCKET_GETSOCKOPT:
case NET_SOCKET_SETSOCKOPT:
315,6 → 347,17
socket = socket_cores_find( local_sockets, socket_id );
if( ! socket ) return ENOTSOCK;
 
// bind the socket to a random free port if not bound
if( socket->port <= 0 ){
// try to find a free port
fibril_rwlock_read_unlock( & udp_globals.lock );
fibril_rwlock_write_lock( & udp_globals.lock );
ERROR_PROPAGATE( 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 );
// set the next port as the search starting port number
udp_globals.last_used_port = socket->port;
}
// TODO do not ask all the time
ERROR_PROPAGATE( ip_packet_size_req( udp_globals.ip_phone, -1, & udp_globals.addr_len, & udp_globals.prefix, & udp_globals.content, & udp_globals.suffix ));
 
/branches/network/uspace/srv/net/tl/udp/udp.h
36,6 → 36,8
#ifndef __NET_UDP_H__
#define __NET_UDP_H__
 
#include <fibril_sync.h>
 
#include "../../socket/socket_core.h"
 
typedef struct udp_globals udp_globals_t;
47,7 → 49,9
size_t content;
size_t suffix;
int net_phone;
int last_used_port;
socket_ports_t sockets;
fibril_rwlock_t lock;
};
 
#endif
/branches/network/uspace/srv/net/app/echo/echo.c
338,7 → 338,10
fprintf( stderr, "Socket send error %d\n", ERROR_CODE );
}
}
if( count > 0 ) -- count;
if( count > 0 ){
-- count;
if( verbose ) printf( "Waiting for next %d packet(s)\n", count );
}
}
 
if( verbose ) printf( "Closing the socket\n" );
/branches/network/uspace/srv/net/include/socket_errno.h
72,7 → 72,7
//#define ECONNRESET (-10054)
//#define ENOBUFS (-10055)
//#define EISCONN (-10056)
//#define ENOTCONN (-10057)
#define ENOTCONN (-10057)
//#define ESHUTDOWN (-10058)
//#define ETOOMANYREFS (-10059)
//#define ETIMEDOUT (-10060)
/branches/network/uspace/srv/net/socket/socket_core.c
48,13 → 48,13
 
#include "socket_core.h"
 
int socket_bind_insert( socket_ports_ref global_sockets, socket_core_ref socket, int port );
 
INT_MAP_IMPLEMENT( socket_cores, socket_core_t );
 
INT_MAP_IMPLEMENT( socket_ports, socket_core_ref );
 
int socket_bind( socket_cores_ref local_sockets, socket_ports_ref global_sockets, int socket_id, void * addr, size_t addrlen ){
ERROR_DECLARE;
 
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;
struct sockaddr * address;
69,6 → 69,10
// find the socket
socket = socket_cores_find( local_sockets, socket_id );
if( ! socket ) return ENOTSOCK;
// bind a free port?
if( address_in->sin_port <= 0 ){
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 ){
77,16 → 81,8
}
// 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;
// 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;
socket->port = -1;
return socket_bind_insert( global_sockets, socket, address_in->sin_port );
break;
// TODO IPv6
default:
95,6 → 91,51
return EOK;
}
 
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 index;
 
// from the last used one
index = last_used_port;
do{
++ index;
// til the range end
if( index >= free_ports_end ){
// start from the range beginning
index = free_ports_start - 1;
do{
++ index;
// til the last used one
if( index >= last_used_port ){
// none found
return ENOTCONN;
}
}while( socket_ports_find( global_sockets, index ) != NULL );
// found, break immediately
break;
}
}while( socket_ports_find( global_sockets, index ) != NULL );
return socket_bind_insert( global_sockets, socket, index );
}
 
int socket_bind_insert( socket_ports_ref global_sockets, socket_core_ref socket, int port ){
ERROR_DECLARE;
 
socket_core_ref * socket_pointer;
 
// create a wrapper
socket_pointer = ( socket_core_ref * ) malloc( sizeof( * socket_pointer ));
if( ! socket_pointer ) return ENOMEM;
* socket_pointer = socket;
// register the incomming port
ERROR_CODE = socket_ports_add( global_sockets, port, socket_pointer );
if( ERROR_CODE < 0 ){
free( socket_pointer );
return ERROR_CODE;
}
socket->port = port;
return EOK;
}
 
int socket_create( socket_cores_ref local_sockets, int app_phone, int * socket_id ){
ERROR_DECLARE;
 
/branches/network/uspace/srv/net/socket/socket_core.h
69,7 → 69,8
 
INT_MAP_DECLARE( socket_ports, socket_core_ref );
 
int socket_bind( socket_cores_ref local_sockets, socket_ports_ref global_sockets, int socket_id, void * addr, size_t addrlen );
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, int * socket_id );
int socket_destroy( int packet_phone, int socket_id, socket_cores_ref local_sockets, socket_ports_ref global_sockets );