mirror of
https://github.com/asterisk/asterisk.git
synced 2026-06-22 08:25:12 -07:00
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.
This commit is contained in:
committed by
github-actions[bot]
parent
08d4960df7
commit
ce0eca443f
@@ -31433,6 +31433,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
|
||||
|
||||
@@ -1248,6 +1248,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([
|
||||
|
||||
@@ -914,6 +914,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
|
||||
|
||||
|
||||
+17
-12
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user