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