Created
September 13, 2009 14:30
-
-
Save jjo/186203 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 828996c831ee96947b785cfb8f376752ea02b69a Mon Sep 17 00:00:00 2001 | |
From: JuanJo Ciarlante <[email protected]> | |
Date: Sun, 13 Sep 2009 13:43:04 +0200 | |
Subject: [PATCH] * rebased openvpn-2.1_rc1b.jjo.20061206.d.patch | |
* passes {udp,tcp}x{v4,v6} loopback tests | |
* passes {udp,tcp}x{v6} remote tests | |
--- | |
buffer.c | 13 ++ | |
configure.ac | 16 ++ | |
init.c | 36 ++-- | |
manage.c | 10 +- | |
mroute.c | 60 ++++++- | |
mtcp.c | 1 + | |
multi.c | 17 ++- | |
occ.c | 2 +- | |
options.c | 42 +++-- | |
ps.c | 6 +- | |
socket.c | 597 +++++++++++++++++++++++++++++++++++++++++++++++----------- | |
socket.h | 233 ++++++++++++++++++++--- | |
socks.c | 18 +- | |
13 files changed, 857 insertions(+), 194 deletions(-) | |
diff --git a/buffer.c b/buffer.c | |
index 15ab776..1bef7d8 100644 | |
--- a/buffer.c | |
+++ b/buffer.c | |
@@ -215,6 +215,19 @@ buf_printf (struct buffer *buf, const char *format, ...) | |
return ret; | |
} | |
+void buf_puts(struct buffer *buf, const char *str) | |
+{ | |
+ uint8_t *ptr = BEND (buf); | |
+ int cap = buf_forward_capacity (buf); | |
+ if (cap > 0) | |
+ { | |
+ strncpynt ((char *)ptr,str, cap); | |
+ *(buf->data + buf->capacity - 1) = 0; /* windows vsnprintf needs this */ | |
+ buf->len += (int) strlen ((char *)ptr); | |
+ } | |
+} | |
+ | |
+ | |
/* | |
* This is necessary due to certain buggy implementations of snprintf, | |
* that don't guarantee null termination for size > 0. | |
diff --git a/configure.ac b/configure.ac | |
index 116ff7c..6864783 100644 | |
--- a/configure.ac | |
+++ b/configure.ac | |
@@ -135,6 +135,12 @@ AC_ARG_ENABLE(multihome, | |
[MULTIHOME="yes"] | |
) | |
+AC_ARG_ENABLE(ipv6, | |
+ [ --disable-ipv6 Disable UDP/IPv6 support], | |
+ [PF_INET6="$enableval"], | |
+ [PF_INET6="yes"] | |
+) | |
+ | |
AC_ARG_ENABLE(port-share, | |
[ --disable-port-share Disable TCP server port-share support (--port-share)], | |
[PORT_SHARE="$enableval"], | |
@@ -550,6 +556,16 @@ LDFLAGS="$LDFLAGS -Wl,--fatal-warnings" | |
AC_CHECK_FUNC(epoll_create, AC_DEFINE(HAVE_EPOLL_CREATE, 1, [epoll_create function is defined])) | |
LDFLAGS="$OLDLDFLAGS" | |
+dnl ipv6 support | |
+if test "$PF_INET6" = "yes"; then | |
+ AC_CHECKING([for struct sockaddr_in6 for IPv6 support]) | |
+ AC_CHECK_TYPE( | |
+ [struct sockaddr_in6], | |
+ [AC_DEFINE(USE_PF_INET6, 1, [struct sockaddr_in6 is needed for IPv6 peer support])], | |
+ [], | |
+ [#include "syshead.h"]) | |
+fi | |
+ | |
dnl | |
dnl check for valgrind tool | |
dnl | |
diff --git a/init.c b/init.c | |
index 80b2849..57ebad0 100644 | |
--- a/init.c | |
+++ b/init.c | |
@@ -94,7 +94,7 @@ update_options_ce_post (struct options *options) | |
*/ | |
if (options->pull | |
&& options->ping_rec_timeout_action == PING_UNDEF | |
- && options->ce.proto == PROTO_UDPv4) | |
+ && proto_is_dgram(options->ce.proto)) | |
{ | |
options->ping_rec_timeout = PRE_PULL_INITIAL_PING_RESTART; | |
options->ping_rec_timeout_action = PING_RESTART; | |
@@ -928,7 +928,7 @@ initialization_sequence_completed (struct context *c, const unsigned int flags) | |
const char *detail = "SUCCESS"; | |
if (c->c1.tuntap) | |
tun_local = c->c1.tuntap->local; | |
- tun_remote = htonl (c->c1.link_socket_addr.actual.dest.sa.sin_addr.s_addr); | |
+ tun_remote = htonl (c->c1.link_socket_addr.actual.dest.addr.in4.sin_addr.s_addr); | |
if (flags & ISC_ERRORS) | |
detail = "ERROR"; | |
management_set_state (management, | |
@@ -1333,7 +1333,7 @@ do_deferred_options (struct context *c, const unsigned int found) | |
#ifdef ENABLE_OCC | |
if (found & OPT_P_EXPLICIT_NOTIFY) | |
{ | |
- if (c->options.ce.proto != PROTO_UDPv4 && c->options.explicit_exit_notification) | |
+ if (!proto_is_udp(c->options.ce.proto) && c->options.explicit_exit_notification) | |
{ | |
msg (D_PUSH, "OPTIONS IMPORT: --explicit-exit-notify can only be used with --proto udp"); | |
c->options.explicit_exit_notification = 0; | |
@@ -1428,13 +1428,22 @@ socket_restart_pause (struct context *c) | |
switch (c->options.ce.proto) | |
{ | |
case PROTO_UDPv4: | |
+#ifdef USE_PF_INET6 | |
+ case PROTO_UDPv6: | |
+#endif | |
if (proxy) | |
sec = c->options.ce.connect_retry_seconds; | |
break; | |
case PROTO_TCPv4_SERVER: | |
+#ifdef USE_PF_INET6 | |
+ case PROTO_TCPv6_SERVER: | |
+#endif | |
sec = 1; | |
break; | |
case PROTO_TCPv4_CLIENT: | |
+#ifdef USE_PF_INET6 | |
+ case PROTO_TCPv6_CLIENT: | |
+#endif | |
sec = c->options.ce.connect_retry_seconds; | |
break; | |
} | |
@@ -2565,7 +2574,7 @@ do_setup_fast_io (struct context *c) | |
#ifdef WIN32 | |
msg (M_INFO, "NOTE: --fast-io is disabled since we are running on Windows"); | |
#else | |
- if (c->options.ce.proto != PROTO_UDPv4) | |
+ if (!proto_is_udp(c->options.ce.proto)) | |
msg (M_INFO, "NOTE: --fast-io is disabled since we are not using UDP"); | |
else | |
{ | |
@@ -2827,7 +2836,11 @@ init_instance (struct context *c, const struct env_set *env, const unsigned int | |
/* link_socket_mode allows CM_CHILD_TCP | |
instances to inherit acceptable fds | |
from a top-level parent */ | |
+#ifdef USE_PF_INET6 | |
+ if (c->options.ce.proto == PROTO_TCPv4_SERVER || c->options.ce.proto == PROTO_TCPv6_SERVER) | |
+#else | |
if (c->options.ce.proto == PROTO_TCPv4_SERVER) | |
+#endif | |
{ | |
if (c->mode == CM_TOP) | |
link_socket_mode = LS_MODE_TCP_LISTEN; | |
@@ -3110,17 +3123,8 @@ inherit_context_child (struct context *dest, | |
{ | |
CLEAR (*dest); | |
- switch (src->options.ce.proto) | |
- { | |
- case PROTO_UDPv4: | |
- dest->mode = CM_CHILD_UDP; | |
- break; | |
- case PROTO_TCPv4_SERVER: | |
- dest->mode = CM_CHILD_TCP; | |
- break; | |
- default: | |
- ASSERT (0); | |
- } | |
+ /* proto_is_dgram will ASSERT(0) if proto is invalid */ | |
+ dest->mode = proto_is_dgram(src->options.ce.proto)? CM_CHILD_UDP : CM_CHILD_TCP; | |
dest->gc = gc_new (); | |
@@ -3226,7 +3230,7 @@ inherit_context_top (struct context *dest, | |
dest->c2.es_owned = false; | |
dest->c2.event_set = NULL; | |
- if (src->options.ce.proto == PROTO_UDPv4) | |
+ if (proto_is_dgram(src->options.ce.proto)) | |
do_event_set_init (dest, false); | |
} | |
diff --git a/manage.c b/manage.c | |
index 97d69b4..7a1dddf 100644 | |
--- a/manage.c | |
+++ b/manage.c | |
@@ -1874,9 +1874,9 @@ man_settings_init (struct man_settings *ms, | |
/* | |
* Initialize socket address | |
*/ | |
- ms->local.sa.sin_family = AF_INET; | |
- ms->local.sa.sin_addr.s_addr = 0; | |
- ms->local.sa.sin_port = htons (port); | |
+ ms->local.addr.in4.sin_family = AF_INET; | |
+ ms->local.addr.in4.sin_addr.s_addr = 0; | |
+ ms->local.addr.in4.sin_port = htons (port); | |
/* | |
* Run management over tunnel, or | |
@@ -1888,7 +1888,7 @@ man_settings_init (struct man_settings *ms, | |
} | |
else | |
{ | |
- ms->local.sa.sin_addr.s_addr = getaddr | |
+ ms->local.addr.in4.sin_addr.s_addr = getaddr | |
(GETADDR_RESOLVE|GETADDR_WARN_ON_SIGNAL|GETADDR_FATAL, addr, 0, NULL, NULL); | |
} | |
} | |
@@ -2255,7 +2255,7 @@ management_post_tunnel_open (struct management *man, const in_addr_t tun_local_i | |
&& man->connection.state == MS_INITIAL) | |
{ | |
/* listen on our local TUN/TAP IP address */ | |
- man->settings.local.sa.sin_addr.s_addr = htonl (tun_local_ip); | |
+ man->settings.local.addr.in4.sin_addr.s_addr = htonl (tun_local_ip); | |
man_connection_init (man); | |
} | |
diff --git a/mroute.c b/mroute.c | |
index 9d8fa66..e4abdad 100644 | |
--- a/mroute.c | |
+++ b/mroute.c | |
@@ -226,25 +226,47 @@ bool mroute_extract_openvpn_sockaddr (struct mroute_addr *addr, | |
const struct openvpn_sockaddr *osaddr, | |
bool use_port) | |
{ | |
- if (osaddr->sa.sin_family == AF_INET) | |
+ switch (osaddr->addr.sa.sa_family) | |
+ { | |
+ case AF_INET: | |
{ | |
if (use_port) | |
{ | |
addr->type = MR_ADDR_IPV4 | MR_WITH_PORT; | |
addr->netbits = 0; | |
addr->len = 6; | |
- memcpy (addr->addr, &osaddr->sa.sin_addr.s_addr, 4); | |
- memcpy (addr->addr + 4, &osaddr->sa.sin_port, 2); | |
+ memcpy (addr->addr, &osaddr->addr.in4.sin_addr.s_addr, 4); | |
+ memcpy (addr->addr + 4, &osaddr->addr.in4.sin_port, 2); | |
} | |
else | |
{ | |
addr->type = MR_ADDR_IPV4; | |
addr->netbits = 0; | |
addr->len = 4; | |
- memcpy (addr->addr, &osaddr->sa.sin_addr.s_addr, 4); | |
+ memcpy (addr->addr, &osaddr->addr.in4.sin_addr.s_addr, 4); | |
} | |
return true; | |
} | |
+#ifdef USE_PF_INET6 | |
+ case AF_INET6: | |
+ if (use_port) | |
+ { | |
+ addr->type = MR_ADDR_IPV6 | MR_WITH_PORT; | |
+ addr->netbits = 0; | |
+ addr->len = 18; | |
+ memcpy (addr->addr, &osaddr->addr.in6.sin6_addr, 16); | |
+ memcpy (addr->addr + 16, &osaddr->addr.in6.sin6_port, 2); | |
+ } | |
+ else | |
+ { | |
+ addr->type = MR_ADDR_IPV6; | |
+ addr->netbits = 0; | |
+ addr->len = 16; | |
+ memcpy (addr->addr, &osaddr->addr.in6.sin6_addr, 16); | |
+ } | |
+ return true; | |
+#endif | |
+ } | |
return false; | |
} | |
@@ -337,7 +359,37 @@ mroute_addr_print_ex (const struct mroute_addr *ma, | |
} | |
break; | |
case MR_ADDR_IPV6: | |
+#ifdef USE_PF_INET6 | |
+ { | |
+ struct buffer buf; | |
+ struct sockaddr_in6 sin6; | |
+ int port; | |
+ char buf6[INET6_ADDRSTRLEN] = ""; | |
+ memset(&sin6, 0, sizeof sin6); | |
+ sin6.sin6_family = AF_INET6; | |
+ buf_set_read (&buf, maddr.addr, maddr.len); | |
+ if (buf_read(&buf, &sin6.sin6_addr, sizeof (sin6.sin6_addr))) | |
+ { | |
+ if (getnameinfo((struct sockaddr *)&sin6, sizeof (struct sockaddr_in6), | |
+ buf6, sizeof (buf6), NULL, 0, NI_NUMERICHOST) != 0) | |
+ { | |
+ buf_printf (&out, "MR_ADDR_IPV6 getnameinfo() err"); | |
+ break; | |
+ } | |
+ buf_puts (&out, buf6); | |
+ if (maddr.type & MR_WITH_NETBITS) | |
+ buf_printf (&out, "/%d", maddr.netbits); | |
+ if (maddr.type & MR_WITH_PORT) | |
+ { | |
+ port = buf_read_u16 (&buf); | |
+ if (port >= 0) | |
+ buf_printf (&out, ":%d", port); | |
+ } | |
+ } | |
+ } | |
+#else /* old pre IPV6 1-line code: */ | |
buf_printf (&out, "IPV6"); | |
+#endif | |
break; | |
default: | |
buf_printf (&out, "UNKNOWN"); | |
diff --git a/mtcp.c b/mtcp.c | |
index 72c9618..f578429 100644 | |
--- a/mtcp.c | |
+++ b/mtcp.c | |
@@ -153,6 +153,7 @@ multi_tcp_instance_specific_init (struct multi_context *m, struct multi_instance | |
ASSERT (mi->context.c2.link_socket); | |
ASSERT (mi->context.c2.link_socket->info.lsa); | |
ASSERT (mi->context.c2.link_socket->mode == LS_MODE_TCP_ACCEPT_FROM); | |
+ ASSERT (mi->context.c2.link_socket->info.lsa->actual.dest.addr.sa.sa_family == AF_INET); | |
if (!mroute_extract_openvpn_sockaddr (&mi->real, &mi->context.c2.link_socket->info.lsa->actual.dest, true)) | |
{ | |
msg (D_MULTI_ERRORS, "MULTI TCP: TCP client address is undefined"); | |
diff --git a/multi.c b/multi.c | |
index f62563c..f89814a 100644 | |
--- a/multi.c | |
+++ b/multi.c | |
@@ -1066,8 +1066,8 @@ multi_learn_in_addr_t (struct multi_context *m, | |
struct mroute_addr addr; | |
CLEAR (remote_si); | |
- remote_si.sa.sin_family = AF_INET; | |
- remote_si.sa.sin_addr.s_add |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment