Subversion Repositories HelenOS

Compare Revisions

No changes between revisions

Ignore whitespace Rev 4725 → Rev 4726

/branches/network/uspace/srv/net/tl/tcp/Makefile
38,6 → 38,7
SOURCES = \
$(NAME).c \
$(NAME)_module.c \
$(NET_BASE)crc.c \
$(NET_BASE)module.c \
$(NET_BASE)modules.c \
$(NET_BASE)il/ip/ip_client.c \
47,6 → 48,7
$(NET_BASE)tl/icmp/icmp_client.c \
$(NET_BASE)tl/icmp/icmp_common.c \
$(NET_BASE)tl/icmp/icmp_remote.c \
$(NET_BASE)tl/tl_common.c \
$(STRUCTURES)dynamic_fifo.c \
$(STRUCTURES)measured_strings.c \
$(STRUCTURES)packet/packet.c \
/branches/network/uspace/srv/net/tl/udp/udp.c
65,6 → 65,7
#include "../../socket/socket_core.h"
#include "../../socket/socket_messages.h"
 
#include "../tl_common.h"
#include "../tl_messages.h"
 
#include "udp.h"
113,14 → 114,6
*/
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.
* Releases the packet queu on error.
* @param packet The packet to be send. Input parameter.
* @param error The packet error reporting service. Prefixes the received packet. Input parameter.
*/
void udp_send_icmp_port_unreachable( packet_t packet, services_t error );
 
/** @name Socket messages processing functions
*/
/*@{*/
143,6 → 136,7
* @param addr The destination address. Input parameter.
* @param addrlen The address length. Input parameter.
* @param fragments The number of data fragments. Input parameter.
* @param data_fragment_size The data fragment size in bytes. Input parameter.
* @param flags Various send flags. Input parameter.
* @returns EOK on success.
* @returns EAFNOTSUPPORT if the address family is not supported.
154,7 → 148,7
* @returns Other error codes as defined for the ip_client_prepare_packet() function.
* @returns Other error codes as defined for the ip_send_msg() function.
*/
int udp_sendto_message( socket_cores_ref local_sockets, int socket_id, const struct sockaddr * addr, socklen_t addrlen, int fragments, int flags );
int udp_sendto_message( socket_cores_ref local_sockets, int socket_id, const struct sockaddr * addr, socklen_t addrlen, int fragments, size_t data_fragment_size, int flags );
 
/** Receives data to the socket.
* Handles the NET_SOCKET_RECVFROM message.
175,29 → 169,6
 
/*@}*/
 
/** Receives data from the socket into a packet.
* @param packet The new created packet. Output parameter.
* @param prefix Reserved packet data prefix length. Input parameter.
* @param addr The destination address. Input parameter.
* @param addrlen The address length. Input parameter.
* @returns Number of bytes received.
* @returns EINVAL if the client does not send data.
* @returns ENOMEM if there is not enough memory left.
* @returns Other error codes as defined for the ipc_data_read_finalize() function.
*/
int socket_read_packet_data( packet_ref packet, size_t prefix, const struct sockaddr * addr, socklen_t addrlen );
 
/** Sets the address port.
* Supports AF_INET and AF_INET6 address families.
* @param addr The address to be updated. Input/output parameter.
* @param addrlen The address length. Input parameter.
* @param port The port to be set. Input parameter.
* @returns EOK on success.
* @returns EINVAL if the address length does not match the address family.
* @returns EAFNOSUPPORT if the address family is not supported.
*/
int udp_set_address_port( struct sockaddr * addr, int addrlen, uint16_t port );
 
/** UDP global data.
*/
udp_globals_t udp_globals;
220,10 → 191,10
if( udp_globals.ip_phone < 0 ){
return udp_globals.ip_phone;
}
ERROR_PROPAGATE( ip_packet_size_req( udp_globals.ip_phone, -1, & udp_globals.addr_len, & udp_globals.prefix, & udp_globals.content, & udp_globals.suffix ));
ERROR_PROPAGATE( ip_packet_size_req( udp_globals.ip_phone, -1, & udp_globals.packet_dimension.addr_len, & udp_globals.packet_dimension.prefix, & udp_globals.packet_dimension.content, & udp_globals.packet_dimension.suffix ));
ERROR_PROPAGATE( socket_ports_initialize( & udp_globals.sockets ));
udp_globals.prefix += sizeof( udp_header_t );
udp_globals.content -= sizeof( udp_header_t );
udp_globals.packet_dimension.prefix += sizeof( udp_header_t );
udp_globals.packet_dimension.content -= sizeof( udp_header_t );
udp_globals.last_used_port = UDP_FREE_PORTS_START - 1;
// get configuration
udp_globals.checksum_computing = NET_DEFAULT_UDP_CHECKSUM_COMPUTING;
302,7 → 273,7
// find the destination socket
socket = socket_ports_find( & udp_globals.sockets, ntohs( header->dest ));
if( ! socket ){
udp_send_icmp_port_unreachable( packet, error );
tl_send_icmp_port_unreachable( udp_globals.net_phone, udp_globals.icmp_phone, packet, error );
return EADDRNOTAVAIL;
}
// trim after successful processing to be able to send an ICMP error message!
373,7 → 344,7
}
 
// notify the destination socket
async_msg_2(( ** socket ).phone, NET_SOCKET_RECEIVED, ( ipcarg_t ) ( ** socket ).socket_id, ( ipcarg_t ) fragments );
async_msg_5(( ** socket ).phone, NET_SOCKET_RECEIVED, ( ipcarg_t ) ( ** socket ).socket_id, 0, 0, 0, ( ipcarg_t ) fragments );
return EOK;
}
 
404,7 → 375,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;
 
414,8 → 385,10
*/
ipc_answer_0( callid, EOK );
 
// 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
430,21 → 403,21
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 );
// fibril_rwlock_write_lock( & lock );
res = socket_create( & local_sockets, app_phone, NULL, SOCKET_SET_SOCKET_ID( answer ));
// fibril_rwlock_write_unlock( & lock );
* SOCKET_SET_DATA_FRAGMENT_SIZE( answer ) = MAX_UDP_FRAGMENT_SIZE;
* SOCKET_SET_HEADER_SIZE( answer ) = sizeof( udp_header_t );
* SOCKET_SET_DATA_FRAGMENT_SIZE( answer ) = MAX_UDP_FRAGMENT_SIZE;
answer_count = 3;
break;
case NET_SOCKET_BIND:
res = data_receive(( void ** ) & addr, & addrlen );
if( res == EOK ){
fibril_rwlock_write_lock( & lock );
// 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 );
// fibril_rwlock_write_unlock( & lock );
free( addr );
}
break;
451,20 → 424,20
case NET_SOCKET_SENDTO:
res = data_receive(( void ** ) & addr, & addrlen );
if( res == EOK ){
fibril_rwlock_read_lock( & lock );
// 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 ));
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_read_unlock( & lock );
free( addr );
}
break;
case NET_SOCKET_RECVFROM:
fibril_rwlock_read_lock( & lock );
// 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 ), & addrlen );
fibril_rwlock_read_unlock( & udp_globals.lock );
fibril_rwlock_read_unlock( & lock );
// fibril_rwlock_read_unlock( & lock );
if( res > 0 ){
* SOCKET_SET_READ_DATA_LENGTH( answer ) = res;
* SOCKET_SET_ADDRESS_LENGTH( answer ) = addrlen;
473,11 → 446,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 );
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:
491,17 → 464,16
answer_call( callid, res, & answer, answer_count );
}
 
// TODO call socket_destroy() on all bound!
socket_cores_destroy( & local_sockets );
 
return EOK;
}
 
int udp_sendto_message( socket_cores_ref local_sockets, int socket_id, const struct sockaddr * addr, socklen_t addrlen, int fragments, int flags ){
int udp_sendto_message( socket_cores_ref local_sockets, int socket_id, const struct sockaddr * addr, socklen_t addrlen, int fragments, size_t data_fragment_size, int flags ){
ERROR_DECLARE;
 
socket_core_ref socket;
struct sockaddr_in * address_in;
struct sockaddr_in6 * address_in6;
packet_t packet;
packet_t next_packet;
udp_header_ref header;
514,21 → 486,7
size_t headerlen;
device_id_t device_id;
 
if( addrlen < sizeof( struct sockaddr )) return EINVAL;
switch( addr->sa_family ){
case AF_INET:
if( addrlen != sizeof( struct sockaddr_in )) return EINVAL;
address_in = ( struct sockaddr_in * ) addr;
dest_port = address_in->sin_port;
break;
case AF_INET6:
if( addrlen != sizeof( struct sockaddr_in6 )) return EINVAL;
address_in6 = ( struct sockaddr_in6 * ) addr;
dest_port = address_in6->sin6_port;
break;
default:
return EAFNOSUPPORT;
}
ERROR_PROPAGATE( tl_get_address_port( addr, addrlen, & dest_port ));
 
socket = socket_cores_find( local_sockets, socket_id );
if( ! socket ) return ENOTSOCK;
548,10 → 506,10
}
 
// TODO do not ask all the time
ERROR_PROPAGATE( ip_packet_size_req( udp_globals.ip_phone, socket->device_id, & udp_globals.addr_len, & udp_globals.prefix, & udp_globals.content, & udp_globals.suffix ));
ERROR_PROPAGATE( ip_packet_size_req( udp_globals.ip_phone, -1, & udp_globals.packet_dimension.addr_len, & udp_globals.packet_dimension.prefix, & udp_globals.packet_dimension.content, & udp_globals.packet_dimension.suffix ));
 
// read the first packet fragment
result = socket_read_packet_data( & packet, sizeof( udp_header_t ), addr, addrlen );
result = tl_socket_read_packet_data( udp_globals.net_phone, & packet, sizeof( udp_header_t ), & udp_globals.packet_dimension, addr, addrlen );
if( result < 0 ) return result;
total_length = ( size_t ) result;
if( udp_globals.checksum_computing ){
567,7 → 525,7
bzero( header, sizeof( * header ));
// read the rest of the packet fragments
for( index = 1; index < fragments; ++ index ){
result = socket_read_packet_data( & next_packet, 0, addr, addrlen );
result = tl_socket_read_packet_data( udp_globals.net_phone, & next_packet, 0, & udp_globals.packet_dimension, addr, addrlen );
if( result < 0 ){
return udp_release_and_return( packet, result );
}
599,7 → 557,7
header->check = htons( flip_checksum( compact_checksum( checksum )));
free( ip_header );
}else{
device_id = socket->device_id;
device_id = -1;
}
// prepare the first packet fragment
if( ERROR_OCCURRED( ip_client_prepare_packet( packet, IPPROTO_UDP, 0, 0, 0, 0 ))){
642,7 → 600,7
 
// set the source address port
result = packet_get_addr( packet, ( uint8_t ** ) & addr, NULL );
if( ERROR_OCCURRED( udp_set_address_port( addr, result, ntohs( header->source )))){
if( ERROR_OCCURRED( tl_set_address_port( addr, result, ntohs( header->source )))){
pq_release( udp_globals.net_phone, packet_id );
return ERROR_CODE;
}
695,82 → 653,10
return ( int ) length;
}
 
int socket_read_packet_data( packet_ref packet, size_t prefix, const struct sockaddr * addr, socklen_t addrlen ){
ERROR_DECLARE;
 
ipc_callid_t callid;
size_t length;
void * data;
 
// get the data length
if( ! ipc_data_write_receive( & callid, & length )) return EINVAL;
// get a new packet
* packet = packet_get_4( udp_globals.net_phone, length, udp_globals.addr_len, prefix + udp_globals.prefix, udp_globals.suffix );
if( ! packet ) return ENOMEM;
// allocate space in the packet
data = packet_suffix( * packet, length );
if( ! data ){
return udp_release_and_return( * packet, ENOMEM );
}
// read the data into the packet
if( ERROR_OCCURRED( ipc_data_write_finalize( callid, data, length ))
// set the packet destination address
|| ERROR_OCCURRED( packet_set_addr( * packet, NULL, ( uint8_t * ) addr, addrlen ))){
return udp_release_and_return( * packet, ERROR_CODE );
}
return ( int ) length;
}
 
int udp_release_and_return( packet_t packet, int result ){
pq_release( udp_globals.net_phone, packet_get_id( packet ));
return result;
}
 
void udp_send_icmp_port_unreachable( packet_t packet, services_t error ){
packet_t next;
uint8_t * src;
int length;
 
// detach the first packet and release the others
next = pq_detach( packet );
if( next ){
pq_release( udp_globals.net_phone, packet_get_id( next ));
}
length = packet_get_addr( packet, & src, NULL );
if(( length > 0 )
&& ( ! 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, ( size_t ) length ) == EOK )){
icmp_destination_unreachable_msg( udp_globals.icmp_phone, ICMP_PORT_UNREACH, 0, packet );
}else{
udp_release_and_return( packet, EINVAL );
}
}
 
int udp_set_address_port( struct sockaddr * addr, int addrlen, uint16_t port ){
struct sockaddr_in * address_in;
struct sockaddr_in6 * address_in6;
size_t length;
 
if( addrlen < 0 ) return EINVAL;
length = ( size_t ) addrlen;
if( length < sizeof( struct sockaddr )) return EINVAL;
switch( addr->sa_family ){
case AF_INET:
if( length != sizeof( struct sockaddr_in )) return EINVAL;
address_in = ( struct sockaddr_in * ) addr;
address_in->sin_port = port;
return EOK;
case AF_INET6:
if( length != sizeof( struct sockaddr_in6 )) return EINVAL;
address_in6 = ( struct sockaddr_in6 * ) addr;
address_in6->sin6_port = port;
return EOK;
default:
return EAFNOSUPPORT;
}
}
 
/** @}
*/
/branches/network/uspace/srv/net/tl/udp/Makefile
48,6 → 48,7
$(NET_BASE)tl/icmp/icmp_client.c \
$(NET_BASE)tl/icmp/icmp_common.c \
$(NET_BASE)tl/icmp/icmp_remote.c \
$(NET_BASE)tl/tl_common.c \
$(STRUCTURES)dynamic_fifo.c \
$(STRUCTURES)measured_strings.c \
$(STRUCTURES)packet/packet.c \
/branches/network/uspace/srv/net/tl/udp/udp.h
41,6 → 41,8
 
#include "../../socket/socket_core.h"
 
#include "../tl_common.h"
 
/** Type definition of the UDP global data.
* @see udp_globals
*/
58,18 → 60,9
/** ICMP module phone.
*/
int icmp_phone;
/** Reserved packet prefix length.
/** Packet dimension.
*/
size_t prefix;
/** Maximal packet content length.
*/
size_t content;
/** Reserved packet suffix length.
*/
size_t suffix;
/** Packet address length.
*/
size_t addr_len;
packet_dimension_t packet_dimension;
/** Indicates whether UDP checksum computing is enabled.
*/
int checksum_computing;
/branches/network/uspace/srv/net/tl/tl_common.c
0,0 → 1,154
/*
* Copyright (c) 2008 Lukas Mejdrech
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup net_tl
* @{
*/
 
/** @file
* Transport layer common functions implementation.
* @see tl_common.h
*/
 
#include <async.h>
#include <ipc/services.h>
 
#include "../err.h"
 
#include "../structures/packet/packet.h"
#include "../structures/packet/packet_client.h"
 
#include "../include/icmp_interface.h"
#include "../include/in.h"
#include "../include/in6.h"
#include "../include/inet.h"
#include "../include/socket_codes.h"
#include "../include/socket_errno.h"
 
#include "tl_common.h"
 
int tl_get_address_port( const struct sockaddr * addr, int addrlen, uint16_t * port ){
const struct sockaddr_in * address_in;
const struct sockaddr_in6 * address_in6;
 
if( addrlen < sizeof( struct sockaddr )) return EINVAL;
switch( addr->sa_family ){
case AF_INET:
if( addrlen != sizeof( struct sockaddr_in )) return EINVAL;
address_in = ( struct sockaddr_in * ) addr;
* port = address_in->sin_port;
break;
case AF_INET6:
if( addrlen != sizeof( struct sockaddr_in6 )) return EINVAL;
address_in6 = ( struct sockaddr_in6 * ) addr;
* port = address_in6->sin6_port;
break;
default:
return EAFNOSUPPORT;
}
return EOK;
}
 
 
int tl_set_address_port( struct sockaddr * addr, int addrlen, uint16_t port ){
struct sockaddr_in * address_in;
struct sockaddr_in6 * address_in6;
size_t length;
 
if( addrlen < 0 ) return EINVAL;
length = ( size_t ) addrlen;
if( length < sizeof( struct sockaddr )) return EINVAL;
switch( addr->sa_family ){
case AF_INET:
if( length != sizeof( struct sockaddr_in )) return EINVAL;
address_in = ( struct sockaddr_in * ) addr;
address_in->sin_port = port;
return EOK;
case AF_INET6:
if( length != sizeof( struct sockaddr_in6 )) return EINVAL;
address_in6 = ( struct sockaddr_in6 * ) addr;
address_in6->sin6_port = port;
return EOK;
default:
return EAFNOSUPPORT;
}
}
 
void tl_send_icmp_port_unreachable( int packet_phone, int icmp_phone, packet_t packet, services_t error ){
packet_t next;
uint8_t * src;
int length;
 
// detach the first packet and release the others
next = pq_detach( packet );
if( next ){
pq_release( packet_phone, packet_get_id( next ));
}
length = packet_get_addr( packet, & src, NULL );
if(( length > 0 )
&& ( ! error )
&& ( 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, ( size_t ) length ) == EOK )){
icmp_destination_unreachable_msg( icmp_phone, ICMP_PORT_UNREACH, 0, packet );
}else{
pq_release( packet_phone, packet_get_id( packet ));
}
}
 
int tl_socket_read_packet_data( int packet_phone, packet_ref packet, size_t prefix, const packet_dimension_ref dimension, const struct sockaddr * addr, socklen_t addrlen ){
ERROR_DECLARE;
 
ipc_callid_t callid;
size_t length;
void * data;
 
if( ! dimension ) return EINVAL;
// get the data length
if( ! ipc_data_write_receive( & callid, & length )) return EINVAL;
// get a new packet
* packet = packet_get_4( packet_phone, length, dimension->addr_len, prefix + dimension->prefix, dimension->suffix );
if( ! packet ) return ENOMEM;
// allocate space in the packet
data = packet_suffix( * packet, length );
if( ! data ){
pq_release( packet_phone, packet_get_id( * packet ));
return ENOMEM;
}
// read the data into the packet
if( ERROR_OCCURRED( ipc_data_write_finalize( callid, data, length ))
// set the packet destination address
|| ERROR_OCCURRED( packet_set_addr( * packet, NULL, ( uint8_t * ) addr, addrlen ))){
pq_release( packet_phone, packet_get_id( * packet ));
return ERROR_CODE;
}
return ( int ) length;
}
 
/** @}
*/
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/branches/network/uspace/srv/net/tl/tl_common.h
0,0 → 1,122
/*
* Copyright (c) 2008 Lukas Mejdrech
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup net_tl
* @{
*/
 
/** @file
* Transport layer common functions.
*/
 
#ifndef __NET_TL_COMMON_H__
#define __NET_TL_COMMON_H__
 
#include "../structures/packet/packet.h"
 
#include "../include/inet.h"
#include "../include/socket_codes.h"
 
/** Type definition of the packet dimension.
* @see packet_dimension
*/
typedef struct packet_dimension packet_dimension_t;
 
/** Type definition of the packet dimension pointer.
* @see packet_dimension
*/
typedef packet_dimension_t * packet_dimension_ref;
 
/** Packet dimension.
*/
struct packet_dimension{
/** Reserved packet prefix length.
*/
size_t prefix;
/** Maximal packet content length.
*/
size_t content;
/** Reserved packet suffix length.
*/
size_t suffix;
/** Maximal packet address length.
*/
size_t addr_len;
};
 
/** Gets the address port.
* Supports AF_INET and AF_INET6 address families.
* @param addr The address to be updated. Input/output parameter.
* @param addrlen The address length. Input parameter.
* @param port The set port. Output parameter.
* @returns EOK on success.
* @returns EINVAL if the address length does not match the address family.
* @returns EAFNOSUPPORT if the address family is not supported.
*/
int tl_get_address_port( const struct sockaddr * addr, int addrlen, uint16_t * port );
 
/** Sets the address port.
* Supports AF_INET and AF_INET6 address families.
* @param addr The address to be updated. Input/output parameter.
* @param addrlen The address length. Input parameter.
* @param port The port to be set. Input parameter.
* @returns EOK on success.
* @returns EINVAL if the address length does not match the address family.
* @returns EAFNOSUPPORT if the address family is not supported.
*/
int tl_set_address_port( struct sockaddr * addr, int addrlen, uint16_t port );
 
/** Sends the port unreachable ICMP notification.
* Sends the first packet and releases all the others.
* Releases the packet queu on error.
* @param packet_phone The packet server module phone. Input parameter.
* @param icmp_phone The ICMP module phone. Input parameter.
* @param packet The packet to be send. Input parameter.
* @param error The packet error reporting service. Prefixes the received packet. Input parameter.
*/
void tl_send_icmp_port_unreachable( int packet_phone, int icmp_phone, packet_t packet, services_t error );
 
/** Receives data from the socket into a packet.
* @param packet_phone The packet server module phone. Input parameter.
* @param packet The new created packet. Output parameter.
* @param prefix Reserved packet data prefix length. Input parameter.
* @param dimension The packet dimension. Input parameter.
* @param addr The destination address. Input parameter.
* @param addrlen The address length. Input parameter.
* @returns Number of bytes received.
* @returns EINVAL if the client does not send data.
* @returns ENOMEM if there is not enough memory left.
* @returns Other error codes as defined for the ipc_data_read_finalize() function.
*/
int tl_socket_read_packet_data( int packet_phone, packet_ref packet, size_t prefix, const packet_dimension_ref dimension, const struct sockaddr * addr, socklen_t addrlen );
 
#endif
 
/** @}
*/
 
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property