rtp/rtcp: Configure dual-stack behavior via IPV6_V6ONLY

Dual-stack behavior (simultaneous listening for IPV4 and IPV6
connections on a single socket) is required by Asterisk's ICE
implementation.  On systems with the IPV6_V6ONLY sockopt, set
the option to 0 (dual-stack enabled) when binding to the IPV6
any address. This ensures correct behavior regardless of the
system's default dual-stack configuration.
releases/20
Justin T. Gibbs 1 month ago committed by Asterisk Development Team
parent 1217dac239
commit 2fdf1c5942

34
configure vendored

@ -31513,6 +31513,40 @@ esac
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if setsockopt() accepts the IPV6_V6ONLY socket option" >&5
printf %s "checking if setsockopt() accepts the IPV6_V6ONLY socket option... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <sys/socket.h>
#include <netinet/in.h>
int
main (void)
{
int opt = IPV6_V6ONLY;
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; }
printf "%s\n" "#define HAVE_SOCK_IPV6_V6ONLY 1" >>confdefs.h
else case e in #(
e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can increase the maximum select-able file descriptor" >&5
printf %s "checking if we can increase the maximum select-able file descriptor... " >&6; }
if test "$cross_compiling" = yes

@ -1250,6 +1250,19 @@ AC_RUN_IFELSE(
AC_MSG_RESULT(cross-compile)
)
AC_MSG_CHECKING([if setsockopt() accepts the IPV6_V6ONLY socket option])
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM([
#include <sys/socket.h>
#include <netinet/in.h>
], [
int opt = IPV6_V6ONLY;
])],
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_SOCK_IPV6_V6ONLY, 1, [Define to 1 if your socket() implementation has the IPV6_V6ONLY socket option.]),
AC_MSG_RESULT(no)
)
AC_MSG_CHECKING(if we can increase the maximum select-able file descriptor)
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([

@ -923,6 +923,9 @@
/* Define to 1 if your socket() implementation can accept SOCK_NONBLOCK. */
#undef HAVE_SOCK_NONBLOCK
/* Define to 1 if your socket() implementation has the IPV6_V6ONLY socket option. */
#undef HAVE_SOCK_IPV6_V6ONLY
/* Define to 1 if your system has soxmix application. */
#undef HAVE_SOXMIX

@ -3565,9 +3565,13 @@ static void calc_mean_and_standard_deviation(double new_sample, double *mean, do
*std_dev = sqrt((last_sum_of_squares + (delta1 * delta2)) / *count);
}
static int create_new_socket(const char *type, int af)
static int create_new_socket(const char *type, struct ast_sockaddr *bind_addr)
{
int sock = ast_socket_nonblock(af, SOCK_DGRAM, 0);
int af, sock;
af = ast_sockaddr_is_ipv4(bind_addr) ? AF_INET :
ast_sockaddr_is_ipv6(bind_addr) ? AF_INET6 : -1;
sock = ast_socket_nonblock(af, SOCK_DGRAM, 0);
if (sock < 0) {
ast_log(LOG_WARNING, "Unable to allocate %s socket: %s\n", type, strerror(errno));
@ -3580,6 +3584,15 @@ static int create_new_socket(const char *type, int af)
}
#endif
#ifdef HAVE_SOCK_IPV6_V6ONLY
if (AF_INET6 == af && ast_sockaddr_is_any(bind_addr)) {
/* ICE relies on dual-stack behavior. Ensure it is enabled. */
if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &(int){0}, sizeof(int)) != 0) {
ast_log(LOG_WARNING, "setsockopt IPV6_V6ONLY=0 failed: %s\n", strerror(errno));
}
}
#endif
return sock;
}
@ -4041,10 +4054,7 @@ static int rtp_allocate_transport(struct ast_rtp_instance *instance, struct ast_
rtp->strict_rtp_state = (strictrtp ? STRICT_RTP_CLOSED : STRICT_RTP_OPEN);
/* Create a new socket for us to listen on and use */
if ((rtp->s =
create_new_socket("RTP",
ast_sockaddr_is_ipv4(&rtp->bind_address) ? AF_INET :
ast_sockaddr_is_ipv6(&rtp->bind_address) ? AF_INET6 : -1)) < 0) {
if ((rtp->s = create_new_socket("RTP", &rtp->bind_address)) < 0) {
ast_log(LOG_WARNING, "Failed to create a new socket for RTP instance '%p'\n", instance);
return -1;
}
@ -8938,12 +8948,7 @@ static void ast_rtp_prop_set(struct ast_rtp_instance *instance, enum ast_rtp_pro
* switching from MUX. Either way, we won't have
* a socket set up, and we need to set it up
*/
if ((rtp->rtcp->s =
create_new_socket("RTCP",
ast_sockaddr_is_ipv4(&rtp->rtcp->us) ?
AF_INET :
ast_sockaddr_is_ipv6(&rtp->rtcp->us) ?
AF_INET6 : -1)) < 0) {
if ((rtp->rtcp->s = create_new_socket("RTCP", &rtp->rtcp->us)) < 0) {
ast_debug_rtcp(1, "(%p) RTCP failed to create a new socket\n", instance);
ast_free(rtp->rtcp->local_addr_str);
ast_free(rtp->rtcp);

Loading…
Cancel
Save