@ -51,6 +51,7 @@ ASTERISK_REGISTER_FILE()
 
			
		
	
		
		
			
				
					
					# include  <pjlib.h> # include  <pjlib.h>  
			
		
	
		
		
			
				
					
					# include  <pjlib-util.h> # include  <pjlib-util.h>  
			
		
	
		
		
			
				
					
					# include  <pjnath.h> # include  <pjnath.h>  
			
		
	
		
		
			
				
					
					# include  <ifaddrs.h>  
			
		
	
		
		
			
				
					
					# endif # endif  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					# include  "asterisk/stun.h" # include  "asterisk/stun.h"  
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -145,6 +146,9 @@ static pj_str_t turnaddr;
 
			
		
	
		
		
			
				
					
					static  int  turnport  =  DEFAULT_TURN_PORT ; static  int  turnport  =  DEFAULT_TURN_PORT ;  
			
		
	
		
		
			
				
					
					static  pj_str_t  turnusername ; static  pj_str_t  turnusername ;  
			
		
	
		
		
			
				
					
					static  pj_str_t  turnpassword ; static  pj_str_t  turnpassword ;  
			
		
	
		
		
			
				
					
					static  struct  ast_ha  * ice_blacklist  =  NULL ;     /*!< Blacklisted ICE networks */  
			
		
	
		
		
			
				
					
					static  ast_rwlock_t  ice_blacklist_lock  =  AST_RWLOCK_INIT_VALUE ;  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					/*! \brief Pool factory used by pjlib to allocate memory. */ /*! \brief Pool factory used by pjlib to allocate memory. */  
			
		
	
		
		
			
				
					
					static  pj_caching_pool  cachingpool ; static  pj_caching_pool  cachingpool ;  
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -2446,11 +2450,38 @@ static int rtp_learning_rtp_seq_update(struct rtp_learning_info *info, uint16_t
 
			
		
	
		
		
			
				
					
					} }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					# ifdef HAVE_PJPROJECT # ifdef HAVE_PJPROJECT  
			
		
	
		
		
			
				
					
					/*!
  
			
		
	
		
		
			
				
					
					 *  \ internal 
 
			
		
	
		
		
			
				
					
					 *  \ brief  Checks  an  address  against  the  ICE  blacklist 
 
			
		
	
		
		
			
				
					
					 *  \ note  If  there  is  no  ice_blacklist  list ,  always  returns  0 
 
			
		
	
		
		
			
				
					
					 * 
 
			
		
	
		
		
			
				
					
					 *  \ param  address  The  address  to  consider 
 
			
		
	
		
		
			
				
					
					 *  \ retval  0  if  address  is  not  ICE  blacklisted 
 
			
		
	
		
		
			
				
					
					 *  \ retval  1  if  address  is  ICE  blacklisted 
 
			
		
	
		
		
			
				
					
					 */ 
 
			
		
	
		
		
			
				
					
					static  int  rtp_address_is_ice_blacklisted ( const  pj_sockaddr_t  * address )  
			
		
	
		
		
			
				
					
					{  
			
		
	
		
		
			
				
					
						char  buf [ PJ_INET6_ADDRSTRLEN ] ; 
 
			
		
	
		
		
			
				
					
						struct  ast_sockaddr  saddr ; 
 
			
		
	
		
		
			
				
					
						int  result  =  1 ; 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
						ast_sockaddr_parse ( & saddr ,  pj_sockaddr_print ( address ,  buf ,  sizeof ( buf ) ,  0 ) ,  0 ) ; 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
						ast_rwlock_rdlock ( & ice_blacklist_lock ) ; 
 
			
		
	
		
		
			
				
					
						if  ( ! ice_blacklist  | |  ( ast_apply_ha ( ice_blacklist ,  & saddr )  = =  AST_SENSE_ALLOW ) )  { 
 
			
		
	
		
		
			
				
					
							result  =  0 ; 
 
			
		
	
		
		
			
				
					
						} 
 
			
		
	
		
		
			
				
					
						ast_rwlock_unlock ( & ice_blacklist_lock ) ; 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
						return  result ; 
 
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					static  void  rtp_add_candidates_to_ice ( struct  ast_rtp_instance  * instance ,  struct  ast_rtp  * rtp ,  struct  ast_sockaddr  * addr ,  int  port ,  int  component , static  void  rtp_add_candidates_to_ice ( struct  ast_rtp_instance  * instance ,  struct  ast_rtp  * rtp ,  struct  ast_sockaddr  * addr ,  int  port ,  int  component ,  
			
		
	
		
		
			
				
					
									      int  transport ) 
				      int  transport ) 
 
			
		
	
		
		
			
				
					
					{ {  
			
		
	
		
		
			
				
					
						pj_sockaddr  address [ 16 ] ; 
	pj_sockaddr  address [ 16 ] ; 
 
			
		
	
		
		
			
				
					
						unsigned  int  count  =  PJ_ARRAY_SIZE ( address ) ,  pos  =  0 ; 
	unsigned  int  count  =  PJ_ARRAY_SIZE ( address ) ,  pos  =  0 ; 
 
			
		
	
		
		
			
				
					
						int  basepos  =  - 1 ; 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
						/* Add all the local interface IP addresses */ 
	/* Add all the local interface IP addresses */ 
 
			
		
	
		
		
			
				
					
						if  ( ast_sockaddr_is_ipv4 ( addr ) )  { 
	if  ( ast_sockaddr_is_ipv4 ( addr ) )  { 
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -2464,9 +2495,18 @@ static void rtp_add_candidates_to_ice(struct ast_rtp_instance *instance, struct
 
			
		
	
		
		
			
				
					
						host_candidate_overrides_apply ( count ,  address ) ; 
	host_candidate_overrides_apply ( count ,  address ) ; 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
						for  ( pos  =  0 ;  pos  <  count ;  pos + + )  { 
	for  ( pos  =  0 ;  pos  <  count ;  pos + + )  { 
 
			
		
	
		
		
			
				
					
							pj_sockaddr_set_port ( & address [ pos ] ,  port ) ; 
		if  ( ! rtp_address_is_ice_blacklisted ( & address [ pos ] ) )  { 
 
			
				
				
			
		
	
		
		
			
				
					
							ast_rtp_ice_add_cand ( rtp ,  component ,  transport ,  PJ_ICE_CAND_TYPE_HOST ,  65535 ,  & address [ pos ] ,  & address [ pos ] ,  NULL , 
			if  ( basepos  = =  - 1 )  { 
 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
									basepos  =  pos ; 
 
			
		
	
		
		
			
				
					
								} 
 
			
		
	
		
		
			
				
					
								pj_sockaddr_set_port ( & address [ pos ] ,  port ) ; 
 
			
		
	
		
		
			
				
					
								ast_rtp_ice_add_cand ( rtp ,  component ,  transport ,  PJ_ICE_CAND_TYPE_HOST ,  65535 ,  & address [ pos ] ,  & address [ pos ] ,  NULL , 
 
			
		
	
		
		
			
				
					
									     pj_sockaddr_get_len ( & address [ pos ] ) ) ; 
				     pj_sockaddr_get_len ( & address [ pos ] ) ) ; 
 
			
		
	
		
		
			
				
					
							} 
 
			
		
	
		
		
			
				
					
						} 
 
			
		
	
		
		
			
				
					
						if  ( basepos  = =  - 1 )  { 
 
			
		
	
		
		
			
				
					
							/* start with first address unless excluded above */ 
 
			
		
	
		
		
			
				
					
							basepos  =  0 ; 
 
			
		
	
		
		
			
				
					
						} 
	} 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
						/* If configured to use a STUN server to get our external mapped address do so */ 
	/* If configured to use a STUN server to get our external mapped address do so */ 
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -2475,15 +2515,27 @@ static void rtp_add_candidates_to_ice(struct ast_rtp_instance *instance, struct
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
							if  ( ! ast_stun_request ( component  = =  AST_RTP_ICE_COMPONENT_RTCP  ?  rtp - > rtcp - > s  :  rtp - > s ,  & stunaddr ,  NULL ,  & answer ) )  { 
		if  ( ! ast_stun_request ( component  = =  AST_RTP_ICE_COMPONENT_RTCP  ?  rtp - > rtcp - > s  :  rtp - > s ,  & stunaddr ,  NULL ,  & answer ) )  { 
 
			
		
	
		
		
			
				
					
								pj_sockaddr  base ; 
			pj_sockaddr  base ; 
 
			
		
	
		
		
			
				
					
								pj_sockaddr  ext ; 
 
			
		
	
		
		
			
				
					
								pj_str_t  mapped  =  pj_str ( ast_strdupa ( ast_inet_ntoa ( answer . sin_addr ) ) ) ; 
			pj_str_t  mapped  =  pj_str ( ast_strdupa ( ast_inet_ntoa ( answer . sin_addr ) ) ) ; 
 
			
		
	
		
		
			
				
					
								int  srflx  =  1 ; 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
								/* Use the first local host candidate as the base */ 
			/* Use the first local host candidate as the base */ 
 
			
		
	
		
		
			
				
					
								pj_sockaddr_cp ( & base ,  & address [ 0 ] ) ; 
			pj_sockaddr_cp ( & base ,  & address [ basepos ] ) ; 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
								pj_sockaddr_init ( pj_AF_INET ( ) ,  & ext ,  & mapped ,  ntohs ( answer . sin_port ) ) ; 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
								pj_sockaddr_init ( pj_AF_INET ( ) ,  & address [ 0 ] ,  & mapped ,  ntohs ( answer . sin_port ) ) ; 
			/* If the returned address is the same as one of our host candidates, don't send the srflx */ 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
								for  ( pos  =  0 ;  pos  <  count ;  pos + + )  { 
 
			
		
	
		
		
			
				
					
									if  ( ( pj_sockaddr_cmp ( & address [ pos ] ,  & ext )  = =  0 )  & &  ! rtp_address_is_ice_blacklisted ( & address [ pos ] ) )  { 
 
			
		
	
		
		
			
				
					
										srflx  =  0 ; 
 
			
		
	
		
		
			
				
					
										break ; 
 
			
		
	
		
		
			
				
					
									} 
 
			
		
	
		
		
			
				
					
								} 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
								ast_rtp_ice_add_cand ( rtp ,  component ,  transport ,  PJ_ICE_CAND_TYPE_SRFLX ,  65535 ,  & address [ 0 ] ,  & base , 
			if  ( srflx )  { 
 
			
				
				
			
		
	
		
		
			
				
					
										     & base ,  pj_sockaddr_get_len ( & address [ 0 ] ) ) ; 
				ast_rtp_ice_add_cand ( rtp ,  component ,  transport ,  PJ_ICE_CAND_TYPE_SRFLX ,  65535 ,  & ext ,  & base , 
 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
												 & base ,  pj_sockaddr_get_len ( & ext ) ) ; 
 
			
		
	
		
		
			
				
					
								} 
 
			
		
	
		
		
			
				
					
							} 
		} 
 
			
		
	
		
		
			
				
					
						} 
	} 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -5393,6 +5445,10 @@ static int rtp_reload(int reload)
 
			
		
	
		
		
			
				
					
						turnusername  =  pj_str ( NULL ) ; 
	turnusername  =  pj_str ( NULL ) ; 
 
			
		
	
		
		
			
				
					
						turnpassword  =  pj_str ( NULL ) ; 
	turnpassword  =  pj_str ( NULL ) ; 
 
			
		
	
		
		
			
				
					
						host_candidate_overrides_clear ( ) ; 
	host_candidate_overrides_clear ( ) ; 
 
			
		
	
		
		
			
				
					
						ast_rwlock_wrlock ( & ice_blacklist_lock ) ; 
 
			
		
	
		
		
			
				
					
						ast_free_ha ( ice_blacklist ) ; 
 
			
		
	
		
		
			
				
					
						ice_blacklist  =  NULL ; 
 
			
		
	
		
		
			
				
					
						ast_rwlock_unlock ( & ice_blacklist_lock ) ; 
 
			
		
	
		
		
			
				
					
					# endif # endif  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
						if  ( cfg )  { 
	if  ( cfg )  { 
 
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -5502,6 +5558,25 @@ static int rtp_reload(int reload)
 
			
		
	
		
		
			
				
					
								AST_RWLIST_INSERT_TAIL ( & host_candidates ,  candidate ,  next ) ; 
			AST_RWLIST_INSERT_TAIL ( & host_candidates ,  candidate ,  next ) ; 
 
			
		
	
		
		
			
				
					
							} 
		} 
 
			
		
	
		
		
			
				
					
							AST_RWLIST_UNLOCK ( & host_candidates ) ; 
		AST_RWLIST_UNLOCK ( & host_candidates ) ; 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
							/* Read ICE blacklist configuration lines */ 
 
			
		
	
		
		
			
				
					
							ast_rwlock_wrlock ( & ice_blacklist_lock ) ; 
 
			
		
	
		
		
			
				
					
							for  ( var  =  ast_variable_browse ( cfg ,  " general " ) ;  var ;  var  =  var - > next )  { 
 
			
		
	
		
		
			
				
					
								if  ( ! strcasecmp ( var - > name ,  " ice_blacklist " ) )  { 
 
			
		
	
		
		
			
				
					
									struct  ast_ha  * na ; 
 
			
		
	
		
		
			
				
					
									int  ha_error  =  0 ; 
 
			
		
	
		
		
			
				
					
									if  ( ! ( na  =  ast_append_ha ( " d " ,  var - > value ,  ice_blacklist ,  & ha_error ) ) )  { 
 
			
		
	
		
		
			
				
					
										ast_log ( LOG_WARNING ,  " Invalid ice_blacklist value: %s \n " ,  var - > value ) ; 
 
			
		
	
		
		
			
				
					
									}  else  { 
 
			
		
	
		
		
			
				
					
										ice_blacklist  =  na ; 
 
			
		
	
		
		
			
				
					
									} 
 
			
		
	
		
		
			
				
					
									if  ( ha_error )  { 
 
			
		
	
		
		
			
				
					
										ast_log ( LOG_ERROR ,  " Bad ice_blacklist configuration value line %d : %s \n " ,  var - > lineno ,  var - > value ) ; 
 
			
		
	
		
		
			
				
					
									} 
 
			
		
	
		
		
			
				
					
								} 
 
			
		
	
		
		
			
				
					
							} 
 
			
		
	
		
		
			
				
					
							ast_rwlock_unlock ( & ice_blacklist_lock ) ; 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					# endif # endif  
			
		
	
		
		
			
				
					
							ast_config_destroy ( cfg ) ; 
		ast_config_destroy ( cfg ) ; 
 
			
		
	
		
		
			
				
					
						} 
	}