When binding on the IPv6 any address bind for IPv4 too

On some Linux systems this is the default. On most other operating
systems accepting IPv4 connections on a IPv6 socket only happens when
explicitly requested. Even on Linux it depends on the sysctl config.

This change makes it independent from the system's defaults whether IPv4
connections will be accepted too through the same socket.
This commit is contained in:
Giel van Schijndel
2017-05-22 16:58:00 +02:00
committed by John Hood
parent 9f54cc76d2
commit cb91788d05
+9
View File
@@ -41,6 +41,7 @@
#include <netinet/in.h> #include <netinet/in.h>
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
#include <string.h>
#include <unistd.h> #include <unistd.h>
#include "dos_assert.h" #include "dos_assert.h"
@@ -326,6 +327,14 @@ bool Connection::try_bind( const char *addr, int port_low, int port_high )
throw NetworkException( "Unknown address family", 0 ); throw NetworkException( "Unknown address family", 0 );
} }
if ( local_addr.sa.sa_family == AF_INET6
&& memcmp(&local_addr.sin6.sin6_addr, &in6addr_any, sizeof(in6addr_any)) == 0 ) {
const int off = 0;
if ( setsockopt( sock(), IPPROTO_IPV6, IPV6_V6ONLY, &off, sizeof(off) ) ) {
perror( "setsockopt( IPV6_V6ONLY, off )" );
}
}
if ( bind( sock(), &local_addr.sa, local_addr_len ) == 0 ) { if ( bind( sock(), &local_addr.sa, local_addr_len ) == 0 ) {
set_MTU( local_addr.sa.sa_family ); set_MTU( local_addr.sa.sa_family );
return true; return true;