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