@ -1584,12 +1584,14 @@ static const char *kernelize_target(kernelize_state *s, struct packet_stream *st
// fill input
__auto_type reti = & s - > reti . target ;
if ( PS_ISSET2 ( stream , STRICT_SOURCE , MEDIA_HANDOVER ) ) {
reti - > stun = MEDIA_ISSET ( media , ICE ) & & media - > ice_agent ? 1 : 0 ;
if ( PS_ISSET2 ( stream , STRICT_SOURCE , MEDIA_HANDOVER ) | | reti - > stun ) {
__re_address_translate_ep ( & reti - > expected_src , MEDIA_ISSET ( media , ASYMMETRIC ) ? & stream - > learned_endpoint : & stream - > endpoint ) ;
if ( PS_ISSET ( stream , STRICT_SOURCE ) )
reti - > src_mismatch = MSM_DROP ;
else if ( PS_ISSET ( stream , MEDIA_HANDOVER ) )
if ( PS_ISSET ( stream , MEDIA_HANDOVER ) | | reti - > stun )
reti - > src_mismatch = MSM_PROPAGATE ;
else if ( PS_ISSET ( stream , STRICT_SOURCE ) )
reti - > src_mismatch = MSM_DROP ;
}
__re_address_translate_ep ( & reti - > local , & sfd - > socket . local ) ;
@ -1597,7 +1599,6 @@ static const char *kernelize_target(kernelize_state *s, struct packet_stream *st
reti - > stats = stream - > stats_in ;
reti - > rtcp = PS_ISSET ( stream , RTCP ) ;
reti - > dtls = MEDIA_ISSET ( media , DTLS ) ;
reti - > stun = media - > ice_agent ? 1 : 0 ;
reti - > non_forwarding = s - > non_forwarding ? 1 : 0 ;
reti - > blackhole = s - > blackhole ? 1 : 0 ;
reti - > rtp_stats = ( rtpe_config . measure_rtp
@ -3146,6 +3147,8 @@ static bool media_packet_address_check(struct packet_handler_ctx *phc)
return false ;
}
bool has_ice = MEDIA_ISSET ( phc - > mp . media , ICE ) & & phc - > mp . media - > ice_agent ;
// GH #697 - apparent Asterisk bug where it sends stray RTCP to the RTP port.
// work around this by detecting this situation and ignoring the packet for
// confirmation purposes when needed. This is regardless of whether rtcp-mux
@ -3164,7 +3167,7 @@ static bool media_packet_address_check(struct packet_handler_ctx *phc)
if ( MEDIA_ISSET ( phc - > mp . media , ASYMMETRIC ) )
update_endpoint = & phc - > mp . stream - > learned_endpoint ;
if ( phc - > mp . stream - > el_flags = = EL_OFF )
if ( phc - > mp . stream - > el_flags = = EL_OFF | | has_ice )
phc - > mp . sfd - > confirmed = true ;
/* confirm sinks for unidirectional streams in order to kernelize */
@ -3176,13 +3179,28 @@ static bool media_packet_address_check(struct packet_handler_ctx *phc)
}
}
/* wait at least 3 seconds after last signal before committing to a particular
* endpoint address */
bool wait_time = false ;
if ( ! phc - > mp . call - > last_signal_us | | rtpe_now < = phc - > mp . call - > last_signal_us + 3000000LL )
wait_time = true ;
/* if we have already updated the endpoint in the past ... */
if ( phc - > mp . sfd - > confirmed ) {
/* see if we need to compare the source address with the known endpoint */
if ( PS_ISSET2 ( phc - > mp . stream , STRICT_SOURCE , MEDIA_HANDOVER ) ) {
bool matched = memcmp ( & phc - > mp . fsin , update_endpoint , sizeof ( phc - > mp . fsin ) ) = = 0 ;
if ( PS_ISSET2 ( phc - > mp . stream , STRICT_SOURCE , MEDIA_HANDOVER ) | | has_ice ) {
bool matched = memcmp ( & phc - > mp . fsin , update_endpoint , sizeof ( phc - > mp . fsin ) ) = = 0
& & phc - > mp . sfd = = phc - > mp . stream - > selected_sfd ;
if ( ! matched & & has_ice ) {
// rate-limit for ICE to avoid rapid flip-flop
if ( wait_time )
matched = true ;
else
phc - > mp . call - > last_signal_us = rtpe_now ;
}
if ( ! matched & & PS_ISSET ( phc - > mp . stream , MEDIA_HANDOVER ) ) {
if ( ! matched & & ( PS_ISSET ( phc - > mp . stream , MEDIA_HANDOVER ) | | has_ice ) ) {
/* out_lock remains locked */
ilog ( LOG_INFO | LOG_FLAG_LIMIT , " Peer address changed to %s%s%s " ,
FMT_M ( endpoint_print_buf ( & phc - > mp . fsin ) ) ) ;
@ -3196,17 +3214,21 @@ static bool media_packet_address_check(struct packet_handler_ctx *phc)
// try some other options before dropping
if ( ! matched & & ! MEDIA_ISSET ( phc - > mp . media , ASYMMETRIC ) )
matched = memcmp ( & phc - > mp . fsin , & phc - > orig_stream - > endpoint ,
sizeof ( phc - > mp . fsin ) ) = = 0 ;
sizeof ( phc - > mp . fsin ) ) = = 0
& & phc - > mp . sfd = = phc - > mp . stream - > selected_sfd ;
if ( ! matched )
matched = memcmp ( & phc - > mp . fsin , & phc - > orig_stream - > learned_endpoint ,
sizeof ( phc - > mp . fsin ) ) = = 0 ;
sizeof ( phc - > mp . fsin ) ) = = 0
& & phc - > mp . sfd = = phc - > mp . stream - > selected_sfd ;
if ( ! matched & & PS_ISSET ( phc - > mp . stream , STRICT_SOURCE ) ) {
ilog ( LOG_INFO | LOG_FLAG_LIMIT , " Drop due to strict-source attribute; "
" got %s%s%s , "
" expected %s%s%s " ,
" got %s%s%s -> %s , "
" expected %s%s%s -> %s " ,
FMT_M ( endpoint_print_buf ( & phc - > mp . fsin ) ) ,
FMT_M ( endpoint_print_buf ( update_endpoint ) ) ) ;
endpoint_print_buf ( & phc - > mp . sfd - > socket . local ) ,
FMT_M ( endpoint_print_buf ( update_endpoint ) ) ,
endpoint_print_buf ( & phc - > mp . stream - > selected_sfd - > socket . local ) ) ;
atomic64_inc_na ( & phc - > mp . stream - > stats_in - > errors ) ;
atomic64_inc_na ( & phc - > mp . sfd - > local_intf - > stats - > in . errors ) ;
ret = true ;
@ -3216,15 +3238,9 @@ static bool media_packet_address_check(struct packet_handler_ctx *phc)
return ret ;
}
/* wait at least 3 seconds after last signal before committing to a particular
* endpoint address */
bool wait_time = false ;
if ( ! phc - > mp . call - > last_signal_us | | rtpe_now < = phc - > mp . call - > last_signal_us + 3000000LL )
wait_time = true ;
const struct endpoint * use_endpoint_confirm = & phc - > mp . fsin ;
if ( phc - > mp . stream - > el_flags = = EL_IMMEDIATE )
if ( phc - > mp . stream - > el_flags = = EL_IMMEDIATE | | has_ice )
goto confirm_now ;
if ( phc - > mp . stream - > el_flags = = EL_HEURISTIC