summaryrefslogtreecommitdiffstats
path: root/src/openvpn/socket.c
diff options
context:
space:
mode:
authorArne Schwabe <arne@rfc2549.org>2013-11-25 13:31:18 +0100
committerGert Doering <gert@greenie.muc.de>2013-11-29 21:21:29 +0100
commit8832c6c4cf7d1425684dd8e56984e407fe3e2aac (patch)
tree8c2697f2be9ddb03cfbc3701995cb5cd82bc1fee /src/openvpn/socket.c
parent68793f40e1d04409264d21dd24453d959828a306 (diff)
downloadopenvpn-8832c6c4cf7d1425684dd8e56984e407fe3e2aac.tar.gz
openvpn-8832c6c4cf7d1425684dd8e56984e407fe3e2aac.tar.xz
openvpn-8832c6c4cf7d1425684dd8e56984e407fe3e2aac.zip
Implement listing on IPv4/IPv6 dual socket on all platform
With this patch OpenVPN will listen on Ipv4 as well as IPv6 when an IPv6 socket is used. Using bind ipv6only will disable this behavior Acked-by: Gert Doering <gert@greenie.muc.de> Message-Id: <1385382680-5912-7-git-send-email-arne@rfc2549.org> URL: http://article.gmane.org/gmane.network.openvpn.devel/8052 Signed-off-by: Gert Doering <gert@greenie.muc.de>
Diffstat (limited to 'src/openvpn/socket.c')
-rw-r--r--src/openvpn/socket.c31
1 files changed, 23 insertions, 8 deletions
diff --git a/src/openvpn/socket.c b/src/openvpn/socket.c
index 5ba1ee3..141af72 100644
--- a/src/openvpn/socket.c
+++ b/src/openvpn/socket.c
@@ -662,11 +662,10 @@ create_socket (struct link_socket *sock)
{
/* create socket, use information carried over from getaddrinfo */
const int ai_proto = sock->info.lsa->actual.ai_protocol;
- const int ai_family = sock->info.lsa->actual.ai_family;
+ int ai_family = sock->info.lsa->actual.ai_family;
ASSERT (sock->info.af == AF_UNSPEC || sock->info.af == ai_family);
-
if (ai_proto == IPPROTO_UDP)
{
sock->sd = create_socket_udp (ai_family, sock->sockflags);
@@ -880,7 +879,8 @@ void
socket_bind (socket_descriptor_t sd,
struct addrinfo *local,
int ai_family,
- const char *prefix)
+ const char *prefix,
+ bool ipv6only)
{
struct gc_arena gc = gc_new ();
@@ -891,9 +891,11 @@ socket_bind (socket_descriptor_t sd,
* What is the correct way to deal with it?
*/
- ASSERT(local);
struct addrinfo* cur;
+ ASSERT(local);
+
+
/* find the first addrinfo with correct ai_family */
for (cur = local; cur; cur=cur->ai_next)
{
@@ -904,6 +906,15 @@ socket_bind (socket_descriptor_t sd,
msg (M_FATAL, "%s: Socket bind failed: Addr to bind has no %s record",
prefix, addr_family_name(ai_family));
+ if (ai_family == AF_INET6)
+ {
+ int v6only = ipv6only ? 0: 1; /* setsockopt must have an "int" */
+
+ if (setsockopt(sd, IPPROTO_IPV6, IPV6_V6ONLY, &v6only, sizeof(v6only)))
+ {
+ msg (M_NONFATAL|M_ERRNO, "Setting IPV6_V6ONLY=%d failed", v6only);
+ }
+ }
if (bind (sd, cur->ai_addr, cur->ai_addrlen))
{
const int errnum = openvpn_errno ();
@@ -1153,11 +1164,12 @@ static void bind_local (struct link_socket *sock)
#ifdef ENABLE_SOCKS
if (sock->socks_proxy && sock->info.proto == PROTO_UDP)
socket_bind (sock->ctrl_sd, sock->info.lsa->bind_local,
- sock->info.lsa->actual.ai_family, "SOCKS");
+ sock->info.lsa->actual.ai_family, "SOCKS", false);
else
#endif
socket_bind (sock->sd, sock->info.lsa->bind_local,
- sock->info.lsa->actual.ai_family, "TCP/UDP");
+ sock->info.lsa->actual.ai_family,
+ "TCP/UDP", sock->info.bind_ipv6_only);
}
}
@@ -1294,11 +1306,12 @@ create_new_socket (struct link_socket* sock)
resolve_bind_local (sock, sock->info.af);
}
resolve_remote (sock, 1, NULL, NULL);
+
/*
* In P2P or server mode we must create the socket even when resolving
* the remote site fails/is not specified. */
- if (sock->info.af && sock->info.lsa->actual.ai_family==0 && sock->bind_local)
+ if (sock->info.lsa->actual.ai_family==0 && sock->bind_local)
{
/* Copy sock parameters from bind addr */
set_actual_address (&sock->info.lsa->actual, sock->info.lsa->bind_local);
@@ -1309,7 +1322,7 @@ create_new_socket (struct link_socket* sock)
/*
* Create the socket early if socket should be bound
*/
- if (sock->bind_local && sock->info.lsa->actual.ai_family)
+ if (sock->bind_local)
{
create_socket (sock);
@@ -1328,6 +1341,7 @@ link_socket_init_phase1 (struct link_socket *sock,
const char *remote_port,
int proto,
sa_family_t af,
+ bool bind_ipv6_only,
int mode,
const struct link_socket *accept_from,
#ifdef ENABLE_HTTP_PROXY
@@ -1388,6 +1402,7 @@ link_socket_init_phase1 (struct link_socket *sock,
sock->info.af = af;
sock->info.remote_float = remote_float;
sock->info.lsa = lsa;
+ sock->info.bind_ipv6_only = bind_ipv6_only;
sock->info.ipchange_command = ipchange_command;
sock->info.plugins = plugins;