Skip to content

Commit 3da3ffa

Browse files
authored
Don't create IPv6 sockets if IPv6 is completely disabled (see #3159) (#3179)
1 parent cce3f23 commit 3da3ffa

File tree

3 files changed

+119
-35
lines changed

3 files changed

+119
-35
lines changed

src/plugins/janus_audiobridge.c

+14-6
Original file line numberDiff line numberDiff line change
@@ -8607,13 +8607,13 @@ static int janus_audiobridge_plainrtp_allocate_port(janus_audiobridge_plainrtp_m
86078607
break;
86088608
}
86098609
if(rtp_fd == -1)
8610-
rtp_fd = socket(AF_INET6, SOCK_DGRAM, 0);
8610+
rtp_fd = socket(!ipv6_disabled ? AF_INET6 : AF_INET, SOCK_DGRAM, 0);
86118611
if(rtp_fd == -1) {
86128612
JANUS_LOG(LOG_ERR, "Error creating socket... %d (%s)\n", errno, g_strerror(errno));
86138613
break;
86148614
}
86158615
int v6only = 0;
8616-
if(setsockopt(rtp_fd, IPPROTO_IPV6, IPV6_V6ONLY, &v6only, sizeof(v6only)) != 0) {
8616+
if(!ipv6_disabled && setsockopt(rtp_fd, IPPROTO_IPV6, IPV6_V6ONLY, &v6only, sizeof(v6only)) != 0) {
86178617
JANUS_LOG(LOG_ERR, "setsockopt on socket failed... %d (%s)\n", errno, g_strerror(errno));
86188618
break;
86198619
}
@@ -8625,10 +8625,18 @@ static int janus_audiobridge_plainrtp_allocate_port(janus_audiobridge_plainrtp_m
86258625
rtp_port_next = rtp_range_min;
86268626
rtp_port_wrap = TRUE;
86278627
}
8628-
struct sockaddr_in6 rtp_address = { 0 };
8629-
rtp_address.sin6_family = AF_INET6;
8630-
rtp_address.sin6_port = htons(rtp_port);
8631-
rtp_address.sin6_addr = in6addr_any;
8628+
struct sockaddr_storage rtp_address = { 0 };
8629+
if(!ipv6_disabled) {
8630+
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)&rtp_address;
8631+
addr->sin6_family = AF_INET6;
8632+
addr->sin6_port = htons(rtp_port);
8633+
addr->sin6_addr = in6addr_any;
8634+
} else {
8635+
struct sockaddr_in *addr = (struct sockaddr_in *)&rtp_address;
8636+
addr->sin_family = AF_INET;
8637+
addr->sin_port = htons(rtp_port);
8638+
addr->sin_addr.s_addr = INADDR_ANY;
8639+
}
86328640
if(bind(rtp_fd, (struct sockaddr *)(&rtp_address), sizeof(rtp_address)) < 0) {
86338641
/* rtp_fd still unbound, reuse it in the next iteration */
86348642
} else {

src/plugins/janus_nosip.c

+32-8
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ static struct janus_json_parameter recording_parameters[] = {
260260
/* Useful stuff */
261261
static volatile gint initialized = 0, stopping = 0;
262262
static gboolean notify_events = TRUE;
263+
static gboolean ipv6_disabled = FALSE;
263264
static janus_callbacks *gateway = NULL;
264265

265266
static char *local_ip = NULL, *sdp_ip = NULL;
@@ -793,6 +794,21 @@ int janus_nosip_init(janus_callbacks *callback, const char *config_path) {
793794
/* This is the callback we'll need to invoke to contact the Janus core */
794795
gateway = callback;
795796

797+
/* Finally, let's check if IPv6 is disabled, as we may need to know for RTP/RTCP sockets */
798+
int fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
799+
if(fd <= 0) {
800+
ipv6_disabled = TRUE;
801+
} else {
802+
int v6only = 0;
803+
if(setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &v6only, sizeof(v6only)) != 0)
804+
ipv6_disabled = TRUE;
805+
}
806+
if(fd > 0)
807+
close(fd);
808+
if(ipv6_disabled) {
809+
JANUS_LOG(LOG_WARN, "IPv6 disabled, will only use IPv4 for RTP/RTCP sockets (NoSIP)\n");
810+
}
811+
796812
g_atomic_int_set(&initialized, 1);
797813

798814
GError *error = NULL;
@@ -1982,10 +1998,18 @@ char *janus_nosip_sdp_manipulate(janus_nosip_session *session, janus_sdp *sdp, g
19821998
}
19831999

19842000
static int janus_nosip_bind_socket(int fd, int port) {
1985-
struct sockaddr_in6 rtp_address = { 0 };
1986-
rtp_address.sin6_family = AF_INET6;
1987-
rtp_address.sin6_port = htons(port);
1988-
rtp_address.sin6_addr = in6addr_any;
2001+
struct sockaddr_storage rtp_address = { 0 };
2002+
if(!ipv6_disabled) {
2003+
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)&rtp_address;
2004+
addr->sin6_family = AF_INET6;
2005+
addr->sin6_port = htons(port);
2006+
addr->sin6_addr = in6addr_any;
2007+
} else {
2008+
struct sockaddr_in *addr = (struct sockaddr_in *)&rtp_address;
2009+
addr->sin_family = AF_INET;
2010+
addr->sin_port = htons(port);
2011+
addr->sin_addr.s_addr = INADDR_ANY;
2012+
}
19892013
if(bind(fd, (struct sockaddr *)(&rtp_address), sizeof(rtp_address)) < 0) {
19902014
JANUS_LOG(LOG_ERR, "Bind failed (port %d)\n", port);
19912015
return -1;
@@ -2007,9 +2031,9 @@ static int janus_nosip_allocate_port_pair(gboolean video, int fds[2], int ports[
20072031
break;
20082032
}
20092033
if(rtp_fd == -1) {
2010-
rtp_fd = socket(AF_INET6, SOCK_DGRAM, 0);
2034+
rtp_fd = socket(!ipv6_disabled ? AF_INET6 : AF_INET, SOCK_DGRAM, 0);
20112035
int v6only = 0;
2012-
if(rtp_fd != -1 && setsockopt(rtp_fd, IPPROTO_IPV6, IPV6_V6ONLY, &v6only, sizeof(v6only)) != 0) {
2036+
if(!ipv6_disabled && rtp_fd != -1 && setsockopt(rtp_fd, IPPROTO_IPV6, IPV6_V6ONLY, &v6only, sizeof(v6only)) != 0) {
20132037
JANUS_LOG(LOG_WARN, "Error setting v6only to false on RTP socket (error=%s)\n",
20142038
g_strerror(errno));
20152039
}
@@ -2032,8 +2056,8 @@ static int janus_nosip_allocate_port_pair(gboolean video, int fds[2], int ports[
20322056
}
20332057
if(rtcp_fd == -1) {
20342058
int v6only = 0;
2035-
rtcp_fd = socket(AF_INET6, SOCK_DGRAM, 0);
2036-
if(rtcp_fd != -1 && setsockopt(rtcp_fd, IPPROTO_IPV6, IPV6_V6ONLY, &v6only, sizeof(v6only)) != 0) {
2059+
rtcp_fd = socket(!ipv6_disabled ? AF_INET6 : AF_INET, SOCK_DGRAM, 0);
2060+
if(!ipv6_disabled && rtcp_fd != -1 && setsockopt(rtcp_fd, IPPROTO_IPV6, IPV6_V6ONLY, &v6only, sizeof(v6only)) != 0) {
20372061
JANUS_LOG(LOG_WARN, "Error setting v6only to false on RTP socket (error=%s)\n",
20382062
g_strerror(errno));
20392063
}

src/plugins/janus_sip.c

+73-21
Original file line numberDiff line numberDiff line change
@@ -850,6 +850,7 @@ static struct janus_json_parameter sipmessage_parameters[] = {
850850
/* Useful stuff */
851851
static volatile gint initialized = 0, stopping = 0;
852852
static gboolean notify_events = TRUE;
853+
static gboolean ipv6_disabled = FALSE;
853854
static janus_callbacks *gateway = NULL;
854855

855856
static char *local_ip = NULL, *sdp_ip = NULL, *local_media_ip = NULL;
@@ -2019,6 +2020,21 @@ int janus_sip_init(janus_callbacks *callback, const char *config_path) {
20192020
/* This is the callback we'll need to invoke to contact the Janus core */
20202021
gateway = callback;
20212022

2023+
/* Finally, let's check if IPv6 is disabled, as we may need to know for RTP/RTCP sockets */
2024+
int fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
2025+
if(fd <= 0) {
2026+
ipv6_disabled = TRUE;
2027+
} else {
2028+
int v6only = 0;
2029+
if(setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &v6only, sizeof(v6only)) != 0)
2030+
ipv6_disabled = TRUE;
2031+
}
2032+
if(fd > 0)
2033+
close(fd);
2034+
if(ipv6_disabled) {
2035+
JANUS_LOG(LOG_WARN, "IPv6 disabled, will only use IPv4 for RTP/RTCP sockets (SIP)\n");
2036+
}
2037+
20222038
g_atomic_int_set(&initialized, 1);
20232039

20242040
/* Launch the thread that will handle incoming messages */
@@ -6608,14 +6624,15 @@ static int janus_sip_allocate_local_ports(janus_sip_session *session, gboolean u
66086624
int attempts = 100; /* FIXME Don't retry forever */
66096625
if(session->media.has_audio) {
66106626
JANUS_LOG(LOG_VERB, "Allocating audio ports:\n");
6611-
struct sockaddr_in6 audio_rtp_address, audio_rtcp_address;
6627+
struct sockaddr_storage audio_rtp_address, audio_rtcp_address;
66126628
while(session->media.local_audio_rtp_port == 0 || session->media.local_audio_rtcp_port == 0) {
66136629
if(attempts == 0) /* Too many failures */
66146630
return -1;
66156631
if(session->media.audio_rtp_fd == -1) {
6616-
session->media.audio_rtp_fd = socket(AF_INET6, SOCK_DGRAM, 0);
6632+
session->media.audio_rtp_fd = socket(!ipv6_disabled ? AF_INET6 : AF_INET, SOCK_DGRAM, 0);
66176633
int v6only = 0;
6618-
if(session->media.audio_rtp_fd != -1 && setsockopt(session->media.audio_rtp_fd, IPPROTO_IPV6, IPV6_V6ONLY, &v6only, sizeof(v6only)) != 0) {
6634+
if(!ipv6_disabled && session->media.audio_rtp_fd != -1 &&
6635+
setsockopt(session->media.audio_rtp_fd, IPPROTO_IPV6, IPV6_V6ONLY, &v6only, sizeof(v6only)) != 0) {
66196636
JANUS_LOG(LOG_WARN, "Error setting v6only to false on audio RTP socket (error=%s)\n",
66206637
g_strerror(errno));
66216638
}
@@ -6630,9 +6647,10 @@ static int janus_sip_allocate_local_ports(janus_sip_session *session, gboolean u
66306647
}
66316648
}
66326649
if(session->media.audio_rtcp_fd == -1) {
6633-
session->media.audio_rtcp_fd = socket(AF_INET6, SOCK_DGRAM, 0);
6650+
session->media.audio_rtcp_fd = socket(!ipv6_disabled ? AF_INET6 : AF_INET, SOCK_DGRAM, 0);
66346651
int v6only = 0;
6635-
if(session->media.audio_rtcp_fd != -1 && setsockopt(session->media.audio_rtcp_fd, IPPROTO_IPV6, IPV6_V6ONLY, &v6only, sizeof(v6only)) != 0) {
6652+
if(!ipv6_disabled && session->media.audio_rtcp_fd != -1 &&
6653+
setsockopt(session->media.audio_rtcp_fd, IPPROTO_IPV6, IPV6_V6ONLY, &v6only, sizeof(v6only)) != 0) {
66366654
JANUS_LOG(LOG_WARN, "Error setting v6only to false on audio RTCP socket (error=%s)\n",
66376655
g_strerror(errno));
66386656
}
@@ -6644,9 +6662,17 @@ static int janus_sip_allocate_local_ports(janus_sip_session *session, gboolean u
66446662
int rtp_port = g_random_int_range(rtp_range_min, rtp_range_max);
66456663
if(rtp_port % 2)
66466664
rtp_port++; /* Pick an even port for RTP */
6647-
audio_rtp_address.sin6_family = AF_INET6;
6648-
audio_rtp_address.sin6_port = htons(rtp_port);
6649-
audio_rtp_address.sin6_addr = in6addr_any;
6665+
if(!ipv6_disabled) {
6666+
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)&audio_rtp_address;
6667+
addr->sin6_family = AF_INET6;
6668+
addr->sin6_port = htons(rtp_port);
6669+
addr->sin6_addr = in6addr_any;
6670+
} else {
6671+
struct sockaddr_in *addr = (struct sockaddr_in *)&audio_rtp_address;
6672+
addr->sin_family = AF_INET;
6673+
addr->sin_port = htons(rtp_port);
6674+
addr->sin_addr.s_addr = INADDR_ANY;
6675+
}
66506676
if(bind(session->media.audio_rtp_fd, (struct sockaddr *)(&audio_rtp_address), sizeof(audio_rtp_address)) < 0) {
66516677
JANUS_LOG(LOG_ERR, "Bind failed for audio RTP (port %d), trying a different one...\n", rtp_port);
66526678
close(session->media.audio_rtp_fd);
@@ -6656,9 +6682,17 @@ static int janus_sip_allocate_local_ports(janus_sip_session *session, gboolean u
66566682
}
66576683
JANUS_LOG(LOG_VERB, "Audio RTP listener bound to %s:%d(%d)\n", (local_media_ip ? local_media_ip : local_ip), rtp_port, session->media.audio_rtp_fd);
66586684
int rtcp_port = rtp_port+1;
6659-
audio_rtcp_address.sin6_family = AF_INET6;
6660-
audio_rtcp_address.sin6_port = htons(rtcp_port);
6661-
audio_rtcp_address.sin6_addr = in6addr_any;
6685+
if(!ipv6_disabled) {
6686+
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)&audio_rtcp_address;
6687+
addr->sin6_family = AF_INET6;
6688+
addr->sin6_port = htons(rtcp_port);
6689+
addr->sin6_addr = in6addr_any;
6690+
} else {
6691+
struct sockaddr_in *addr = (struct sockaddr_in *)&audio_rtcp_address;
6692+
addr->sin_family = AF_INET;
6693+
addr->sin_port = htons(rtcp_port);
6694+
addr->sin_addr.s_addr = INADDR_ANY;
6695+
}
66626696
if(bind(session->media.audio_rtcp_fd, (struct sockaddr *)(&audio_rtcp_address), sizeof(audio_rtcp_address)) < 0) {
66636697
JANUS_LOG(LOG_ERR, "Bind failed for audio RTCP (port %d), trying a different one...\n", rtcp_port);
66646698
/* RTP socket is not valid anymore, reset it */
@@ -6681,9 +6715,10 @@ static int janus_sip_allocate_local_ports(janus_sip_session *session, gboolean u
66816715
if(attempts == 0) /* Too many failures */
66826716
return -1;
66836717
if(session->media.video_rtp_fd == -1) {
6684-
session->media.video_rtp_fd = socket(AF_INET, SOCK_DGRAM, 0);
6718+
session->media.video_rtp_fd = socket(!ipv6_disabled ? AF_INET6 : AF_INET, SOCK_DGRAM, 0);
66856719
int v6only = 0;
6686-
if(session->media.video_rtp_fd != -1 && setsockopt(session->media.video_rtp_fd, IPPROTO_IPV6, IPV6_V6ONLY, &v6only, sizeof(v6only)) != 0) {
6720+
if(!ipv6_disabled && session->media.video_rtp_fd != -1 &&
6721+
setsockopt(session->media.video_rtp_fd, IPPROTO_IPV6, IPV6_V6ONLY, &v6only, sizeof(v6only)) != 0) {
66876722
JANUS_LOG(LOG_WARN, "Error setting v6only to false on video RTP socket (error=%s)\n",
66886723
g_strerror(errno));
66896724
}
@@ -6698,9 +6733,10 @@ static int janus_sip_allocate_local_ports(janus_sip_session *session, gboolean u
66986733
}
66996734
}
67006735
if(session->media.video_rtcp_fd == -1) {
6701-
session->media.video_rtcp_fd = socket(AF_INET, SOCK_DGRAM, 0);
6736+
session->media.video_rtcp_fd = socket(!ipv6_disabled ? AF_INET6 : AF_INET, SOCK_DGRAM, 0);
67026737
int v6only = 0;
6703-
if(session->media.video_rtcp_fd != -1 && setsockopt(session->media.video_rtcp_fd, IPPROTO_IPV6, IPV6_V6ONLY, &v6only, sizeof(v6only)) != 0) {
6738+
if(!ipv6_disabled && session->media.video_rtcp_fd != -1 &&
6739+
setsockopt(session->media.video_rtcp_fd, IPPROTO_IPV6, IPV6_V6ONLY, &v6only, sizeof(v6only)) != 0) {
67046740
JANUS_LOG(LOG_WARN, "Error setting v6only to false on video RTCP socket (error=%s)\n",
67056741
g_strerror(errno));
67066742
}
@@ -6712,9 +6748,17 @@ static int janus_sip_allocate_local_ports(janus_sip_session *session, gboolean u
67126748
int rtp_port = g_random_int_range(rtp_range_min, rtp_range_max);
67136749
if(rtp_port % 2)
67146750
rtp_port++; /* Pick an even port for RTP */
6715-
video_rtp_address.sin6_family = AF_INET6;
6716-
video_rtp_address.sin6_port = htons(rtp_port);
6717-
video_rtp_address.sin6_addr = in6addr_any;
6751+
if(!ipv6_disabled) {
6752+
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)&video_rtp_address;
6753+
addr->sin6_family = AF_INET6;
6754+
addr->sin6_port = htons(rtp_port);
6755+
addr->sin6_addr = in6addr_any;
6756+
} else {
6757+
struct sockaddr_in *addr = (struct sockaddr_in *)&video_rtp_address;
6758+
addr->sin_family = AF_INET;
6759+
addr->sin_port = htons(rtp_port);
6760+
addr->sin_addr.s_addr = INADDR_ANY;
6761+
}
67186762
if(bind(session->media.video_rtp_fd, (struct sockaddr *)(&video_rtp_address), sizeof(video_rtp_address)) < 0) {
67196763
JANUS_LOG(LOG_ERR, "Bind failed for video RTP (port %d), trying a different one...\n", rtp_port);
67206764
close(session->media.video_rtp_fd);
@@ -6724,9 +6768,17 @@ static int janus_sip_allocate_local_ports(janus_sip_session *session, gboolean u
67246768
}
67256769
JANUS_LOG(LOG_VERB, "Video RTP listener bound to %s:%d(%d)\n", (local_media_ip ? local_media_ip : local_ip), rtp_port, session->media.video_rtp_fd);
67266770
int rtcp_port = rtp_port+1;
6727-
video_rtcp_address.sin6_family = AF_INET;
6728-
video_rtcp_address.sin6_port = htons(rtcp_port);
6729-
video_rtcp_address.sin6_addr = in6addr_any;
6771+
if(!ipv6_disabled) {
6772+
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)&video_rtcp_address;
6773+
addr->sin6_family = AF_INET6;
6774+
addr->sin6_port = htons(rtcp_port);
6775+
addr->sin6_addr = in6addr_any;
6776+
} else {
6777+
struct sockaddr_in *addr = (struct sockaddr_in *)&video_rtcp_address;
6778+
addr->sin_family = AF_INET;
6779+
addr->sin_port = htons(rtcp_port);
6780+
addr->sin_addr.s_addr = INADDR_ANY;
6781+
}
67306782
if(bind(session->media.video_rtcp_fd, (struct sockaddr *)(&video_rtcp_address), sizeof(video_rtcp_address)) < 0) {
67316783
JANUS_LOG(LOG_ERR, "Bind failed for video RTCP (port %d), trying a different one...\n", rtcp_port);
67326784
/* RTP socket is not valid anymore, reset it */

0 commit comments

Comments
 (0)