@ -82,7 +82,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
static int udptlstart = 4500 ;
static int udptlend = 4599 ;
static int udptldebug ; /*!< Are we debugging? */
static struct sockaddr_in udptldebugaddr ; /*!< Debug packets to/from this host */
static struct ast_ sockaddr udptldebugaddr ; /*!< Debug packets to/from this host */
# ifdef SO_NO_CHECK
static int nochecksums ;
# endif
@ -121,8 +121,8 @@ struct ast_udptl {
unsigned int lasteventseqn ;
int nat ;
int flags ;
struct sockaddr_in us ;
struct sockaddr_in them ;
struct ast_ sockaddr us ;
struct ast_ sockaddr them ;
int * ioid ;
struct sched_context * sched ;
struct io_context * io ;
@ -172,8 +172,6 @@ struct ast_udptl {
int verbose ;
struct sockaddr_in far ;
unsigned int tx_seq_no ;
unsigned int rx_seq_no ;
unsigned int rx_expected_seq_no ;
@ -184,17 +182,20 @@ struct ast_udptl {
static AST_RWLIST_HEAD_STATIC ( protos , ast_udptl_protocol ) ;
static inline int udptl_debug_test_addr ( const struct sockaddr_in * addr )
static inline int udptl_debug_test_addr ( const struct ast_ sockaddr * addr )
{
if ( udptldebug = = 0 )
return 0 ;
if ( udptldebugaddr . sin_addr . s_addr ) {
if ( ( ( ntohs ( udptldebugaddr . sin_port ) ! = 0 ) & &
( udptldebugaddr . sin_port ! = addr - > sin_port ) ) | |
( udptldebugaddr . sin_addr . s_addr ! = addr - > sin_addr . s_addr ) )
return 0 ;
if ( ast_sockaddr_isnull ( & udptldebugaddr ) ) {
return 1 ;
}
if ( ast_sockaddr_port ( & udptldebugaddr ) ) {
return ! ast_sockaddr_cmp ( & udptldebugaddr , addr ) ;
} else {
return ! ast_sockaddr_cmp_addr ( & udptldebugaddr , addr ) ;
}
return 1 ;
}
static int decode_length ( uint8_t * buf , unsigned int limit , unsigned int * len , unsigned int * pvalue )
@ -672,20 +673,16 @@ static int udptlread(int *id, int fd, short events, void *cbdata)
struct ast_frame * ast_udptl_read ( struct ast_udptl * udptl )
{
int res ;
struct sockaddr_in sin ;
socklen_t len ;
struct ast_sockaddr addr ;
uint16_t seqno = 0 ;
uint16_t * udptlheader ;
len = sizeof ( sin ) ;
/* Cache where the header will go */
res = recvfrom( udptl - > fd ,
res = ast_ recvfrom( udptl - > fd ,
udptl - > rawdata + AST_FRIENDLY_OFFSET ,
sizeof ( udptl - > rawdata ) - AST_FRIENDLY_OFFSET ,
0 ,
( struct sockaddr * ) & sin ,
& len ) ;
& addr ) ;
udptlheader = ( uint16_t * ) ( udptl - > rawdata + AST_FRIENDLY_OFFSET ) ;
if ( res < 0 ) {
if ( errno ! = EAGAIN )
@ -696,22 +693,22 @@ struct ast_frame *ast_udptl_read(struct ast_udptl *udptl)
}
/* Ignore if the other side hasn't been given an address yet. */
if ( ! udptl - > them . sin_addr . s_addr | | ! udptl - > them . sin_port )
if ( ast_sockaddr_isnull ( & udptl - > them ) ) {
return & ast_null_frame ;
}
if ( udptl - > nat ) {
/* Send to whoever sent to us */
if ( ( udptl - > them . sin_addr . s_addr ! = sin . sin_addr . s_addr ) | |
( udptl - > them . sin_port ! = sin . sin_port ) ) {
memcpy ( & udptl - > them , & sin , sizeof ( udptl - > them ) ) ;
ast_debug ( 1 , " UDPTL NAT (%s): Using address %s:%d \n " ,
LOG_TAG ( udptl ) , ast_inet_ntoa ( udptl - > them . sin_addr ) , ntohs ( udptl - > them . sin_port ) ) ;
if ( ast_sockaddr_cmp ( & udptl - > them , & addr ) ) {
ast_sockaddr_copy ( & udptl - > them , & addr ) ;
ast_debug ( 1 , " UDPTL NAT (%s): Using address %s \n " ,
LOG_TAG ( udptl ) , ast_sockaddr_stringify ( & udptl - > them ) ) ;
}
}
if ( udptl_debug_test_addr ( & sin ) ) {
ast_verb ( 1 , " UDPTL (%s): packet from %s :%d (type %d, seq %d, len %d)\n " ,
LOG_TAG ( udptl ) , ast_ inet_ntoa( sin . sin_addr ) , ntohs ( sin . sin_port ) , 0 , seqno , res ) ;
if ( udptl_debug_test_addr ( & addr ) ) {
ast_verb ( 1 , " UDPTL (%s): packet from %s (type %d, seq %d, len %d)\n " ,
LOG_TAG ( udptl ) , ast_ sockaddr_stringify( & addr ) , 0 , seqno , res ) ;
}
if ( udptl_rx_packet ( udptl , udptl - > rawdata + AST_FRIENDLY_OFFSET , res ) < 1 )
return & ast_null_frame ;
@ -916,7 +913,7 @@ unsigned int ast_udptl_get_far_max_ifp(struct ast_udptl *udptl)
return udptl - > far_max_ifp ;
}
struct ast_udptl * ast_udptl_new_with_bindaddr ( struct sched_context * sched , struct io_context * io , int callbackmode , struct in_addr addr )
struct ast_udptl * ast_udptl_new_with_bindaddr ( struct sched_context * sched , struct io_context * io , int callbackmode , struct ast_sockaddr * addr )
{
struct ast_udptl * udptl ;
int x ;
@ -940,10 +937,8 @@ struct ast_udptl *ast_udptl_new_with_bindaddr(struct sched_context *sched, struc
udptl - > tx [ i ] . buf_len = - 1 ;
}
udptl - > them . sin_family = AF_INET ;
udptl - > us . sin_family = AF_INET ;
if ( ( udptl - > fd = socket ( AF_INET , SOCK_DGRAM , 0 ) ) < 0 ) {
if ( ( udptl - > fd = socket ( ast_sockaddr_is_ipv6 ( addr ) ?
AF_INET6 : AF_INET , SOCK_DGRAM , 0 ) ) < 0 ) {
ast_free ( udptl ) ;
ast_log ( LOG_WARNING , " Unable to allocate socket: %s \n " , strerror ( errno ) ) ;
return NULL ;
@ -961,10 +956,11 @@ struct ast_udptl *ast_udptl_new_with_bindaddr(struct sched_context *sched, struc
}
startplace = x ;
for ( ; ; ) {
udptl - > us . sin_port = htons ( x ) ;
udptl - > us . sin_addr = addr ;
if ( bind( udptl - > fd , ( struct sockaddr * ) & udptl - > us , sizeof ( udptl - > us ) ) = = 0 )
ast_sockaddr_copy ( & udptl - > us , addr ) ;
ast_sockaddr_set_port ( & udptl - > us , x ) ;
if ( ast_ bind( udptl - > fd , & udptl - > us ) = = 0 ) {
break ;
}
if ( errno ! = EADDRINUSE ) {
ast_log ( LOG_WARNING , " Unexpected bind error: %s \n " , strerror ( errno ) ) ;
close ( udptl - > fd ) ;
@ -994,13 +990,6 @@ struct ast_udptl *ast_udptl_new_with_bindaddr(struct sched_context *sched, struc
return udptl ;
}
struct ast_udptl * ast_udptl_new ( struct sched_context * sched , struct io_context * io , int callbackmode )
{
struct in_addr ia ;
memset ( & ia , 0 , sizeof ( ia ) ) ;
return ast_udptl_new_with_bindaddr ( sched , io , callbackmode , ia ) ;
}
void ast_udptl_set_tag ( struct ast_udptl * udptl , const char * format , . . . )
{
va_list ap ;
@ -1021,29 +1010,24 @@ int ast_udptl_setqos(struct ast_udptl *udptl, unsigned int tos, unsigned int cos
return ast_netsock_set_qos ( udptl - > fd , tos , cos , " UDPTL " ) ;
}
void ast_udptl_set_peer ( struct ast_udptl * udptl , const struct sockaddr_in * them )
void ast_udptl_set_peer ( struct ast_udptl * udptl , const struct ast_ sockaddr * them )
{
udptl - > them . sin_port = them - > sin_port ;
udptl - > them . sin_addr = them - > sin_addr ;
ast_sockaddr_copy ( & udptl - > them , them ) ;
}
void ast_udptl_get_peer ( const struct ast_udptl * udptl , struct sockaddr_in * them )
void ast_udptl_get_peer ( const struct ast_udptl * udptl , struct ast_ sockaddr * them )
{
memset ( them , 0 , sizeof ( * them ) ) ;
them - > sin_family = AF_INET ;
them - > sin_port = udptl - > them . sin_port ;
them - > sin_addr = udptl - > them . sin_addr ;
ast_sockaddr_copy ( them , & udptl - > them ) ;
}
void ast_udptl_get_us ( const struct ast_udptl * udptl , struct sockaddr_in * us )
void ast_udptl_get_us ( const struct ast_udptl * udptl , struct ast_sockaddr * us )
{
memc py( us , & udptl - > us , sizeof ( udptl - > us ) ) ;
ast_sockaddr_co py( us , & udptl - > us ) ;
}
void ast_udptl_stop ( struct ast_udptl * udptl )
{
memset ( & udptl - > them . sin_addr , 0 , sizeof ( udptl - > them . sin_addr ) ) ;
memset ( & udptl - > them . sin_port , 0 , sizeof ( udptl - > them . sin_port ) ) ;
ast_sockaddr_setnull ( & udptl - > them ) ;
}
void ast_udptl_destroy ( struct ast_udptl * udptl )
@ -1068,9 +1052,10 @@ int ast_udptl_write(struct ast_udptl *s, struct ast_frame *f)
memset ( buf , 0 , sizeof ( buf ) ) ;
/* If we have no peer, return immediately */
if ( s - > them . sin_addr . s_addr = = INADDR_ANY )
/* If we have no peer, return immediately */
if ( ast_sockaddr_isnull ( & s - > them ) ) {
return 0 ;
}
/* If there is no data length, return immediately */
if ( f - > datalen = = 0 )
@ -1097,13 +1082,13 @@ int ast_udptl_write(struct ast_udptl *s, struct ast_frame *f)
/* Cook up the UDPTL packet, with the relevant EC info. */
len = udptl_build_packet ( s , buf , sizeof ( buf ) , f - > data . ptr , len ) ;
if ( ( signed int ) len > 0 & & s - > them . sin_port & & s - > them . sin_addr . s_addr ) {
if ( ( res = sendto( s - > fd , buf , len , 0 , ( struct sockaddr * ) & s - > them , sizeof ( s - > them ) ) ) < 0 )
ast_log ( LOG_NOTICE , " (%s): UDPTL Transmission error to %s: %d: %s\n " ,
LOG_TAG ( s ) , ast_ inet_ntoa( s - > them . sin_addr ) , ntohs ( s - > them . sin_port ) , strerror ( errno ) ) ;
if ( ( signed int ) len > 0 & & ! ast_sockaddr_isnull ( & s - > them ) ) {
if ( ( res = ast_ sendto( s - > fd , buf , len , 0 , & s - > them ) ) < 0 )
ast_log ( LOG_NOTICE , " (%s): UDPTL Transmission error to %s: %s\n " ,
LOG_TAG ( s ) , ast_ sockaddr_stringify( & s - > them ) , strerror ( errno ) ) ;
if ( udptl_debug_test_addr ( & s - > them ) )
ast_verb ( 1 , " UDPTL (%s): packet to %s :%d (type %d, seq %d, len %d)\n " ,
LOG_TAG ( s ) , ast_ inet_ntoa( s - > them . sin_addr ) , ntohs ( s - > them . sin_port ) , 0 , seq , len ) ;
ast_verb ( 1 , " UDPTL (%s): packet to %s (type %d, seq %d, len %d)\n " ,
LOG_TAG ( s ) , ast_ sockaddr_stringify( & s - > them ) , 0 , seq , len ) ;
}
return 0 ;
@ -1156,10 +1141,10 @@ int ast_udptl_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags,
struct ast_udptl * p1 ;
struct ast_udptl_protocol * pr0 ;
struct ast_udptl_protocol * pr1 ;
struct sockaddr_in ac0 ;
struct sockaddr_in ac1 ;
struct sockaddr_in t0 ;
struct sockaddr_in t1 ;
struct ast_ sockaddr ac0 ;
struct ast_ sockaddr ac1 ;
struct ast_ sockaddr t0 ;
struct ast_ sockaddr t1 ;
void * pvt0 ;
void * pvt1 ;
int to ;
@ -1224,19 +1209,19 @@ int ast_udptl_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags,
to = - 1 ;
ast_udptl_get_peer ( p1 , & t1 ) ;
ast_udptl_get_peer ( p0 , & t0 ) ;
if ( inaddr cmp( & t1 , & ac1 ) ) {
ast_debug ( 1 , " Oooh, '%s' changed end address to %s :%d \n " ,
c1 - > name , ast_ inet_ntoa( t1 . sin_addr ) , ntohs ( t1 . sin_port ) ) ;
ast_debug ( 1 , " Oooh, '%s' was %s :%d \n " ,
c1 - > name , ast_ inet_ntoa( ac1 . sin_addr ) , ntohs ( ac1 . sin_port ) ) ;
memc py( & ac1 , & t1 , sizeof ( ac1 ) ) ;
if ( ast_sockaddr_ cmp( & t1 , & ac1 ) ) {
ast_debug ( 1 , " Oooh, '%s' changed end address to %s \n " ,
c1 - > name , ast_ sockaddr_stringify( & t1 ) ) ;
ast_debug ( 1 , " Oooh, '%s' was %s \n " ,
c1 - > name , ast_ sockaddr_stringify( & ac1 ) ) ;
ast_sockaddr_co py( & ac1 , & t1 ) ;
}
if ( inaddr cmp( & t0 , & ac0 ) ) {
ast_debug ( 1 , " Oooh, '%s' changed end address to %s :%d \n " ,
c0 - > name , ast_ inet_ntoa( t0 . sin_addr ) , ntohs ( t0 . sin_port ) ) ;
ast_debug ( 1 , " Oooh, '%s' was %s :%d \n " ,
c0 - > name , ast_ inet_ntoa( ac0 . sin_addr ) , ntohs ( ac0 . sin_port ) ) ;
memc py( & ac0 , & t0 , sizeof ( ac0 ) ) ;
if ( ast_sockaddr_ cmp( & t0 , & ac0 ) ) {
ast_debug ( 1 , " Oooh, '%s' changed end address to %s \n " ,
c0 - > name , ast_ sockaddr_stringify( & t0 ) ) ;
ast_debug ( 1 , " Oooh, '%s' was %s \n " ,
c0 - > name , ast_ sockaddr_stringify( & ac0 ) ) ;
ast_sockaddr_co py( & ac0 , & t0 ) ;
}
who = ast_waitfor_n ( cs , 2 , & to ) ;
if ( ! who ) {
@ -1274,12 +1259,6 @@ int ast_udptl_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags,
static char * handle_cli_udptl_set_debug ( struct ast_cli_entry * e , int cmd , struct ast_cli_args * a )
{
struct hostent * hp ;
struct ast_hostent ahp ;
int port ;
char * p ;
char * arg ;
switch ( cmd ) {
case CLI_INIT :
e - > command = " udptl set debug {on|off|ip} " ;
@ -1308,27 +1287,16 @@ static char *handle_cli_udptl_set_debug(struct ast_cli_entry *e, int cmd, struct
return CLI_SHOWUSAGE ;
}
} else {
struct ast_sockaddr * addrs ;
if ( strncasecmp ( a - > argv [ 3 ] , " ip " , 2 ) )
return CLI_SHOWUSAGE ;
port = 0 ;
arg = ast_strdupa ( a - > argv [ 4 ] ) ;
p = strstr ( arg , " : " ) ;
if ( p ) {
* p = ' \0 ' ;
p + + ;
port = atoi ( p ) ;
}
hp = ast_gethostbyname ( arg , & ahp ) ;
if ( hp = = NULL )
if ( ! ast_sockaddr_resolve ( & addrs , a - > argv [ 4 ] , 0 , 0 ) ) {
return CLI_SHOWUSAGE ;
udptldebugaddr . sin_family = AF_INET ;
memcpy ( & udptldebugaddr . sin_addr , hp - > h_addr , sizeof ( udptldebugaddr . sin_addr ) ) ;
udptldebugaddr . sin_port = htons ( port ) ;
if ( port = = 0 )
ast_cli ( a - > fd , " UDPTL Debugging Enabled for IP: %s \n " , ast_inet_ntoa ( udptldebugaddr . sin_addr ) ) ;
else
ast_cli ( a - > fd , " UDPTL Debugging Enabled for IP: %s:%d \n " , ast_inet_ntoa ( udptldebugaddr . sin_addr ) , port ) ;
}
ast_sockaddr_copy ( & udptldebugaddr , & addrs [ 0 ] ) ;
ast_cli ( a - > fd , " UDPTL Debugging Enabled for IP: %s \n " , ast_sockaddr_stringify ( & udptldebugaddr ) ) ;
udptldebug = 1 ;
ast_free ( addrs ) ;
}
return CLI_SUCCESS ;