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