226,13 → 226,14 |
int udp_received_msg( device_id_t device_id, packet_t packet, services_t receiver, services_t error ){ |
ERROR_DECLARE; |
|
int length; |
int offset; |
size_t length; |
size_t offset; |
int result; |
uint8_t * data; |
udp_header_ref header; |
socket_core_ref * socket; |
packet_t next_packet; |
int total_length; |
size_t total_length; |
// uint16_t checksum; |
int fragments; |
packet_t tmp_packet; |
245,11 → 246,12 |
// process error |
// TODO remove debug dump |
// length = icmp_client_header_length( packet ); |
length = icmp_client_process_packet( packet, & type, & code, NULL, NULL ); |
if( length < 0 ){ |
return release_and_return( packet, length ); |
result = icmp_client_process_packet( packet, & type, & code, NULL, NULL ); |
if( result < 0 ){ |
return 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 ); |
} |
259,10 → 261,11 |
} |
} |
// TODO process received ipopts? |
offset = ip_client_process_packet( packet, NULL, NULL, NULL, NULL, NULL ); |
if( offset < 0 ){ |
return release_and_return( packet, offset ); |
result = ip_client_process_packet( packet, NULL, NULL, NULL, NULL, NULL ); |
if( result < 0 ){ |
return release_and_return( packet, result ); |
} |
offset = ( size_t ) result; |
|
length = packet_get_data_length( packet ); |
if( length <= 0 ){ |
292,7 → 295,7 |
do{ |
++ fragments; |
length = packet_get_data_length( packet ); |
if( ! length ){ |
if( length <= 0 ){ |
return release_and_return( packet, NO_DATA ); |
} |
if( total_length < length ){ |
320,7 → 323,7 |
} |
|
// notify the destination socket |
async_msg_2(( ** socket ).phone, NET_SOCKET_RECEIVED, ( ** socket ).socket_id, fragments ); |
async_msg_2(( ** socket ).phone, NET_SOCKET_RECEIVED, ( ipcarg_t ) ( ** socket ).socket_id, ( ipcarg_t ) fragments ); |
return EOK; |
} |
|
448,17 → 451,17 |
// printf( "res = %d\n", res ); |
|
switch( answer_count ){ |
case 0: ipc_answer_0( callid, res ); |
case 0: ipc_answer_0( callid, ( ipcarg_t ) res ); |
continue; |
case 1: ipc_answer_1( callid, res, IPC_GET_ARG1( answer )); |
case 1: ipc_answer_1( callid, ( ipcarg_t ) res, IPC_GET_ARG1( answer )); |
continue; |
case 2: ipc_answer_2( callid, res, IPC_GET_ARG1( answer ), IPC_GET_ARG2( answer )); |
case 2: ipc_answer_2( callid, ( ipcarg_t ) res, IPC_GET_ARG1( answer ), IPC_GET_ARG2( answer )); |
continue; |
case 3: ipc_answer_3( callid, res, IPC_GET_ARG1( answer ), IPC_GET_ARG2( answer ), IPC_GET_ARG3( answer )); |
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, res, IPC_GET_ARG1( answer ), IPC_GET_ARG2( answer ), IPC_GET_ARG3( answer ), IPC_GET_ARG4( answer )); |
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, res, IPC_GET_ARG1( answer ), IPC_GET_ARG2( answer ), IPC_GET_ARG3( answer ), IPC_GET_ARG4( answer ), IPC_GET_ARG5( answer )); |
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; |
} |
} |
478,8 → 481,8 |
packet_t next_packet; |
udp_header_ref header; |
int index; |
int total_length; |
int length; |
size_t total_length; |
int result; |
|
if( addrlen < sizeof( struct sockaddr )) return EINVAL; |
address = ( struct sockaddr * ) addr; |
505,8 → 508,9 |
ERROR_PROPAGATE( ip_packet_size_req( udp_globals.ip_phone, -1, & udp_globals.addr_len, & udp_globals.prefix, & udp_globals.content, & udp_globals.suffix )); |
|
// read the first packet fragment |
total_length = socket_read_packet_data( & packet, sizeof( udp_header_t ), address_in ); |
if( total_length < 0 ) return total_length; |
result = socket_read_packet_data( & packet, sizeof( udp_header_t ), address_in ); |
if( result < 0 ) return result; |
total_length = ( size_t ) result; |
// prefix the udp header |
header = PACKET_PREFIX( packet, udp_header_t ); |
if( ! header ){ |
515,16 → 519,15 |
} |
// read the rest of the packet fragments |
for( index = 1; index < fragments; ++ index ){ |
length = socket_read_packet_data( & next_packet, 0, address_in ); |
if( length < 0 ){ |
pq_release( udp_globals.net_phone, packet_get_id( packet )); |
return length; |
result = socket_read_packet_data( & next_packet, 0, address_in ); |
if( result < 0 ){ |
return release_and_return( packet, result ); |
} |
packet = pq_add( packet, next_packet, index, 0 ); |
total_length += length; |
total_length += ( size_t ) result; |
} |
// set the udp header |
header->source = ( socket->port < 0 ) ? 0 : htons( socket->port ); |
header->source = htons( socket->port ); |
header->dest = htons( address_in->sin_port ); |
header->len = htons( total_length + sizeof( udp_header_t )); |
// TODO my ip address for the pseudo header checksum |
537,11 → 540,9 |
// send the packet |
return ip_send_msg( udp_globals.ip_phone, socket->device_id, packet, SERVICE_UDP, 0 ); |
// TODO IPv6 |
default: |
} |
return EAFNOSUPPORT; |
} |
return EOK; |
} |
|
int udp_recvfrom_message( socket_cores_ref local_sockets, int socket_id, int flags ){ |
ERROR_DECLARE; |
551,12 → 552,13 |
packet_t packet; |
udp_header_ref header; |
struct sockaddr_in address; |
int length; |
size_t length; |
packet_t next_packet; |
void * data; |
int fragments; |
int * lengths; |
int index; |
uint8_t * data; |
size_t fragments; |
size_t * lengths; |
int result; |
size_t index; |
uint8_t * addr; |
|
// find the socket |
576,8 → 578,8 |
// set the source address |
address.sin_family = PF_INET; |
address.sin_port = ntohs( header->source ); |
length = packet_get_addr( packet, & addr, NULL ); |
if( length != sizeof( address.sin_addr.s_addr )){ |
result = packet_get_addr( packet, & addr, NULL ); |
if( result != sizeof( address.sin_addr.s_addr )){ |
pq_release( udp_globals.net_phone, packet_id ); |
return EINVAL; |
} |
599,7 → 601,7 |
++ fragments; |
} |
// compute and store the fragment lengths |
lengths = ( int * ) malloc( sizeof( int ) * ( fragments + 1 )); |
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 ]; |
627,7 → 629,7 |
dyn_fifo_pop( & socket->received ); |
pq_release( udp_globals.net_phone, packet_get_id( packet )); |
// return the total length |
return length; |
return ( int ) length; |
} |
|
int socket_write_data( void * data, size_t data_length ){ |
682,7 → 684,7 |
pq_release( udp_globals.net_phone, packet_get_id( * packet )); |
return ERROR_CODE; |
} |
return length; |
return ( int ) length; |
} |
|
static int release_and_return( packet_t packet, int result ){ |
705,10 → 707,10 |
&& ( ! error ) |
&& ( udp_globals.icmp_phone >= 0 ) |
// set both addresses to the source one (avoids the source address deletion before setting the destination one) |
&& ( packet_set_addr( packet, src, src, length ) == EOK )){ |
&& ( packet_set_addr( packet, src, src, ( size_t ) length ) == EOK )){ |
icmp_destination_unreachable_msg( udp_globals.icmp_phone, ICMP_PORT_UNREACH, 0, packet ); |
}else{ |
return release_and_return( packet, EINVAL ); |
release_and_return( packet, EINVAL ); |
} |
} |
|