56,7 → 56,7 |
#include "../../include/ip_protocols.h" |
#include "../../include/icmp_client.h" |
#include "../../include/icmp_interface.h" |
#include "../../include/socket.h" |
#include "../../include/socket_codes.h" |
#include "../../include/socket_errno.h" |
|
#include "../../socket/socket_core.h" |
104,7 → 104,7 |
* @param result The result to be returned. Input parameter. |
* @return The result parameter. |
*/ |
static int release_and_return( packet_t packet, int result ); |
int udp_release_and_return( packet_t packet, int result ); |
|
/** Sends the port unreachable ICMP notification. |
* Sends the first packet and releases all the others. |
125,7 → 125,7 |
* @returns EOK on success. |
* @see socket.h |
*/ |
int process_client_messages( ipc_callid_t callid, ipc_call_t call ); |
int udp_process_client_messages( ipc_callid_t callid, ipc_call_t call ); |
|
/** Sends data from the socket to the remote address. |
* Binds the socket to a free port if not already connected/bound. |
248,35 → 248,35 |
// length = icmp_client_header_length( packet ); |
result = icmp_client_process_packet( packet, & type, & code, NULL, NULL ); |
if( result < 0 ){ |
return release_and_return( packet, result ); |
return udp_release_and_return( packet, result ); |
} |
printf( "ICMP error %d (%d) in packet %d\n", type, code, packet_get_id( packet ) ); |
length = ( size_t ) result; |
if( ERROR_OCCURRED( packet_trim( packet, length, 0 ))){ |
return release_and_return( packet, ERROR_CODE ); |
return udp_release_and_return( packet, ERROR_CODE ); |
} |
break; |
default: |
return release_and_return( packet, ENOTSUP ); |
return udp_release_and_return( packet, ENOTSUP ); |
} |
} |
// TODO process received ipopts? |
result = ip_client_process_packet( packet, NULL, NULL, NULL, NULL, NULL ); |
if( result < 0 ){ |
return release_and_return( packet, result ); |
return udp_release_and_return( packet, result ); |
} |
offset = ( size_t ) result; |
|
length = packet_get_data_length( packet ); |
if( length <= 0 ){ |
return release_and_return( packet, EINVAL ); |
return udp_release_and_return( packet, EINVAL ); |
} |
if( length < sizeof( udp_header_t ) + offset ){ |
return release_and_return( packet, NO_DATA ); |
return udp_release_and_return( packet, NO_DATA ); |
} |
data = packet_get_data( packet ); |
if( ! data ){ |
return release_and_return( packet, NO_DATA ); |
return udp_release_and_return( packet, NO_DATA ); |
} |
// get udp header |
header = ( udp_header_ref )( data + offset ); |
296,12 → 296,12 |
++ fragments; |
length = packet_get_data_length( packet ); |
if( length <= 0 ){ |
return release_and_return( packet, NO_DATA ); |
return udp_release_and_return( packet, NO_DATA ); |
} |
if( total_length < length ){ |
// cut of the suffix if too long |
if( ERROR_OCCURRED( packet_trim( next_packet, 0, length - total_length ))){ |
return release_and_return( packet, ERROR_CODE ); |
return udp_release_and_return( packet, ERROR_CODE ); |
} |
// relese the rest of the packet fragments |
tmp_packet = pq_next( next_packet ); |
319,7 → 319,7 |
}while(( next_packet = pq_next( next_packet )) && ( total_length > 0 )); |
// queue the received packet |
if( ERROR_OCCURRED( dyn_fifo_push( &( ** socket ).received, packet_get_id( packet ), SOCKET_MAX_RECEIVED_SIZE ))){ |
return release_and_return( packet, ERROR_CODE ); |
return udp_release_and_return( packet, ERROR_CODE ); |
} |
|
// notify the destination socket |
342,14 → 342,12 |
fibril_rwlock_read_unlock( & udp_globals.lock ); |
return ERROR_CODE; |
case IPC_M_CONNECT_TO_ME: |
return process_client_messages( callid, * call ); |
return udp_process_client_messages( callid, * call ); |
} |
return ENOTSUP; |
} |
|
int process_client_messages( ipc_callid_t callid, ipc_call_t call ){ |
ERROR_DECLARE; |
|
int udp_process_client_messages( ipc_callid_t callid, ipc_call_t call ){ |
int res; |
bool keep_on_going = true; |
socket_cores_t local_sockets; |
371,15 → 369,7 |
|
while( keep_on_going ){ |
// refresh data |
answer_count = 0; |
IPC_SET_RETVAL( answer, 0 ); |
// just to be precize |
IPC_SET_METHOD( answer, 0 ); |
IPC_SET_ARG1( answer, 0 ); |
IPC_SET_ARG2( answer, 0 ); |
IPC_SET_ARG3( answer, 0 ); |
IPC_SET_ARG4( answer, 0 ); |
IPC_SET_ARG5( answer, 0 ); |
refresh_answer( & answer, & answer_count ); |
|
callid = async_get_call( & call ); |
// printf( "message %d\n", IPC_GET_METHOD( * call )); |
398,10 → 388,8 |
answer_count = 3; |
break; |
case NET_SOCKET_BIND: |
if( ERROR_OCCURRED( socket_read_data( & addr, & addrlen ))){ |
res = ERROR_CODE; |
break; |
} |
res = socket_read_data( & addr, & addrlen ); |
if( res == EOK ){ |
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 ); |
408,12 → 396,11 |
fibril_rwlock_write_unlock( & udp_globals.lock ); |
fibril_rwlock_write_unlock( & lock ); |
free( addr ); |
} |
break; |
case NET_SOCKET_SENDTO: |
if( ERROR_OCCURRED( socket_read_data( & addr, & addrlen ))){ |
res = ERROR_CODE; |
break; |
} |
res = socket_read_data( & addr, & addrlen ); |
if( res == EOK ){ |
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 )); |
420,6 → 407,7 |
fibril_rwlock_read_unlock( & udp_globals.lock ); |
fibril_rwlock_read_unlock( & lock ); |
free( addr ); |
} |
break; |
case NET_SOCKET_RECVFROM: |
fibril_rwlock_read_lock( & lock ); |
450,21 → 438,8 |
|
// printf( "res = %d\n", res ); |
|
switch( answer_count ){ |
case 0: ipc_answer_0( callid, ( ipcarg_t ) res ); |
continue; |
case 1: ipc_answer_1( callid, ( ipcarg_t ) res, IPC_GET_ARG1( answer )); |
continue; |
case 2: ipc_answer_2( callid, ( ipcarg_t ) res, IPC_GET_ARG1( answer ), IPC_GET_ARG2( answer )); |
continue; |
case 3: ipc_answer_3( callid, ( ipcarg_t ) res, IPC_GET_ARG1( answer ), IPC_GET_ARG2( answer ), IPC_GET_ARG3( answer )); |
continue; |
case 4: ipc_answer_4( callid, ( ipcarg_t ) res, IPC_GET_ARG1( answer ), IPC_GET_ARG2( answer ), IPC_GET_ARG3( answer ), IPC_GET_ARG4( answer )); |
continue; |
default: ipc_answer_5( callid, ( ipcarg_t ) res, IPC_GET_ARG1( answer ), IPC_GET_ARG2( answer ), IPC_GET_ARG3( answer ), IPC_GET_ARG4( answer ), IPC_GET_ARG5( answer )); |
continue; |
answer_call( callid, res, & answer, answer_count ); |
} |
} |
|
socket_cores_destroy( & local_sockets ); |
|
494,16 → 469,18 |
if( ! socket ) return ENOTSOCK; |
|
// bind the socket to a random free port if not bound |
if( socket->port <= 0 ){ |
while( socket->port <= 0 ){ |
// try to find a free port |
fibril_rwlock_read_unlock( & udp_globals.lock ); |
fibril_rwlock_write_lock( & udp_globals.lock ); |
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 )); |
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; |
} |
fibril_rwlock_write_unlock( & udp_globals.lock ); |
fibril_rwlock_read_lock( & udp_globals.lock ); |
} |
// 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 )); |
|
521,7 → 498,7 |
for( index = 1; index < fragments; ++ index ){ |
result = socket_read_packet_data( & next_packet, 0, address_in ); |
if( result < 0 ){ |
return release_and_return( packet, result ); |
return udp_release_and_return( packet, result ); |
} |
packet = pq_add( packet, next_packet, index, 0 ); |
total_length += ( size_t ) result; |
687,7 → 664,7 |
return ( int ) length; |
} |
|
static int release_and_return( packet_t packet, int result ){ |
int udp_release_and_return( packet_t packet, int result ){ |
pq_release( udp_globals.net_phone, packet_get_id( packet )); |
return result; |
} |
710,7 → 687,7 |
&& ( packet_set_addr( packet, src, src, ( size_t ) length ) == EOK )){ |
icmp_destination_unreachable_msg( udp_globals.icmp_phone, ICMP_PORT_UNREACH, 0, packet ); |
}else{ |
release_and_return( packet, EINVAL ); |
udp_release_and_return( packet, EINVAL ); |
} |
} |
|