diff options
Diffstat (limited to 'debian/patches/jjo-ipv6-support.patch')
-rw-r--r-- | debian/patches/jjo-ipv6-support.patch | 4011 |
1 files changed, 0 insertions, 4011 deletions
diff --git a/debian/patches/jjo-ipv6-support.patch b/debian/patches/jjo-ipv6-support.patch deleted file mode 100644 index c516763..0000000 --- a/debian/patches/jjo-ipv6-support.patch +++ /dev/null @@ -1,4011 +0,0 @@ -Description: OpenVPN over UDP6/TCP6 patch -Author: JuanJo Ciarlante <jjo@google.com> -URL: https://github.com/jjo/openvpn-ipv6/ -Index: openvpn-2.2.1/README.ipv6 -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ openvpn-2.2.1/README.ipv6 2011-12-13 12:23:07.264081559 +0100 -@@ -0,0 +1,81 @@ -+[ Last updated: 25-Mar-2011. ] -+ -+OpenVPN-2.1 over UDP6/TCP6 README for ipv6-0.4.x patch releases: -+( --udp6 and --tcp6-{client,server} ) -+ -+* Availability -+ Source code under GPLv2 from http://github.com/jjo/openvpn-ipv6 -+ -+ Distro ready repos/packages: -+ o Debian sid official repo, by Alberto Gonzalez Iniesta, -+ starting from openvpn_2.1~rc20-2 -+ o Gentoo official portage tree, by Marcel Pennewiss: -+ - https://bugs.gentoo.org/show_bug.cgi?id=287896 -+ o Ubuntu package, by Bernhard Schmidt: -+ - https://launchpad.net/~berni/+archive/ipv6/+packages -+ o Freetz.org, milestone freetz-1.2 -+ - http://trac.freetz.org/milestone/freetz-1.2 -+ -+* Status: -+ o OK: -+ - upd6,tcp6: GNU/Linux, win32, openbsd-4.7, freebsd-8.1 -+ - udp4->upd6,tcp4->tcp6 (ipv4/6 mapped): GNU/Linux -+ (gives a warning on local!=remote proto matching) -+ o NOT: -+ - win32: tcp4->tcp6 (ipv4/6 mapped) fails w/connection refused -+ o NOT tested: -+ - mgmt console -+ -+* Build setup: -+ ./configure --enable-ipv6 (by default) -+ -+* Usage: -+ For IPv6 just specify "-p upd6" an proper IPv6 hostnames, adapting the example -+ from man page ... -+ -+ On may: -+ openvpn --proto udp6 --remote <june_IPv6_addr> --dev tun1 \ -+ --ifconfig 10.4.0.1 10.4.0.2 --verb 5 --secret key -+ -+ On june: -+ openvpn --proto udp6 --remote <may_IPv6_addr> --dev tun1 \ -+ --ifconfig 10.4.0.2 10.4.0.1 --verb 5 --secret key -+ -+ Same for --proto tcp6-client, tcp6-server. -+ -+* Main code changes summary: -+ - socket.h: New struct openvpn_sockaddr type that holds sockaddrs and pktinfo, -+ (here I omitted #ifdef USE_PF_xxxx, see socket.h ) -+ -+ struct openvpn_sockaddr { -+ union { -+ struct sockaddr sa; -+ struct sockaddr_in in; -+ struct sockaddr_in6 in6; -+ } addr; -+ }; -+ -+ struct link_socket_addr -+ { -+ struct openvpn_sockaddr local; -+ struct openvpn_sockaddr remote; -+ struct openvpn_sockaddr actual; -+ }; -+ -+ PRO: allows simple type overloading: local.addr.sa, local.addr.in, local.addr.in6 ... etc -+ (also local.pi.in and local.pi.in6) -+ -+ - several function prototypes moved from sockaddr_in to openvpn_sockaddr -+ - several new sockaddr functions needed to "generalize" AF_xxxx operations: -+ addr_copy(), addr_zero(), ...etc -+ proto_is_udp(), proto_is_dgram(), proto_is_net() -+ -+* TODO: See TODO.ipv6 -+ -+-- -+JuanJo Ciarlante jjo () google () com ............................ -+: : -+. Linux IP Aliasing author . -+. Modular algo (AES et all) support for FreeSWAN/OpenSWAN author . -+. OpenVPN over IPv6 support . -+:...... plus other scattered free software bits in the wild ...: -Index: openvpn-2.2.1/TODO.ipv6 -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ openvpn-2.2.1/TODO.ipv6 2011-12-13 12:23:07.267081520 +0100 -@@ -0,0 +1,30 @@ -+[ Last updated: 11-Nov-2009. ] -+ -+* All platforms: -+ o mgmt console: as currently passes straight in_addr_t bits around -+ -+ o make possible to get AF from getaddrinfo() answer, ie allow openvpn to -+ use ipv4/6 if DNS returns A/AAAA without specifying protocol. -+ Hard: requires deep changes in initialization/calling logic -+ -+ o use AI_PASSIVE -+ -+ o the getaddr()/getaddr6() interface is not prepared for handling socktype -+ "tagging", currently I abuse the sockflags bits for getting the ai_socktype -+ downstream. -+ -+ o implement comparison for mapped addesses: server in dual stack -+ listening IPv6 must permit incoming streams from allowed IPv4 peer, -+ currently you need to pass eg: --remote ffff::1.2.3.4 -+ -+ o do something with multi mode learn routes, for now just ignoring -+ ipv6 addresses seems the most sensible thing to do, because there's -+ no support for intra-tunnel ipv6 stuff. -+ -+* win32: -+ o find out about mapped addresses, as I can't make it work -+ with bound at ::1 and connect to 127.0.0.1 -+ -+* N/A: -+ o this is ipv6 *endpoint* support, so don't expect "ifconfig6"-like -+ support in this patch -Index: openvpn-2.2.1/acinclude.m4 -=================================================================== ---- openvpn-2.2.1.orig/acinclude.m4 2011-06-24 08:13:38.000000000 +0200 -+++ openvpn-2.2.1/acinclude.m4 2011-12-13 12:23:07.290081232 +0100 -@@ -123,5 +123,9 @@ - AC_DEFINE_UNQUOTED(socklen_t, $curl_cv_socklen_t_equiv, - [type to use in place of socklen_t if not defined])], - [#include <sys/types.h> --#include <sys/socket.h>]) -+#ifdef WIN32 -+#include <ws2tcpip.h> -+#else -+#include <sys/socket.h> -+#endif]) - ]) -Index: openvpn-2.2.1/aclocal.m4 -=================================================================== ---- openvpn-2.2.1.orig/aclocal.m4 2011-07-01 11:26:36.000000000 +0200 -+++ openvpn-2.2.1/aclocal.m4 2011-12-13 12:23:07.323080820 +0100 -@@ -13,8 +13,8 @@ - - m4_ifndef([AC_AUTOCONF_VERSION], - [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl --m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.66],, --[m4_warning([this file was generated for autoconf 2.66. -+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.65],, -+[m4_warning([this file was generated for autoconf 2.65. - You have another version of autoconf. It may work, but is not guaranteed to. - If you have problems, you may need to regenerate the build system entirely. - To do so, use the procedure documented by the package, typically `autoreconf'.])]) -Index: openvpn-2.2.1/buffer.c -=================================================================== ---- openvpn-2.2.1.orig/buffer.c 2011-06-24 08:13:38.000000000 +0200 -+++ openvpn-2.2.1/buffer.c 2011-12-13 12:23:07.326080784 +0100 -@@ -214,6 +214,23 @@ - return ret; - } - -+bool -+buf_puts(struct buffer *buf, const char *str) -+{ -+ int ret = false; -+ 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); -+ ret = true; -+ } -+ return ret; -+} -+ -+ - /* - * This is necessary due to certain buggy implementations of snprintf, - * that don't guarantee null termination for size > 0. -Index: openvpn-2.2.1/buffer.h -=================================================================== ---- openvpn-2.2.1.orig/buffer.h 2011-06-24 08:13:38.000000000 +0200 -+++ openvpn-2.2.1/buffer.h 2011-12-13 12:23:07.329080745 +0100 -@@ -277,6 +277,11 @@ - ; - - /* -+ * puts append to a buffer with overflow check -+ */ -+bool buf_puts (struct buffer *buf, const char *str); -+ -+/* - * Like snprintf but guarantees null termination for size > 0 - */ - int openvpn_snprintf(char *str, size_t size, const char *format, ...) -Index: openvpn-2.2.1/config.h.in -=================================================================== ---- openvpn-2.2.1.orig/config.h.in 2011-07-01 11:26:37.000000000 +0200 -+++ openvpn-2.2.1/config.h.in 2011-12-13 12:23:07.332080708 +0100 -@@ -531,6 +531,9 @@ - /* Use LZO compression library */ - #undef USE_LZO - -+/* struct sockaddr_in6 is needed for IPv6 peer support */ -+#undef USE_PF_INET6 -+ - /* Enable PKCS11 capability */ - #undef USE_PKCS11 - -Index: openvpn-2.2.1/configure -=================================================================== ---- openvpn-2.2.1.orig/configure 2011-07-01 11:26:37.000000000 +0200 -+++ openvpn-2.2.1/configure 2011-12-13 12:23:07.347080520 +0100 -@@ -319,7 +319,7 @@ - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" -- } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" -+ } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir" - - - } # as_fn_mkdir_p -@@ -359,19 +359,19 @@ - fi # as_fn_arith - - --# as_fn_error STATUS ERROR [LINENO LOG_FD] --# ---------------------------------------- -+# as_fn_error ERROR [LINENO LOG_FD] -+# --------------------------------- - # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are - # provided, also output the error to LOG_FD, referencing LINENO. Then exit the --# script with STATUS, using 1 if that was 0. -+# script with status $?, using 1 if that was 0. - as_fn_error () - { -- as_status=$1; test $as_status -eq 0 && as_status=1 -- if test "$4"; then -- as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack -- $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 -+ as_status=$?; test $as_status -eq 0 && as_status=1 -+ if test "$3"; then -+ as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack -+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3 - fi -- $as_echo "$as_me: error: $2" >&2 -+ $as_echo "$as_me: error: $1" >&2 - as_fn_exit $as_status - } # as_fn_error - -@@ -533,7 +533,7 @@ - exec 6>&1 - - # Name of the host. --# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, -+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, - # so uname gets run too. - ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` - -@@ -715,6 +715,7 @@ - enable_http - enable_fragment - enable_multihome -+enable_ipv6 - enable_port_share - enable_debug - enable_small -@@ -858,7 +859,7 @@ - ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && -- as_fn_error $? "invalid feature name: $ac_useropt" -+ as_fn_error "invalid feature name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in -@@ -884,7 +885,7 @@ - ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && -- as_fn_error $? "invalid feature name: $ac_useropt" -+ as_fn_error "invalid feature name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in -@@ -1088,7 +1089,7 @@ - ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && -- as_fn_error $? "invalid package name: $ac_useropt" -+ as_fn_error "invalid package name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in -@@ -1104,7 +1105,7 @@ - ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && -- as_fn_error $? "invalid package name: $ac_useropt" -+ as_fn_error "invalid package name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in -@@ -1134,8 +1135,8 @@ - | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) - x_libraries=$ac_optarg ;; - -- -*) as_fn_error $? "unrecognized option: \`$ac_option' --Try \`$0 --help' for more information" -+ -*) as_fn_error "unrecognized option: \`$ac_option' -+Try \`$0 --help' for more information." - ;; - - *=*) -@@ -1143,7 +1144,7 @@ - # Reject names that are not valid shell variable names. - case $ac_envvar in #( - '' | [0-9]* | *[!_$as_cr_alnum]* ) -- as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; -+ as_fn_error "invalid variable name: \`$ac_envvar'" ;; - esac - eval $ac_envvar=\$ac_optarg - export $ac_envvar ;; -@@ -1161,13 +1162,13 @@ - - if test -n "$ac_prev"; then - ac_option=--`echo $ac_prev | sed 's/_/-/g'` -- as_fn_error $? "missing argument to $ac_option" -+ as_fn_error "missing argument to $ac_option" - fi - - if test -n "$ac_unrecognized_opts"; then - case $enable_option_checking in - no) ;; -- fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; -+ fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;; - *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; - esac - fi -@@ -1190,7 +1191,7 @@ - [\\/$]* | ?:[\\/]* ) continue;; - NONE | '' ) case $ac_var in *prefix ) continue;; esac;; - esac -- as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" -+ as_fn_error "expected an absolute directory name for --$ac_var: $ac_val" - done - - # There might be people who depend on the old broken behavior: `$host' -@@ -1204,8 +1205,8 @@ - if test "x$host_alias" != x; then - if test "x$build_alias" = x; then - cross_compiling=maybe -- $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. -- If a cross compiler is detected then cross compile mode will be used" >&2 -+ $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. -+ If a cross compiler is detected then cross compile mode will be used." >&2 - elif test "x$build_alias" != "x$host_alias"; then - cross_compiling=yes - fi -@@ -1220,9 +1221,9 @@ - ac_pwd=`pwd` && test -n "$ac_pwd" && - ac_ls_di=`ls -di .` && - ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || -- as_fn_error $? "working directory cannot be determined" -+ as_fn_error "working directory cannot be determined" - test "X$ac_ls_di" = "X$ac_pwd_ls_di" || -- as_fn_error $? "pwd does not report name of working directory" -+ as_fn_error "pwd does not report name of working directory" - - - # Find the source files, if location was not specified. -@@ -1261,11 +1262,11 @@ - fi - if test ! -r "$srcdir/$ac_unique_file"; then - test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." -- as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" -+ as_fn_error "cannot find sources ($ac_unique_file) in $srcdir" - fi - ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" - ac_abs_confdir=`( -- cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" -+ cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg" - pwd)` - # When building in place, set srcdir=. - if test "$ac_abs_confdir" = "$ac_pwd"; then -@@ -1305,7 +1306,7 @@ - --help=short display options specific to this package - --help=recursive display the short help of all the included packages - -V, --version display version information and exit -- -q, --quiet, --silent do not print \`checking ...' messages -+ -q, --quiet, --silent do not print \`checking...' messages - --cache-file=FILE cache test results in FILE [disabled] - -C, --config-cache alias for \`--cache-file=config.cache' - -n, --no-create do not create output files -@@ -1383,6 +1384,7 @@ - --disable-http Disable HTTP proxy support - --disable-fragment Disable internal fragmentation support (--fragment) - --disable-multihome Disable multi-homed UDP server support (--multihome) -+ --disable-ipv6 Disable UDP/IPv6 support - --disable-port-share Disable TCP server port-share support (--port-share) - --disable-debug Disable debugging support (disable gremlin and verb 7+ messages) - --enable-small Enable smaller executable size (disable OCC, usage message, and verb 4 parm list) -@@ -1588,10 +1590,10 @@ - ac_fn_c_check_header_mongrel () - { - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack -- if eval "test \"\${$3+set}\"" = set; then : -+ if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 - $as_echo_n "checking for $2... " >&6; } --if eval "test \"\${$3+set}\"" = set; then : -+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : - $as_echo_n "(cached) " >&6 - fi - eval ac_res=\$$3 -@@ -1650,15 +1652,17 @@ - $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 - $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} --( $as_echo "## -------------------------------------------------- ## -+( cat <<\_ASBOX -+## -------------------------------------------------- ## - ## Report this to openvpn-users@lists.sourceforge.net ## --## -------------------------------------------------- ##" -+## -------------------------------------------------- ## -+_ASBOX - ) | sed "s/^/$as_me: WARNING: /" >&2 - ;; - esac - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 - $as_echo_n "checking for $2... " >&6; } --if eval "test \"\${$3+set}\"" = set; then : -+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : - $as_echo_n "(cached) " >&6 - else - eval "$3=\$ac_header_compiler" -@@ -1722,7 +1726,7 @@ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 - $as_echo_n "checking for $2... " >&6; } --if eval "test \"\${$3+set}\"" = set; then : -+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : - $as_echo_n "(cached) " >&6 - else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -@@ -1753,7 +1757,7 @@ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 - $as_echo_n "checking for $2... " >&6; } --if eval "test \"\${$3+set}\"" = set; then : -+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : - $as_echo_n "(cached) " >&6 - else - eval "$3=no" -@@ -2030,7 +2034,7 @@ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 - $as_echo_n "checking for $2... " >&6; } --if eval "test \"\${$3+set}\"" = set; then : -+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : - $as_echo_n "(cached) " >&6 - else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -@@ -2203,9 +2207,11 @@ - { - echo - -- $as_echo "## ---------------- ## -+ cat <<\_ASBOX -+## ---------------- ## - ## Cache variables. ## --## ---------------- ##" -+## ---------------- ## -+_ASBOX - echo - # The following way of writing the cache mishandles newlines in values, - ( -@@ -2239,9 +2245,11 @@ - ) - echo - -- $as_echo "## ----------------- ## -+ cat <<\_ASBOX -+## ----------------- ## - ## Output variables. ## --## ----------------- ##" -+## ----------------- ## -+_ASBOX - echo - for ac_var in $ac_subst_vars - do -@@ -2254,9 +2262,11 @@ - echo - - if test -n "$ac_subst_files"; then -- $as_echo "## ------------------- ## -+ cat <<\_ASBOX -+## ------------------- ## - ## File substitutions. ## --## ------------------- ##" -+## ------------------- ## -+_ASBOX - echo - for ac_var in $ac_subst_files - do -@@ -2270,9 +2280,11 @@ - fi - - if test -s confdefs.h; then -- $as_echo "## ----------- ## -+ cat <<\_ASBOX -+## ----------- ## - ## confdefs.h. ## --## ----------- ##" -+## ----------- ## -+_ASBOX - echo - cat confdefs.h - echo -@@ -2327,12 +2339,7 @@ - ac_site_file1=NONE - ac_site_file2=NONE - if test -n "$CONFIG_SITE"; then -- # We do not want a PATH search for config.site. -- case $CONFIG_SITE in #(( -- -*) ac_site_file1=./$CONFIG_SITE;; -- */*) ac_site_file1=$CONFIG_SITE;; -- *) ac_site_file1=./$CONFIG_SITE;; -- esac -+ ac_site_file1=$CONFIG_SITE - elif test "x$prefix" != xNONE; then - ac_site_file1=$prefix/share/config.site - ac_site_file2=$prefix/etc/config.site -@@ -2347,11 +2354,7 @@ - { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 - $as_echo "$as_me: loading site script $ac_site_file" >&6;} - sed 's/^/| /' "$ac_site_file" >&5 -- . "$ac_site_file" \ -- || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 --$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} --as_fn_error $? "failed to load site script $ac_site_file --See \`config.log' for more details" "$LINENO" 5; } -+ . "$ac_site_file" - fi - done - -@@ -2427,7 +2430,7 @@ - $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 - $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} -- as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 -+ as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 - fi - ## -------------------- ## - ## Main body of script. ## -@@ -2446,22 +2449,16 @@ - - ac_aux_dir= - for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do -- if test -f "$ac_dir/install-sh"; then -- ac_aux_dir=$ac_dir -- ac_install_sh="$ac_aux_dir/install-sh -c" -- break -- elif test -f "$ac_dir/install.sh"; then -- ac_aux_dir=$ac_dir -- ac_install_sh="$ac_aux_dir/install.sh -c" -- break -- elif test -f "$ac_dir/shtool"; then -- ac_aux_dir=$ac_dir -- ac_install_sh="$ac_aux_dir/shtool install -c" -- break -- fi -+ for ac_t in install-sh install.sh shtool; do -+ if test -f "$ac_dir/$ac_t"; then -+ ac_aux_dir=$ac_dir -+ ac_install_sh="$ac_aux_dir/$ac_t -c" -+ break 2 -+ fi -+ done - done - if test -z "$ac_aux_dir"; then -- as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 -+ as_fn_error "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 - fi - - # These three variables are undocumented and unsupported, -@@ -2475,7 +2472,7 @@ - - # Make sure we can run config.sub. - $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || -- as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 -+ as_fn_error "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 - $as_echo_n "checking build system type... " >&6; } -@@ -2486,16 +2483,16 @@ - test "x$ac_build_alias" = x && - ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` - test "x$ac_build_alias" = x && -- as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 -+ as_fn_error "cannot guess build type; you must specify one" "$LINENO" 5 - ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || -- as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 -+ as_fn_error "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 - - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 - $as_echo "$ac_cv_build" >&6; } - case $ac_cv_build in - *-*-*) ;; --*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; -+*) as_fn_error "invalid value of canonical build" "$LINENO" 5;; - esac - build=$ac_cv_build - ac_save_IFS=$IFS; IFS='-' -@@ -2520,7 +2517,7 @@ - ac_cv_host=$ac_cv_build - else - ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || -- as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 -+ as_fn_error "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 - fi - - fi -@@ -2528,7 +2525,7 @@ - $as_echo "$ac_cv_host" >&6; } - case $ac_cv_host in - *-*-*) ;; --*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; -+*) as_fn_error "invalid value of canonical host" "$LINENO" 5;; - esac - host=$ac_cv_host - ac_save_IFS=$IFS; IFS='-' -@@ -2650,11 +2647,11 @@ - ' - case `pwd` in - *[\\\"\#\$\&\'\`$am_lf]*) -- as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; -+ as_fn_error "unsafe absolute working directory name" "$LINENO" 5;; - esac - case $srcdir in - *[\\\"\#\$\&\'\`$am_lf\ \ ]*) -- as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; -+ as_fn_error "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; - esac - - # Do `set' in a subshell so we don't clobber the current shell's -@@ -2676,7 +2673,7 @@ - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". -- as_fn_error $? "ls -t appears to fail. Make sure there is not a broken -+ as_fn_error "ls -t appears to fail. Make sure there is not a broken - alias in your environment" "$LINENO" 5 - fi - -@@ -2686,7 +2683,7 @@ - # Ok. - : - else -- as_fn_error $? "newly created file is older than distributed files! -+ as_fn_error "newly created file is older than distributed files! - Check your system clock" "$LINENO" 5 - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -@@ -2924,7 +2921,7 @@ - $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } - set x ${MAKE-make} - ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` --if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\"" = set; then : -+if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then : - $as_echo_n "(cached) " >&6 - else - cat >conftest.make <<\_ACEOF -@@ -2932,7 +2929,7 @@ - all: - @echo '@@@%%%=$(MAKE)=@@@%%%' - _ACEOF --# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. -+# GNU make sometimes prints "make[1]: Entering...", which would confuse us. - case `${MAKE-make} -f conftest.make 2>/dev/null` in - *@@@%%%=?*=@@@%%%*) - eval ac_cv_prog_make_${ac_make}_set=yes;; -@@ -2966,7 +2963,7 @@ - am__isrc=' -I$(srcdir)' - # test to see if srcdir already configured - if test -f $srcdir/config.status; then -- as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 -+ as_fn_error "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 - fi - fi - -@@ -3184,6 +3181,15 @@ - fi - - -+# Check whether --enable-ipv6 was given. -+if test "${enable_ipv6+set}" = set; then : -+ enableval=$enable_ipv6; PF_INET6="$enableval" -+else -+ PF_INET6="yes" -+ -+fi -+ -+ - # Check whether --enable-port-share was given. - if test "${enable_port_share+set}" = set; then : - enableval=$enable_port_share; PORT_SHARE="$enableval" -@@ -3954,8 +3960,8 @@ - - test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 - $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} --as_fn_error $? "no acceptable C compiler found in \$PATH --See \`config.log' for more details" "$LINENO" 5; } -+as_fn_error "no acceptable C compiler found in \$PATH -+See \`config.log' for more details." "$LINENO" 5; } - - # Provide some information about the compiler. - $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 -@@ -4069,8 +4075,9 @@ - - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 - $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} --as_fn_error 77 "C compiler cannot create executables --See \`config.log' for more details" "$LINENO" 5; } -+{ as_fn_set_status 77 -+as_fn_error "C compiler cannot create executables -+See \`config.log' for more details." "$LINENO" 5; }; } - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 - $as_echo "yes" >&6; } -@@ -4112,8 +4119,8 @@ - else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 - $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} --as_fn_error $? "cannot compute suffix of executables: cannot compile and link --See \`config.log' for more details" "$LINENO" 5; } -+as_fn_error "cannot compute suffix of executables: cannot compile and link -+See \`config.log' for more details." "$LINENO" 5; } - fi - rm -f conftest conftest$ac_cv_exeext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 -@@ -4170,9 +4177,9 @@ - else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 - $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} --as_fn_error $? "cannot run C compiled programs. -+as_fn_error "cannot run C compiled programs. - If you meant to cross compile, use \`--host'. --See \`config.log' for more details" "$LINENO" 5; } -+See \`config.log' for more details." "$LINENO" 5; } - fi - fi - fi -@@ -4223,8 +4230,8 @@ - - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 - $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} --as_fn_error $? "cannot compute suffix of object files: cannot compile --See \`config.log' for more details" "$LINENO" 5; } -+as_fn_error "cannot compute suffix of object files: cannot compile -+See \`config.log' for more details." "$LINENO" 5; } - fi - rm -f conftest.$ac_cv_objext conftest.$ac_ext - fi -@@ -4762,8 +4769,8 @@ - else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 - $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} --as_fn_error $? "C preprocessor \"$CPP\" fails sanity check --See \`config.log' for more details" "$LINENO" 5; } -+as_fn_error "C preprocessor \"$CPP\" fails sanity check -+See \`config.log' for more details." "$LINENO" 5; } - fi - - ac_ext=c -@@ -4824,7 +4831,7 @@ - done - IFS=$as_save_IFS - if test -z "$ac_cv_path_GREP"; then -- as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 -+ as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi - else - ac_cv_path_GREP=$GREP -@@ -4890,7 +4897,7 @@ - done - IFS=$as_save_IFS - if test -z "$ac_cv_path_EGREP"; then -- as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 -+ as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi - else - ac_cv_path_EGREP=$EGREP -@@ -5064,7 +5071,8 @@ - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` - ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default - " --if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : -+eval as_val=\$$as_ac_Header -+ if test "x$as_val" = x""yes; then : - cat >>confdefs.h <<_ACEOF - #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 - _ACEOF -@@ -5181,7 +5189,7 @@ - test -n "$MAN2HTML" && break - done - -- test -z "${MAN2HTML}" && as_fn_error $? "man2html is required for win32" "$LINENO" 5 -+ test -z "${MAN2HTML}" && as_fn_error "man2html is required for win32" "$LINENO" 5 - fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 -@@ -5518,7 +5526,11 @@ - - - ac_fn_c_check_type "$LINENO" "socklen_t" "ac_cv_type_socklen_t" "#include <sys/types.h> -+#ifdef WIN32 -+#include <ws2tcpip.h> -+#else - #include <sys/socket.h> -+#endif - " - if test "x$ac_cv_type_socklen_t" = x""yes; then : - -@@ -5570,7 +5582,7 @@ - esac - - if test "x$curl_cv_socklen_t_equiv" = x; then -- as_fn_error $? "Cannot find a type to use in place of socklen_t" "$LINENO" 5 -+ as_fn_error "Cannot find a type to use in place of socklen_t" "$LINENO" 5 - fi - - fi -@@ -5711,7 +5723,7 @@ - - else - -- as_fn_error $? "C compiler is unable to creaty empty arrays" "$LINENO" 5 -+ as_fn_error "C compiler is unable to creaty empty arrays" "$LINENO" 5 - - fi - rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -@@ -5725,7 +5737,8 @@ - do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` - ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" --if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : -+eval as_val=\$$as_ac_Header -+ if test "x$as_val" = x""yes; then : - cat >>confdefs.h <<_ACEOF - #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 - _ACEOF -@@ -5781,7 +5794,8 @@ - do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` - ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" --if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : -+eval as_val=\$$as_ac_Header -+ if test "x$as_val" = x""yes; then : - cat >>confdefs.h <<_ACEOF - #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 - _ACEOF -@@ -6077,8 +6091,9 @@ - if test "$ac_cv_type_unsigned_int" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 - $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} --as_fn_error 77 "cannot compute sizeof (unsigned int) --See \`config.log' for more details" "$LINENO" 5; } -+{ as_fn_set_status 77 -+as_fn_error "cannot compute sizeof (unsigned int) -+See \`config.log' for more details." "$LINENO" 5; }; } - else - ac_cv_sizeof_unsigned_int=0 - fi -@@ -6110,8 +6125,9 @@ - if test "$ac_cv_type_unsigned_long" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 - $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} --as_fn_error 77 "cannot compute sizeof (unsigned long) --See \`config.log' for more details" "$LINENO" 5; } -+{ as_fn_set_status 77 -+as_fn_error "cannot compute sizeof (unsigned long) -+See \`config.log' for more details." "$LINENO" 5; }; } - else - ac_cv_sizeof_unsigned_long=0 - fi -@@ -6208,13 +6224,14 @@ - do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` - ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" --if eval test \"x\$"$as_ac_var"\" = x"yes"; then : -+eval as_val=\$$as_ac_var -+ if test "x$as_val" = x""yes; then : - cat >>confdefs.h <<_ACEOF - #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 - _ACEOF - - else -- as_fn_error $? "Required library function not found" "$LINENO" 5 -+ as_fn_error "Required library function not found" "$LINENO" 5 - fi - done - -@@ -6222,7 +6239,8 @@ - do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` - ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" --if eval test \"x\$"$as_ac_var"\" = x"yes"; then : -+eval as_val=\$$as_ac_var -+ if test "x$as_val" = x""yes; then : - cat >>confdefs.h <<_ACEOF - #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 - _ACEOF -@@ -6513,7 +6531,8 @@ - do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` - ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" --if eval test \"x\$"$as_ac_var"\" = x"yes"; then : -+eval as_val=\$$as_ac_var -+ if test "x$as_val" = x""yes; then : - cat >>confdefs.h <<_ACEOF - #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 - _ACEOF -@@ -6727,13 +6746,14 @@ - do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` - ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" --if eval test \"x\$"$as_ac_var"\" = x"yes"; then : -+eval as_val=\$$as_ac_var -+ if test "x$as_val" = x""yes; then : - cat >>confdefs.h <<_ACEOF - #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 - _ACEOF - - else -- as_fn_error $? "Required library function not found" "$LINENO" 5 -+ as_fn_error "Required library function not found" "$LINENO" 5 - fi - done - -@@ -6741,7 +6761,8 @@ - do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` - ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" --if eval test \"x\$"$as_ac_var"\" = x"yes"; then : -+eval as_val=\$$as_ac_var -+ if test "x$as_val" = x""yes; then : - cat >>confdefs.h <<_ACEOF - #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 - _ACEOF -@@ -6861,6 +6882,19 @@ - - LDFLAGS="$OLDLDFLAGS" - -+if test "$PF_INET6" = "yes"; then -+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct sockaddr_in6 for IPv6 support..." >&5 -+$as_echo "$as_me: checking for struct sockaddr_in6 for IPv6 support..." >&6;} -+ ac_fn_c_check_type "$LINENO" "struct sockaddr_in6" "ac_cv_type_struct_sockaddr_in6" "#include \"syshead.h\" -+" -+if test "x$ac_cv_type_struct_sockaddr_in6" = x""yes; then : -+ -+$as_echo "#define USE_PF_INET6 1" >>confdefs.h -+ -+fi -+ -+fi -+ - - if test "$MEMCHECK" = "valgrind"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for valgrind tool and Header files..." >&5 -@@ -6874,7 +6908,7 @@ - CFLAGS="-g -fno-inline" - - else -- as_fn_error $? "valgrind headers not found." "$LINENO" 5 -+ as_fn_error "valgrind headers not found." "$LINENO" 5 - - fi - -@@ -6933,12 +6967,12 @@ - - - else -- as_fn_error $? "dmalloc library not found." "$LINENO" 5 -+ as_fn_error "dmalloc library not found." "$LINENO" 5 - - fi - - else -- as_fn_error $? "dmalloc headers not found." "$LINENO" 5 -+ as_fn_error "dmalloc headers not found." "$LINENO" 5 - - fi - -@@ -7093,7 +7127,7 @@ - as_ac_Lib=`$as_echo "ac_cv_lib_$i''_lzo1x_1_15_compress" | $as_tr_sh` - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for lzo1x_1_15_compress in -l$i" >&5 - $as_echo_n "checking for lzo1x_1_15_compress in -l$i... " >&6; } --if eval "test \"\${$as_ac_Lib+set}\"" = set; then : -+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then : - $as_echo_n "(cached) " >&6 - else - ac_check_lib_save_LIBS=$LIBS -@@ -7128,7 +7162,8 @@ - eval ac_res=\$$as_ac_Lib - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 - $as_echo "$ac_res" >&6; } --if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : -+eval as_val=\$$as_ac_Lib -+ if test "x$as_val" = x""yes; then : - - - LIBS="-l$i $LIBS" -@@ -7148,14 +7183,14 @@ - - done - if test $havelzolib = 0 ; then -- as_fn_error $? "LZO headers were found but LZO library was not found" "$LINENO" 5 -+ as_fn_error "LZO headers were found but LZO library was not found" "$LINENO" 5 - fi - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: LZO headers were not found" >&5 - $as_echo "LZO headers were not found" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: LZO library available from http://www.oberhumer.com/opensource/lzo/" >&5 - $as_echo "LZO library available from http://www.oberhumer.com/opensource/lzo/" >&6; } -- as_fn_error $? "Or try ./configure --disable-lzo" "$LINENO" 5 -+ as_fn_error "Or try ./configure --disable-lzo" "$LINENO" 5 - fi - fi - -@@ -7167,7 +7202,7 @@ - if test "x$ac_cv_header_openssl_evp_h" = x""yes; then : - - else -- as_fn_error $? "OpenSSL Crypto headers not found." "$LINENO" 5 -+ as_fn_error "OpenSSL Crypto headers not found." "$LINENO" 5 - fi - - -@@ -7176,7 +7211,7 @@ - as_ac_Lib=`$as_echo "ac_cv_lib_$lib''_EVP_CIPHER_CTX_init" | $as_tr_sh` - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for EVP_CIPHER_CTX_init in -l$lib" >&5 - $as_echo_n "checking for EVP_CIPHER_CTX_init in -l$lib... " >&6; } --if eval "test \"\${$as_ac_Lib+set}\"" = set; then : -+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then : - $as_echo_n "(cached) " >&6 - else - ac_check_lib_save_LIBS=$LIBS -@@ -7211,7 +7246,8 @@ - eval ac_res=\$$as_ac_Lib - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 - $as_echo "$ac_res" >&6; } --if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : -+eval as_val=\$$as_ac_Lib -+ if test "x$as_val" = x""yes; then : - - cryptofound=1 - -@@ -7223,7 +7259,7 @@ - - done - -- test -n "$cryptofound" || as_fn_error $? "OpenSSL Crypto library not found." "$LINENO" 5 -+ test -n "$cryptofound" || as_fn_error "OpenSSL Crypto library not found." "$LINENO" 5 - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking that OpenSSL Library is at least version 0.9.6" >&5 - $as_echo_n "checking that OpenSSL Library is at least version 0.9.6... " >&6; } -@@ -7303,7 +7339,7 @@ - - - else -- as_fn_error $? "OpenSSL crypto Library is too old." "$LINENO" 5 -+ as_fn_error "OpenSSL crypto Library is too old." "$LINENO" 5 - - fi - rm -f conftest* -@@ -7317,7 +7353,7 @@ - if test "x$ac_cv_header_openssl_ssl_h" = x""yes; then : - - else -- as_fn_error $? "OpenSSL SSL headers not found." "$LINENO" 5 -+ as_fn_error "OpenSSL SSL headers not found." "$LINENO" 5 - - fi - -@@ -7327,7 +7363,7 @@ - as_ac_Lib=`$as_echo "ac_cv_lib_$lib''_SSL_CTX_new" | $as_tr_sh` - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSL_CTX_new in -l$lib" >&5 - $as_echo_n "checking for SSL_CTX_new in -l$lib... " >&6; } --if eval "test \"\${$as_ac_Lib+set}\"" = set; then : -+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then : - $as_echo_n "(cached) " >&6 - else - ac_check_lib_save_LIBS=$LIBS -@@ -7362,7 +7398,8 @@ - eval ac_res=\$$as_ac_Lib - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 - $as_echo "$ac_res" >&6; } --if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : -+eval as_val=\$$as_ac_Lib -+ if test "x$as_val" = x""yes; then : - - sslfound=1 - -@@ -7374,7 +7411,7 @@ - - done - -- test -n "${sslfound}" || as_fn_error $? "OpenSSL SSL library not found." "$LINENO" 5 -+ test -n "${sslfound}" || as_fn_error "OpenSSL SSL library not found." "$LINENO" 5 - - if test "$MEMCHECK" = "ssl"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Memory Debugging Capabilities in OpenSSL Library..." >&5 -@@ -7424,7 +7461,7 @@ - $as_echo "NOTE: OpenSSL library must be compiled with CRYPTO_MDEBUG" >&6; } - - else -- as_fn_error $? "Memory Debugging function in OpenSSL library not found." "$LINENO" 5 -+ as_fn_error "Memory Debugging function in OpenSSL library not found." "$LINENO" 5 - - fi - -@@ -7799,7 +7836,6 @@ - - ac_libobjs= - ac_ltlibobjs= --U= - for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue - # 1. Remove the extension, and $U if already installed. - ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' -@@ -7823,15 +7859,15 @@ - fi - - if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then -- as_fn_error $? "conditional \"AMDEP\" was never defined. -+ as_fn_error "conditional \"AMDEP\" was never defined. - Usually this means the macro was only invoked conditionally." "$LINENO" 5 - fi - if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then -- as_fn_error $? "conditional \"am__fastdepCC\" was never defined. -+ as_fn_error "conditional \"am__fastdepCC\" was never defined. - Usually this means the macro was only invoked conditionally." "$LINENO" 5 - fi - if test -z "${WIN32_TRUE}" && test -z "${WIN32_FALSE}"; then -- as_fn_error $? "conditional \"WIN32\" was never defined. -+ as_fn_error "conditional \"WIN32\" was never defined. - Usually this means the macro was only invoked conditionally." "$LINENO" 5 - fi - -@@ -7981,19 +8017,19 @@ - (unset CDPATH) >/dev/null 2>&1 && unset CDPATH - - --# as_fn_error STATUS ERROR [LINENO LOG_FD] --# ---------------------------------------- -+# as_fn_error ERROR [LINENO LOG_FD] -+# --------------------------------- - # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are - # provided, also output the error to LOG_FD, referencing LINENO. Then exit the --# script with STATUS, using 1 if that was 0. -+# script with status $?, using 1 if that was 0. - as_fn_error () - { -- as_status=$1; test $as_status -eq 0 && as_status=1 -- if test "$4"; then -- as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack -- $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 -+ as_status=$?; test $as_status -eq 0 && as_status=1 -+ if test "$3"; then -+ as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack -+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3 - fi -- $as_echo "$as_me: error: $2" >&2 -+ $as_echo "$as_me: error: $1" >&2 - as_fn_exit $as_status - } # as_fn_error - -@@ -8189,7 +8225,7 @@ - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" -- } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" -+ } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir" - - - } # as_fn_mkdir_p -@@ -8368,7 +8404,7 @@ - ac_need_defaults=false;; - --he | --h) - # Conflict between --help and --header -- as_fn_error $? "ambiguous option: \`$1' -+ as_fn_error "ambiguous option: \`$1' - Try \`$0 --help' for more information.";; - --help | --hel | -h ) - $as_echo "$ac_cs_usage"; exit ;; -@@ -8377,7 +8413,7 @@ - ac_cs_silent=: ;; - - # This is an error. -- -*) as_fn_error $? "unrecognized option: \`$1' -+ -*) as_fn_error "unrecognized option: \`$1' - Try \`$0 --help' for more information." ;; - - *) as_fn_append ac_config_targets " $1" -@@ -8441,7 +8477,7 @@ - "install-win32/Makefile") CONFIG_FILES="$CONFIG_FILES install-win32/Makefile" ;; - "install-win32/settings") CONFIG_FILES="$CONFIG_FILES install-win32/settings" ;; - -- *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; -+ *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;; - esac - done - -@@ -8479,7 +8515,7 @@ - { - tmp=./conf$$-$RANDOM - (umask 077 && mkdir "$tmp") --} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 -+} || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5 - - # Set up the scripts for CONFIG_FILES section. - # No need to generate them if there are no CONFIG_FILES. -@@ -8496,7 +8532,7 @@ - fi - ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null` - if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then -- ac_cs_awk_cr='\\r' -+ ac_cs_awk_cr='\r' - else - ac_cs_awk_cr=$ac_cr - fi -@@ -8510,18 +8546,18 @@ - echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && - echo "_ACEOF" - } >conf$$subs.sh || -- as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 --ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` -+ as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 -+ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'` - ac_delim='%!_!# ' - for ac_last_try in false false false false false :; do - . ./conf$$subs.sh || -- as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 -+ as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 - - ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` - if test $ac_delim_n = $ac_delim_num; then - break - elif $ac_last_try; then -- as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 -+ as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -@@ -8610,28 +8646,20 @@ - else - cat - fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ -- || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 -+ || as_fn_error "could not setup config files machinery" "$LINENO" 5 - _ACEOF - --# VPATH may cause trouble with some makes, so we remove sole $(srcdir), --# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and -+# VPATH may cause trouble with some makes, so we remove $(srcdir), -+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and - # trailing colons and then remove the whole line if VPATH becomes empty - # (actually we leave an empty line to preserve line numbers). - if test "x$srcdir" = x.; then -- ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ --h --s/// --s/^/:/ --s/[ ]*$/:/ --s/:\$(srcdir):/:/g --s/:\${srcdir}:/:/g --s/:@srcdir@:/:/g --s/^:*// -+ ac_vpsub='/^[ ]*VPATH[ ]*=/{ -+s/:*\$(srcdir):*/:/ -+s/:*\${srcdir}:*/:/ -+s/:*@srcdir@:*/:/ -+s/^\([^=]*=[ ]*\):*/\1/ - s/:*$// --x --s/\(=[ ]*\).*/\1/ --G --s/\n// - s/^[^=]*=[ ]*$// - }' - fi -@@ -8659,7 +8687,7 @@ - if test -z "$ac_t"; then - break - elif $ac_last_try; then -- as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 -+ as_fn_error "could not make $CONFIG_HEADERS" "$LINENO" 5 - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -@@ -8744,7 +8772,7 @@ - _ACAWK - _ACEOF - cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -- as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 -+ as_fn_error "could not setup config headers machinery" "$LINENO" 5 - fi # test -n "$CONFIG_HEADERS" - - -@@ -8757,7 +8785,7 @@ - esac - case $ac_mode$ac_tag in - :[FHL]*:*);; -- :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; -+ :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;; - :[FH]-) ac_tag=-:-;; - :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; - esac -@@ -8785,7 +8813,7 @@ - [\\/$]*) false;; - *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; - esac || -- as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; -+ as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;; - esac - case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac - as_fn_append ac_file_inputs " '$ac_f'" -@@ -8812,7 +8840,7 @@ - - case $ac_tag in - *:-:* | *:-) cat >"$tmp/stdin" \ -- || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; -+ || as_fn_error "could not create $ac_file" "$LINENO" 5 ;; - esac - ;; - esac -@@ -8949,22 +8977,22 @@ - $ac_datarootdir_hack - " - eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ -- || as_fn_error $? "could not create $ac_file" "$LINENO" 5 -+ || as_fn_error "could not create $ac_file" "$LINENO" 5 - - test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && - { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && - { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' --which seems to be undefined. Please make sure it is defined" >&5 -+which seems to be undefined. Please make sure it is defined." >&5 - $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' --which seems to be undefined. Please make sure it is defined" >&2;} -+which seems to be undefined. Please make sure it is defined." >&2;} - - rm -f "$tmp/stdin" - case $ac_file in - -) cat "$tmp/out" && rm -f "$tmp/out";; - *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; - esac \ -- || as_fn_error $? "could not create $ac_file" "$LINENO" 5 -+ || as_fn_error "could not create $ac_file" "$LINENO" 5 - ;; - :H) - # -@@ -8975,19 +9003,19 @@ - $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" - } >"$tmp/config.h" \ -- || as_fn_error $? "could not create $ac_file" "$LINENO" 5 -+ || as_fn_error "could not create $ac_file" "$LINENO" 5 - if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then - { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 - $as_echo "$as_me: $ac_file is unchanged" >&6;} - else - rm -f "$ac_file" - mv "$tmp/config.h" "$ac_file" \ -- || as_fn_error $? "could not create $ac_file" "$LINENO" 5 -+ || as_fn_error "could not create $ac_file" "$LINENO" 5 - fi - else - $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ -- || as_fn_error $? "could not create -" "$LINENO" 5 -+ || as_fn_error "could not create -" "$LINENO" 5 - fi - # Compute "$ac_file"'s index in $config_headers. - _am_arg="$ac_file" -@@ -9138,7 +9166,7 @@ - ac_clean_files=$ac_clean_files_save - - test $ac_write_fail = 0 || -- as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 -+ as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5 - - - # configure is writing to config.log, and then calls config.status. -@@ -9159,7 +9187,7 @@ - exec 5>>config.log - # Use ||, not &&, to avoid exiting from the if with $? = 1, which - # would make configure fail if this is the last instruction. -- $ac_cs_success || as_fn_exit 1 -+ $ac_cs_success || as_fn_exit $? - fi - if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 -Index: openvpn-2.2.1/configure.ac -=================================================================== ---- openvpn-2.2.1.orig/configure.ac 2011-06-24 08:13:38.000000000 +0200 -+++ openvpn-2.2.1/configure.ac 2011-12-13 12:23:07.348080508 +0100 -@@ -146,6 +146,12 @@ - [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"], -@@ -566,6 +572,16 @@ - 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 -Index: openvpn-2.2.1/init.c -=================================================================== ---- openvpn-2.2.1.orig/init.c 2011-06-24 08:13:38.000000000 +0200 -+++ openvpn-2.2.1/init.c 2011-12-13 12:23:07.351080471 +0100 -@@ -96,7 +96,7 @@ - */ - 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; -@@ -1150,7 +1150,12 @@ - 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); -+ /* TODO(jjo): for ipv6 this will convert some 32bits in the ipv6 addr -+ * to a meaningless ipv4 address. -+ * In any case, is somewhat inconsistent to send local tunnel -+ * addr with remote _endpoint_ 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, -@@ -1566,7 +1571,7 @@ - #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; -@@ -1661,13 +1666,22 @@ - 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; - } -@@ -2807,7 +2821,7 @@ - #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 - { -@@ -3083,7 +3097,11 @@ - /* link_socket_mode allows CM_CHILD_TCP - instances to inherit acceptable fds - from a top-level parent */ -- if (c->options.ce.proto == PROTO_TCPv4_SERVER) -+ if (c->options.ce.proto == PROTO_TCPv4_SERVER -+#ifdef USE_PF_INET6 -+ || c->options.ce.proto == PROTO_TCPv6_SERVER -+#endif -+ ) - { - if (c->mode == CM_TOP) - link_socket_mode = LS_MODE_TCP_LISTEN; -@@ -3358,17 +3376,8 @@ - { - 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 (); - -@@ -3474,7 +3483,7 @@ - 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); - } - -Index: openvpn-2.2.1/manage.c -=================================================================== ---- openvpn-2.2.1.orig/manage.c 2011-06-24 08:13:38.000000000 +0200 -+++ openvpn-2.2.1/manage.c 2011-12-13 12:23:07.354080432 +0100 -@@ -1957,9 +1957,9 @@ - /* - * 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 -@@ -1971,7 +1971,7 @@ - } - 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); - } - } -@@ -2427,7 +2427,7 @@ - && 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); - } - -Index: openvpn-2.2.1/mroute.c -=================================================================== ---- openvpn-2.2.1.orig/mroute.c 2011-06-24 08:13:38.000000000 +0200 -+++ openvpn-2.2.1/mroute.c 2011-12-13 12:23:07.354080432 +0100 -@@ -226,25 +226,47 @@ - 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; - } - -Index: openvpn-2.2.1/mtcp.c -=================================================================== ---- openvpn-2.2.1.orig/mtcp.c 2011-06-24 08:13:38.000000000 +0200 -+++ openvpn-2.2.1/mtcp.c 2011-12-13 12:23:07.358080384 +0100 -@@ -150,6 +150,11 @@ - 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 -+#ifdef USE_PF_INET6 -+ || mi->context.c2.link_socket->info.lsa->actual.dest.addr.sa.sa_family == AF_INET6 -+#endif -+ ); - 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"); -Index: openvpn-2.2.1/multi.c -=================================================================== ---- openvpn-2.2.1.orig/multi.c 2011-06-24 08:13:39.000000000 +0200 -+++ openvpn-2.2.1/multi.c 2011-12-13 12:23:07.359080371 +0100 -@@ -1058,8 +1058,8 @@ - struct mroute_addr addr; - - CLEAR (remote_si); -- remote_si.sa.sin_family = AF_INET; -- remote_si.sa.sin_addr.s_addr = htonl (a); -+ remote_si.addr.in4.sin_family = AF_INET; -+ remote_si.addr.in4.sin_addr.s_addr = htonl (a); - ASSERT (mroute_extract_openvpn_sockaddr (&addr, &remote_si, false)); - - if (netbits >= 0) -@@ -2496,9 +2496,9 @@ - int count = 0; - - CLEAR (saddr); -- saddr.sa.sin_family = AF_INET; -- saddr.sa.sin_addr.s_addr = htonl (addr); -- saddr.sa.sin_port = htons (port); -+ saddr.addr.in4.sin_family = AF_INET; -+ saddr.addr.in4.sin_addr.s_addr = htonl (addr); -+ saddr.addr.in4.sin_port = htons (port); - if (mroute_extract_openvpn_sockaddr (&maddr, &saddr, true)) - { - hash_iterator_init (m->iter, &hi); -@@ -2675,16 +2675,24 @@ - { - ASSERT (top->options.mode == MODE_SERVER); - -- switch (top->options.ce.proto) { -- case PROTO_UDPv4: -- tunnel_server_udp (top); -- break; -- case PROTO_TCPv4_SERVER: -- tunnel_server_tcp (top); -- break; -- default: -- ASSERT (0); -- } -+#ifdef USE_PF_INET6 -+ if (proto_is_dgram(top->options.ce.proto)) -+ tunnel_server_udp(top); -+ else -+ tunnel_server_tcp(top); -+#else -+ switch (top->options.ce.proto) -+ { -+ case PROTO_UDPv4: -+ tunnel_server_udp (top); -+ break; -+ case PROTO_TCPv4_SERVER: -+ tunnel_server_tcp (top); -+ break; -+ default: -+ ASSERT (0); -+ } -+#endif - } - - #else -Index: openvpn-2.2.1/occ.c -=================================================================== ---- openvpn-2.2.1.orig/occ.c 2011-06-24 08:13:39.000000000 +0200 -+++ openvpn-2.2.1/occ.c 2011-12-13 12:23:07.362080332 +0100 -@@ -369,7 +369,7 @@ - c->c2.max_send_size_remote, - c->c2.max_recv_size_local); - if (!c->options.fragment -- && c->options.ce.proto == PROTO_UDPv4 -+ && (proto_is_dgram(c->options.ce.proto)) - && c->c2.max_send_size_local > TUN_MTU_MIN - && (c->c2.max_recv_size_remote < c->c2.max_send_size_local - || c->c2.max_recv_size_local < c->c2.max_send_size_remote)) -Index: openvpn-2.2.1/openvpn.8 -=================================================================== ---- openvpn-2.2.1.orig/openvpn.8 2011-06-24 08:13:39.000000000 +0200 -+++ openvpn-2.2.1/openvpn.8 2011-12-13 12:23:07.367080271 +0100 -@@ -5463,13 +5463,16 @@ - script execution. - .\"********************************************************* - .TP --.B trusted_ip -+.B trusted_ip (or trusted_ip6) - Actual IP address of connecting client or peer which has been authenticated. - Set prior to execution of - .B \-\-ipchange, \-\-client-connect, - and - .B \-\-client-disconnect - scripts. -+If using ipv6 endpoints (udp6, tcp6), -+.B trusted_ip6 -+will be set instead. - .\"********************************************************* - .TP - .B trusted_port -@@ -5481,7 +5484,7 @@ - scripts. - .\"********************************************************* - .TP --.B untrusted_ip -+.B untrusted_ip (or untrusted_ip6) - Actual IP address of connecting client or peer which has not been authenticated - yet. Sometimes used to - .B nmap -@@ -5493,6 +5496,9 @@ - and - .B \-\-auth-user-pass-verify - scripts. -+If using ipv6 endpoints (udp6, tcp6), -+.B untrusted_ip6 -+will be set instead. - .\"********************************************************* - .TP - .B untrusted_port -Index: openvpn-2.2.1/options.c -=================================================================== ---- openvpn-2.2.1.orig/options.c 2011-12-13 12:22:25.000000000 +0100 -+++ openvpn-2.2.1/options.c 2011-12-13 12:23:07.374080184 +0100 -@@ -79,6 +79,12 @@ - #ifdef ENABLE_EUREPHIA - " [eurephia]" - #endif -+#if ENABLE_IP_PKTINFO -+ " [MH]" -+#endif -+#ifdef USE_PF_INET6 -+ " [PF_INET6]" -+#endif - " built on " __DATE__ - ; - -@@ -101,6 +107,9 @@ - "--proto p : Use protocol p for communicating with peer.\n" - " p = udp (default), tcp-server, or tcp-client\n" - "--proto-force p : only consider protocol p in list of connection profiles.\n" -+#ifdef USE_PF_INET6 -+ " p = udp6, tcp6-server, or tcp6-client (ipv6)\n" -+#endif - "--connect-retry n : For --proto tcp-client, number of seconds to wait\n" - " between connection retries (default=%d).\n" - "--connect-timeout n : For --proto tcp-client, connection timeout (in seconds).\n" -@@ -1707,11 +1716,27 @@ - * Sanity check on TCP mode options - */ - -- if (ce->connect_retry_defined && ce->proto != PROTO_TCPv4_CLIENT) -- msg (M_USAGE, "--connect-retry doesn't make sense unless also used with --proto tcp-client"); -- -- if (ce->connect_timeout_defined && ce->proto != PROTO_TCPv4_CLIENT) -- msg (M_USAGE, "--connect-timeout doesn't make sense unless also used with --proto tcp-client"); -+ if (ce->connect_retry_defined && ce->proto != PROTO_TCPv4_CLIENT -+#ifdef USE_PF_INET6 -+ && ce->proto != PROTO_TCPv6_CLIENT -+#endif -+ ) -+ msg (M_USAGE, "--connect-retry doesn't make sense unless also used with --proto tcp-client" -+#ifdef USE_PF_INET6 -+ " or tcp6-client" -+#endif -+ ); -+ -+ if (ce->connect_timeout_defined && ce->proto != PROTO_TCPv4_CLIENT -+#ifdef USE_PF_INET6 -+ && ce->proto != PROTO_TCPv6_CLIENT -+#endif -+ ) -+ msg (M_USAGE, "--connect-timeout doesn't make sense unless also used with --proto tcp-client" -+#ifdef USE_PF_INET6 -+ " or tcp6-client" -+#endif -+ ); - - /* - * Sanity check on MTU parameters -@@ -1720,7 +1745,7 @@ - msg (M_USAGE, "only one of --tun-mtu or --link-mtu may be defined (note that --ifconfig implies --link-mtu %d)", LINK_MTU_DEFAULT); - - #ifdef ENABLE_OCC -- if (ce->proto != PROTO_UDPv4 && options->mtu_test) -+ if (!proto_is_udp(ce->proto) && options->mtu_test) - msg (M_USAGE, "--mtu-test only makes sense with --proto udp"); - #endif - -@@ -1733,7 +1758,8 @@ - * Sanity check on --local, --remote, and --ifconfig - */ - -- if (string_defined_equal (ce->local, ce->remote) -+ if (proto_is_net(ce->proto) -+ && string_defined_equal (ce->local, ce->remote) - && ce->local_port == ce->remote_port) - msg (M_USAGE, "--remote and --local addresses are the same"); - -@@ -1798,16 +1824,20 @@ - */ - - #ifdef ENABLE_FRAGMENT -- if (ce->proto != PROTO_UDPv4 && options->fragment) -+ if (!proto_is_udp(ce->proto) && options->fragment) - msg (M_USAGE, "--fragment can only be used with --proto udp"); - #endif - - #ifdef ENABLE_OCC -- if (ce->proto != PROTO_UDPv4 && options->explicit_exit_notification) -+ if (!proto_is_udp(ce->proto) && options->explicit_exit_notification) - msg (M_USAGE, "--explicit-exit-notify can only be used with --proto udp"); - #endif - -- if (!ce->remote && ce->proto == PROTO_TCPv4_CLIENT) -+ if (!ce->remote && (ce->proto == PROTO_TCPv4_CLIENT -+#ifdef USE_PF_INET6 -+ || ce->proto == PROTO_TCPv6_CLIENT -+#endif -+ )) - msg (M_USAGE, "--remote MUST be used in TCP Client mode"); - - #ifdef ENABLE_HTTP_PROXY -@@ -1825,7 +1855,12 @@ - msg (M_USAGE, "--socks-proxy can not be used in TCP Server mode"); - #endif - -- if (ce->proto == PROTO_TCPv4_SERVER && connection_list_defined (options)) -+ if ((ce->proto == PROTO_TCPv4_SERVER -+#ifdef USE_PF_INET6 -+ || ce->proto == PROTO_TCPv6_SERVER -+#endif -+ ) -+ && connection_list_defined (options)) - msg (M_USAGE, "TCP server mode allows at most one --remote address"); - - #if P2MP_SERVER -@@ -1839,11 +1874,28 @@ - msg (M_USAGE, "--mode server only works with --dev tun or --dev tap"); - if (options->pull) - msg (M_USAGE, "--pull cannot be used with --mode server"); -- if (!(ce->proto == PROTO_UDPv4 || ce->proto == PROTO_TCPv4_SERVER)) -- msg (M_USAGE, "--mode server currently only supports --proto udp or --proto tcp-server"); -+ if (!(proto_is_udp(ce->proto) || ce->proto == PROTO_TCPv4_SERVER -+#ifdef USE_PF_INET6 -+ || ce->proto == PROTO_TCPv6_SERVER -+#endif -+ )) -+ msg (M_USAGE, "--mode server currently only supports --proto udp or --proto tcp-server" -+#ifdef USE_PF_INET6 -+ " or proto tcp6-server" -+#endif -+ ); - #if PORT_SHARE -- if ((options->port_share_host || options->port_share_port) && ce->proto != PROTO_TCPv4_SERVER) -- msg (M_USAGE, "--port-share only works in TCP server mode (--proto tcp-server)"); -+ if ((options->port_share_host || options->port_share_port) && -+ (ce->proto != PROTO_TCPv4_SERVER -+#ifdef USE_PF_INET6 -+ && ce->proto != PROTO_TCPv6_SERVER -+#endif -+ )) -+ msg (M_USAGE, "--port-share only works in TCP server mode (--proto tcp-server" -+#ifdef USE_PF_INET6 -+ " or tcp6-server" -+#endif -+ ")"); - #endif - if (!options->tls_server) - msg (M_USAGE, "--mode server requires --tls-server"); -@@ -1871,9 +1923,17 @@ - msg (M_USAGE, "--inetd cannot be used with --mode server"); - if (options->ipchange) - msg (M_USAGE, "--ipchange cannot be used with --mode server (use --client-connect instead)"); -- if (!(ce->proto == PROTO_UDPv4 || ce->proto == PROTO_TCPv4_SERVER)) -- msg (M_USAGE, "--mode server currently only supports --proto udp or --proto tcp-server"); -- if (ce->proto != PROTO_UDPv4 && (options->cf_max || options->cf_per)) -+ if (!(proto_is_dgram(ce->proto) || ce->proto == PROTO_TCPv4_SERVER -+#ifdef USE_PF_INET6 -+ || ce->proto == PROTO_TCPv6_SERVER -+#endif -+ )) -+ msg (M_USAGE, "--mode server currently only supports --proto udp or --proto tcp-server" -+#ifdef USE_PF_INET6 -+ " or --proto tcp6-server" -+#endif -+ ); -+ if (!proto_is_udp(ce->proto) && (options->cf_max || options->cf_per)) - msg (M_USAGE, "--connect-freq only works with --mode server --proto udp. Try --max-clients instead."); - if (!(dev == DEV_TYPE_TAP || (dev == DEV_TYPE_TUN && options->topology == TOP_SUBNET)) && options->ifconfig_pool_netmask) - msg (M_USAGE, "The third parameter to --ifconfig-pool (netmask) is only valid in --dev tap mode"); -@@ -1964,7 +2024,7 @@ - /* - * Check consistency of replay options - */ -- if ((ce->proto != PROTO_UDPv4) -+ if ((!proto_is_udp(ce->proto)) - && (options->replay_window != defaults.replay_window - || options->replay_time != defaults.replay_time)) - msg (M_USAGE, "--replay-window only makes sense with --proto udp"); -@@ -2137,6 +2197,10 @@ - { - if (ce->proto == PROTO_TCPv4) - ce->proto = PROTO_TCPv4_CLIENT; -+#ifdef USE_PF_INET6 -+ else if (ce->proto == PROTO_TCPv6) -+ ce->proto = PROTO_TCPv6_CLIENT; -+#endif - } - #endif - -Index: openvpn-2.2.1/ps.c -=================================================================== ---- openvpn-2.2.1.orig/ps.c 2011-06-24 08:13:39.000000000 +0200 -+++ openvpn-2.2.1/ps.c 2011-12-13 12:23:07.375080171 +0100 -@@ -320,9 +320,9 @@ - const int port) - { - CLEAR (*osaddr); -- osaddr->sa.sin_family = AF_INET; -- osaddr->sa.sin_addr.s_addr = htonl (addr); -- osaddr->sa.sin_port = htons (port); -+ osaddr->addr.in4.sin_family = AF_INET; -+ osaddr->addr.in4.sin_addr.s_addr = htonl (addr); -+ osaddr->addr.in4.sin_port = htons (port); - } - - static inline void -Index: openvpn-2.2.1/route.c -=================================================================== ---- openvpn-2.2.1.orig/route.c 2011-06-24 08:13:39.000000000 +0200 -+++ openvpn-2.2.1/route.c 2011-12-13 12:23:07.377080145 +0100 -@@ -581,13 +581,23 @@ - if (!local) - { - /* route remote host to original default gateway */ -- add_route3 (rl->spec.remote_host, -- ~0, -- rl->spec.net_gateway, -- tt, -- flags, -- es); -- rl->did_local = true; -+#ifdef USE_PF_INET6 -+ /* if remote_host is not ipv4 (ie: ipv6), just skip -+ * adding this special /32 route */ -+ if (rl->spec.remote_host != IPV4_INVALID_ADDR) { -+#endif -+ add_route3 (rl->spec.remote_host, -+ ~0, -+ rl->spec.net_gateway, -+ tt, -+ flags, -+ es); -+ rl->did_local = true; -+#ifdef USE_PF_INET6 -+ } else { -+ dmsg (D_ROUTE, "ROUTE remote_host protocol differs from tunneled"); -+ } -+#endif - } - - /* route DHCP/DNS server traffic through original default gateway */ -Index: openvpn-2.2.1/socket.c -=================================================================== ---- openvpn-2.2.1.orig/socket.c 2011-12-13 12:22:23.000000000 +0100 -+++ openvpn-2.2.1/socket.c 2011-12-13 12:23:07.381080096 +0100 -@@ -36,10 +36,16 @@ - #include "memdbg.h" - - const int proto_overhead[] = { /* indexed by PROTO_x */ -- IPv4_UDP_HEADER_SIZE, -+ 0, -+ IPv4_UDP_HEADER_SIZE, /* IPv4 */ - IPv4_TCP_HEADER_SIZE, - IPv4_TCP_HEADER_SIZE, -- IPv4_TCP_HEADER_SIZE -+#ifdef USE_PF_INET6 -+ IPv6_UDP_HEADER_SIZE, /* IPv6 */ -+ IPv6_TCP_HEADER_SIZE, -+ IPv6_TCP_HEADER_SIZE, -+ IPv6_TCP_HEADER_SIZE, -+#endif - }; - - /* -@@ -276,6 +282,201 @@ - return (flags & GETADDR_HOST_ORDER) ? ntohl (ia.s_addr) : ia.s_addr; - } - -+#ifdef USE_PF_INET6 -+/* -+ * Translate IPv6 addr or hostname into struct addrinfo -+ * If resolve error, try again for -+ * resolve_retry_seconds seconds. -+ */ -+bool -+getaddr6 (unsigned int flags, -+ const char *hostname, -+ int resolve_retry_seconds, -+ volatile int *signal_received, -+ int *gai_err, -+ struct sockaddr_in6 *in6) -+{ -+ bool success; -+ struct addrinfo hints, *ai; -+ int status; -+ int sigrec = 0; -+ int msglevel = (flags & GETADDR_FATAL) ? M_FATAL : D_RESOLVE_ERRORS; -+ struct gc_arena gc = gc_new (); -+ -+ ASSERT(in6); -+ -+ if (!hostname) -+ hostname = "::"; -+ -+ if (flags & GETADDR_RANDOMIZE) -+ hostname = hostname_randomize(hostname, &gc); -+ -+ if (flags & GETADDR_MSG_VIRT_OUT) -+ msglevel |= M_MSG_VIRT_OUT; -+ -+ CLEAR (ai); -+ success = false; -+ -+ if ((flags & (GETADDR_FATAL_ON_SIGNAL|GETADDR_WARN_ON_SIGNAL)) -+ && !signal_received) -+ signal_received = &sigrec; -+ -+ /* try numeric ipv6 addr first */ -+ CLEAR(hints); -+ hints.ai_family = AF_INET6; -+ hints.ai_flags = AI_NUMERICHOST; -+ if ((status = getaddrinfo(hostname, NULL, &hints, &ai))==0) -+ { -+ *in6 = *((struct sockaddr_in6 *)(ai->ai_addr)); -+ freeaddrinfo(ai); -+ ai = NULL; -+ } -+ if (gai_err) -+ *gai_err = status; -+ -+ -+ if (status != 0) /* parse as IPv6 address failed? */ -+ { -+ const int fail_wait_interval = 5; /* seconds */ -+ int resolve_retries = (flags & GETADDR_TRY_ONCE) ? 1 : (resolve_retry_seconds / fail_wait_interval); -+ const char *fmt; -+ int level = 0; -+ int err; -+ -+ ai = NULL; -+ -+ fmt = "RESOLVE: Cannot resolve host address: %s: %s"; -+ if ((flags & GETADDR_MENTION_RESOLVE_RETRY) -+ && !resolve_retry_seconds) -+ fmt = "RESOLVE: Cannot resolve host address: %s: %s (I would have retried this name query if you had specified the --resolv-retry option.)"; -+ -+ if (!(flags & GETADDR_RESOLVE) || status == EAI_FAIL) -+ { -+ msg (msglevel, "RESOLVE: Cannot parse IPv6 address: %s", hostname); -+ goto done; -+ } -+ -+#ifdef ENABLE_MANAGEMENT -+ if (flags & GETADDR_UPDATE_MANAGEMENT_STATE) -+ { -+ if (management) -+ management_set_state (management, -+ OPENVPN_STATE_RESOLVE, -+ NULL, -+ (in_addr_t)0, -+ (in_addr_t)0); -+ } -+#endif -+ -+ /* -+ * Resolve hostname -+ */ -+ while (true) -+ { -+ /* try hostname lookup */ -+ hints.ai_flags = 0; -+ hints.ai_socktype = dnsflags_to_socktype(flags); -+ dmsg (D_SOCKET_DEBUG, "GETADDR6 flags=0x%04x ai_family=%d ai_socktype=%d", -+ flags, hints.ai_family, hints.ai_socktype); -+ err = getaddrinfo(hostname, NULL, &hints, &ai); -+ -+ if (gai_err) -+ *gai_err = err; -+ -+ if (signal_received) -+ { -+ get_signal (signal_received); -+ if (*signal_received) /* were we interrupted by a signal? */ -+ { -+ if (0 == err) { -+ ASSERT(ai); -+ freeaddrinfo(ai); -+ ai = NULL; -+ } -+ if (*signal_received == SIGUSR1) /* ignore SIGUSR1 */ -+ { -+ msg (level, "RESOLVE: Ignored SIGUSR1 signal received during DNS resolution attempt"); -+ *signal_received = 0; -+ } -+ else -+ goto done; -+ } -+ } -+ -+ /* success? */ -+ if (0 == err) -+ break; -+ -+ /* resolve lookup failed, should we -+ continue or fail? */ -+ -+ level = msglevel; -+ if (resolve_retries > 0) -+ level = D_RESOLVE_ERRORS; -+ -+ msg (level, -+ fmt, -+ hostname, -+ gai_strerror(err)); -+ -+ if (--resolve_retries <= 0) -+ goto done; -+ -+ openvpn_sleep (fail_wait_interval); -+ } -+ -+ ASSERT(ai); -+ -+ if (!ai->ai_next) -+ *in6 = *((struct sockaddr_in6*)(ai->ai_addr)); -+ else -+ /* more than one address returned */ -+ { -+ struct addrinfo *ai_cursor; -+ int n = 0; -+ /* count address list */ -+ for (ai_cursor = ai; ai_cursor; ai_cursor = ai_cursor->ai_next) n++; -+ ASSERT (n >= 2); -+ -+ msg (D_RESOLVE_ERRORS, "RESOLVE: NOTE: %s resolves to %d ipv6 addresses, choosing one by random", -+ hostname, -+ n); -+ -+ /* choose address randomly, for basic load-balancing capability */ -+ n--; -+ n %= get_random(); -+ for (ai_cursor = ai; n; ai_cursor = ai_cursor->ai_next) n--; -+ *in6 = *((struct sockaddr_in6*)(ai_cursor->ai_addr)); -+ } -+ -+ freeaddrinfo(ai); -+ ai = NULL; -+ -+ /* hostname resolve succeeded */ -+ success = true; -+ } -+ else -+ { -+ /* IP address parse succeeded */ -+ success = true; -+ } -+ -+ done: -+ if (signal_received && *signal_received) -+ { -+ int level = 0; -+ if (flags & GETADDR_FATAL_ON_SIGNAL) -+ level = M_FATAL; -+ else if (flags & GETADDR_WARN_ON_SIGNAL) -+ level = M_WARN; -+ msg (level, "RESOLVE: signal received during DNS resolution attempt"); -+ } -+ -+ gc_free (&gc); -+ return success; -+} -+#endif /* USE_PF_INET6 */ -+ - /* - * We do our own inet_aton because the glibc function - * isn't very good about error checking. -@@ -410,20 +611,53 @@ - bool *changed, - const unsigned int sockflags) - { -- if (host && addr) -+ switch(addr->addr.sa.sa_family) - { -- const in_addr_t new_addr = getaddr ( -- sf2gaf(GETADDR_RESOLVE|GETADDR_UPDATE_MANAGEMENT_STATE, sockflags), -- host, -- 1, -- NULL, -- NULL); -- if (new_addr && addr->sa.sin_addr.s_addr != new_addr) -+ case AF_INET: -+ if (host && addr) - { -- addr->sa.sin_addr.s_addr = new_addr; -- *changed = true; -+ const in_addr_t new_addr = getaddr ( -+ sf2gaf(GETADDR_RESOLVE|GETADDR_UPDATE_MANAGEMENT_STATE, sockflags), -+ host, -+ 1, -+ NULL, -+ NULL); -+ if (new_addr && addr->addr.in4.sin_addr.s_addr != new_addr) -+ { -+ addr->addr.in4.sin_addr.s_addr = new_addr; -+ *changed = true; -+ } - } -- } -+ break; -+#ifdef USE_PF_INET6 -+ case AF_INET6: -+ if (host && addr) -+ { -+ struct sockaddr_in6 sin6; -+ CLEAR(sin6); -+ int success = getaddr6 ( -+ sf2gaf(GETADDR_RESOLVE|GETADDR_UPDATE_MANAGEMENT_STATE, sockflags), -+ host, -+ 1, -+ NULL, -+ NULL, -+ &sin6); -+ if ( success ) -+ { -+ if (!IN6_ARE_ADDR_EQUAL(&sin6.sin6_addr, &addr->addr.in6.sin6_addr)) -+ { -+ int port = addr->addr.in6.sin6_port; -+ /* ipv6 requires also eg. sin6_scope_id => easier to fully copy and override port */ -+ addr->addr.in6 = sin6; -+ addr->addr.in6.sin6_port = port; -+ } -+ } -+ } -+ break; -+#endif -+ default: -+ ASSERT(0); -+ } - } - - static int -@@ -610,12 +844,62 @@ - else if (flags & SF_USE_IP_PKTINFO) - { - int pad = 1; -- setsockopt (sd, SOL_IP, IP_PKTINFO, (void*)&pad, sizeof(pad)); -+#ifdef IP_PKTINFO -+ if (setsockopt (sd, SOL_IP, IP_PKTINFO, -+ (void*)&pad, sizeof(pad)) < 0) -+ msg(M_SOCKERR, "UDP: failed setsockopt for IP_PKTINFO"); -+#elif defined(IP_RECVDSTADDR) -+ if (setsockopt (sd, IPPROTO_IP, IP_RECVDSTADDR, -+ (void*)&pad, sizeof(pad)) < 0) -+ msg(M_SOCKERR, "UDP: failed setsockopt for IP_RECVDSTADDR"); -+#else -+#error ENABLE_IP_PKTINFO is set without IP_PKTINFO xor IP_RECVDSTADDR (fix syshead.h) -+#endif -+ } -+#endif -+ return sd; -+} -+ -+#ifdef USE_PF_INET6 -+static socket_descriptor_t -+create_socket_udp6 (const unsigned int flags) -+{ -+ socket_descriptor_t sd; -+ -+ if ((sd = socket (PF_INET6, SOCK_DGRAM, IPPROTO_UDP)) < 0) -+ msg (M_SOCKERR, "UDP: Cannot create UDP6 socket"); -+#if ENABLE_IP_PKTINFO -+ else if (flags & SF_USE_IP_PKTINFO) -+ { -+ int pad = 1; -+ if (setsockopt (sd, IPPROTO_IPV6, IPV6_RECVPKTINFO, -+ (void*)&pad, sizeof(pad)) < 0) -+ msg(M_SOCKERR, "UDP: failed setsockopt for IPV6_RECVPKTINFO"); - } - #endif - return sd; - } - -+static socket_descriptor_t -+create_socket_tcp6 (void) -+{ -+ socket_descriptor_t sd; -+ -+ if ((sd = socket (PF_INET6, SOCK_STREAM, IPPROTO_TCP)) < 0) -+ msg (M_SOCKERR, "Cannot create TCP6 socket"); -+ -+ /* set SO_REUSEADDR on socket */ -+ { -+ int on = 1; -+ if (setsockopt (sd, SOL_SOCKET, SO_REUSEADDR, -+ (void *) &on, sizeof (on)) < 0) -+ msg (M_SOCKERR, "TCP: Cannot setsockopt SO_REUSEADDR on TCP6 socket"); -+ } -+ -+ return sd; -+} -+ -+#endif - static void - create_socket (struct link_socket *sock) - { -@@ -623,6 +907,7 @@ - if (sock->info.proto == PROTO_UDPv4) - { - sock->sd = create_socket_udp (sock->sockflags); -+ sock->sockflags |= SF_GETADDRINFO_DGRAM; - - #ifdef ENABLE_SOCKS - if (sock->socks_proxy) -@@ -634,6 +919,18 @@ - { - sock->sd = create_socket_tcp (); - } -+#ifdef USE_PF_INET6 -+ else if (sock->info.proto == PROTO_TCPv6_SERVER -+ || sock->info.proto == PROTO_TCPv6_CLIENT) -+ { -+ sock->sd = create_socket_tcp6 (); -+ } -+ else if (sock->info.proto == PROTO_UDPv6) -+ { -+ sock->sd = create_socket_udp6 (sock->sockflags); -+ sock->sockflags |= SF_GETADDRINFO_DGRAM; -+ } -+#endif - else - { - ASSERT (0); -@@ -671,7 +968,12 @@ - struct link_socket_actual *act, - const bool nowait) - { -- socklen_t remote_len = sizeof (act->dest.sa); -+ /* af_addr_size WILL return 0 in this case if AFs other than AF_INET -+ * are compiled because act is empty here. -+ * could use getsockname() to support later remote_len check -+ */ -+ socklen_t remote_len_af = af_addr_size(act->dest.addr.sa.sa_family); -+ socklen_t remote_len = sizeof(act->dest.addr); - socket_descriptor_t new_sd = SOCKET_UNDEFINED; - - CLEAR (*act); -@@ -679,7 +981,7 @@ - #ifdef HAVE_GETPEERNAME - if (nowait) - { -- new_sd = getpeername (sd, (struct sockaddr *) &act->dest.sa, &remote_len); -+ new_sd = getpeername (sd, &act->dest.addr.sa, &remote_len); - - if (!socket_defined (new_sd)) - msg (D_LINK_ERRORS | M_ERRNO_SOCK, "TCP: getpeername() failed"); -@@ -692,7 +994,7 @@ - #endif - else - { -- new_sd = accept (sd, (struct sockaddr *) &act->dest.sa, &remote_len); -+ new_sd = accept (sd, &act->dest.addr.sa, &remote_len); - } - - #if 0 /* For debugging only, test the effect of accept() failures */ -@@ -708,7 +1010,8 @@ - { - msg (D_LINK_ERRORS | M_ERRNO_SOCK, "TCP: accept(%d) failed", sd); - } -- else if (remote_len != sizeof (act->dest.sa)) -+ /* only valid if we have remote_len_af!=0 */ -+ else if (remote_len_af && remote_len != remote_len_af) - { - msg (D_LINK_ERRORS, "TCP: Received strange incoming connection with unknown address length=%d", remote_len); - openvpn_close_socket (new_sd); -@@ -809,7 +1112,7 @@ - { - struct gc_arena gc = gc_new (); - -- if (bind (sd, (struct sockaddr *) &local->sa, sizeof (local->sa))) -+ if (bind (sd, &local->addr.sa, af_addr_size(local->addr.sa.sa_family))) - { - const int errnum = openvpn_errno_socket (); - msg (M_FATAL, "%s: Socket bind failed on local address %s: %s", -@@ -830,7 +1133,7 @@ - - #ifdef CONNECT_NONBLOCK - set_nonblock (sd); -- status = connect (sd, (struct sockaddr *) &remote->sa, sizeof (remote->sa)); -+ status = connect (sd, &remote->addr.sa, af_addr_size(remote->addr.sa.sa_family)); - if (status) - status = openvpn_errno_socket (); - if (status == EINPROGRESS) -@@ -888,7 +1191,7 @@ - } - } - #else -- status = connect (sd, (struct sockaddr *) &remote->sa, sizeof (remote->sa)); -+ status = connect (sd, &remote->addr.sa, af_addr_size(remote->addr.sa.sa_family)); - if (status) - status = openvpn_errno_socket (); - #endif -@@ -966,7 +1269,20 @@ - if (*signal_received) - goto done; - -- *sd = create_socket_tcp (); -+#ifdef USE_PF_INET6 -+ switch(local->addr.sa.sa_family) -+ { -+ case PF_INET6: -+ *sd = create_socket_tcp6 (); -+ break; -+ case PF_INET: -+#endif -+ *sd = create_socket_tcp (); -+#ifdef USE_PF_INET6 -+ break; -+ } -+#endif -+ - if (bind_local) - socket_bind (*sd, local, "TCP Client"); - update_remote (remote_dynamic, remote, remote_changed, sockflags); -@@ -1031,15 +1347,54 @@ - /* resolve local address if undefined */ - if (!addr_defined (&sock->info.lsa->local)) - { -- sock->info.lsa->local.sa.sin_family = AF_INET; -- sock->info.lsa->local.sa.sin_addr.s_addr = -- (sock->local_host ? getaddr (GETADDR_RESOLVE | GETADDR_WARN_ON_SIGNAL | GETADDR_FATAL, -+#ifdef USE_PF_INET6 -+ /* may return AF_{INET|INET6} guessed from local_host */ -+ switch(addr_guess_family(sock->info.proto, sock->local_host)) -+ { -+ case AF_INET: -+#endif -+ sock->info.lsa->local.addr.in4.sin_family = AF_INET; -+ sock->info.lsa->local.addr.in4.sin_addr.s_addr = -+ (sock->local_host ? getaddr (GETADDR_RESOLVE | GETADDR_WARN_ON_SIGNAL | GETADDR_FATAL, -+ sock->local_host, -+ 0, -+ NULL, -+ NULL) -+ : htonl (INADDR_ANY)); -+ sock->info.lsa->local.addr.in4.sin_port = htons (sock->local_port); -+#ifdef USE_PF_INET6 -+ break; -+ case AF_INET6: -+ { -+ int success; -+ int err; -+ CLEAR(sock->info.lsa->local.addr.in6); -+ if (sock->local_host) -+ { -+ success = getaddr6(GETADDR_RESOLVE | GETADDR_WARN_ON_SIGNAL | GETADDR_FATAL, - sock->local_host, - 0, - NULL, -- NULL) -- : htonl (INADDR_ANY)); -- sock->info.lsa->local.sa.sin_port = htons (sock->local_port); -+ &err, -+ &sock->info.lsa->local.addr.in6); -+ } -+ else -+ { -+ sock->info.lsa->local.addr.in6.sin6_family = AF_INET6; -+ sock->info.lsa->local.addr.in6.sin6_addr = in6addr_any; -+ success = true; -+ } -+ if (!success) -+ { -+ msg (M_FATAL, "getaddr6() failed for local \"%s\": %s", -+ sock->local_host, -+ gai_strerror(err)); -+ } -+ sock->info.lsa->local.addr.in6.sin6_port = htons (sock->local_port); -+ } -+ break; -+ } -+#endif /* USE_PF_INET6 */ - } - - /* bind to local address/port */ -@@ -1062,14 +1417,32 @@ - volatile int *signal_received) - { - struct gc_arena gc = gc_new (); -+#ifdef USE_PF_INET6 -+ int af; -+#endif - - if (!sock->did_resolve_remote) - { - /* resolve remote address if undefined */ - if (!addr_defined (&sock->info.lsa->remote)) - { -- sock->info.lsa->remote.sa.sin_family = AF_INET; -- sock->info.lsa->remote.sa.sin_addr.s_addr = 0; -+#ifdef USE_PF_INET6 -+ af = addr_guess_family(sock->info.proto, sock->remote_host); -+ switch(af) -+ { -+ case AF_INET: -+#endif -+ sock->info.lsa->remote.addr.in4.sin_family = AF_INET; -+ sock->info.lsa->remote.addr.in4.sin_addr.s_addr = 0; -+#ifdef USE_PF_INET6 -+ break; -+ case AF_INET6: -+ CLEAR(sock->info.lsa->remote.addr.in6); -+ sock->info.lsa->remote.addr.in6.sin6_family = AF_INET6; -+ sock->info.lsa->remote.addr.in6.sin6_addr = in6addr_any; -+ break; -+ } -+#endif - - if (sock->remote_host) - { -@@ -1112,13 +1485,31 @@ - ASSERT (0); - } - -- sock->info.lsa->remote.sa.sin_addr.s_addr = getaddr ( -- flags, -- sock->remote_host, -- retry, -- &status, -- signal_received); -- -+#ifdef USE_PF_INET6 -+ switch(af) -+ { -+ case AF_INET: -+#endif -+ sock->info.lsa->remote.addr.in4.sin_addr.s_addr = getaddr ( -+ flags, -+ sock->remote_host, -+ retry, -+ &status, -+ signal_received); -+#ifdef USE_PF_INET6 -+ break; -+ case AF_INET6: -+ status = getaddr6 ( -+ flags, -+ sock->remote_host, -+ retry, -+ signal_received, -+ NULL, -+ &sock->info.lsa->remote.addr.in6); -+ break; -+ } -+#endif -+ - dmsg (D_SOCKET_DEBUG, "RESOLVE_REMOTE flags=0x%04x phase=%d rrs=%d sig=%d status=%d", - flags, - phase, -@@ -1138,8 +1529,19 @@ - goto done; - } - } -- -- sock->info.lsa->remote.sa.sin_port = htons (sock->remote_port); -+#ifdef USE_PF_INET6 -+ switch(af) -+ { -+ case AF_INET: -+#endif -+ sock->info.lsa->remote.addr.in4.sin_port = htons (sock->remote_port); -+#ifdef USE_PF_INET6 -+ break; -+ case AF_INET6: -+ sock->info.lsa->remote.addr.in6.sin6_port = htons (sock->remote_port); -+ break; -+ } -+#endif - } - - /* should we re-use previous active remote address? */ -@@ -1256,7 +1658,11 @@ - if (mode == LS_MODE_TCP_ACCEPT_FROM) - { - ASSERT (accept_from); -- ASSERT (sock->info.proto == PROTO_TCPv4_SERVER); -+ ASSERT (sock->info.proto == PROTO_TCPv4_SERVER -+#ifdef USE_PF_INET6 -+ || sock->info.proto == PROTO_TCPv6_SERVER -+#endif -+ ); - ASSERT (!sock->inetd); - sock->sd = accept_from->sd; - } -@@ -1313,7 +1719,11 @@ - /* were we started by inetd or xinetd? */ - if (sock->inetd) - { -- ASSERT (sock->info.proto != PROTO_TCPv4_CLIENT); -+ ASSERT (sock->info.proto != PROTO_TCPv4_CLIENT -+#ifdef USE_PF_INET6 -+ && sock->info.proto != PROTO_TCPv6_CLIENT -+#endif -+ ); - ASSERT (socket_defined (inetd_socket_descriptor)); - sock->sd = inetd_socket_descriptor; - } -@@ -1366,7 +1776,34 @@ - /* were we started by inetd or xinetd? */ - if (sock->inetd) - { -- if (sock->info.proto == PROTO_TCPv4_SERVER) -+ if (sock->info.proto == PROTO_TCPv4_SERVER -+#ifdef USE_PF_INET6 -+ || sock->info.proto == PROTO_TCPv6_SERVER -+#endif -+ ) { -+ /* AF_INET as default (and fallback) for inetd */ -+ sock->info.lsa->actual.dest.addr.sa.sa_family = AF_INET; -+#ifdef USE_PF_INET6 -+#ifdef HAVE_GETSOCKNAME -+ { -+ /* inetd: hint family type for dest = local's */ -+ struct openvpn_sockaddr local_addr; -+ socklen_t addrlen = sizeof(local_addr); -+ if (getsockname (sock->sd, (struct sockaddr *)&local_addr, &addrlen) == 0) { -+ sock->info.lsa->actual.dest.addr.sa.sa_family = local_addr.addr.sa.sa_family; -+ dmsg (D_SOCKET_DEBUG, "inetd(%s): using sa_family=%d from getsockname(%d)", -+ proto2ascii(sock->info.proto, false), local_addr.addr.sa.sa_family, -+ sock->sd); -+ } else -+ msg (M_WARN, "inetd(%s): getsockname(%d) failed, using AF_INET", -+ proto2ascii(sock->info.proto, false), sock->sd); -+ } -+#else -+ msg (M_WARN, "inetd(%s): this OS does not provide the getsockname() " -+ "function, using AF_INET", -+ proto2ascii(sock->info.proto, false)); -+#endif -+#endif - sock->sd = - socket_listen_accept (sock->sd, - &sock->info.lsa->actual, -@@ -1376,6 +1813,7 @@ - false, - sock->inetd == INETD_NOWAIT, - signal_received); -+ } - ASSERT (!remote_changed); - if (*signal_received) - goto done; -@@ -1388,7 +1826,11 @@ - goto done; - - /* TCP client/server */ -- if (sock->info.proto == PROTO_TCPv4_SERVER) -+ if (sock->info.proto == PROTO_TCPv4_SERVER -+#ifdef USE_PF_INET6 -+ ||sock->info.proto == PROTO_TCPv6_SERVER -+#endif -+ ) - { - switch (sock->mode) - { -@@ -1423,7 +1865,11 @@ - ASSERT (0); - } - } -- else if (sock->info.proto == PROTO_TCPv4_CLIENT) -+ else if (sock->info.proto == PROTO_TCPv4_CLIENT -+#ifdef USE_PF_INET6 -+ ||sock->info.proto == PROTO_TCPv6_CLIENT -+#endif -+ ) - { - - #ifdef GENERAL_PROXY_SUPPORT -@@ -1510,8 +1956,8 @@ - sock->remote_port = sock->proxy_dest_port; - sock->did_resolve_remote = false; - -- sock->info.lsa->actual.dest.sa.sin_addr.s_addr = 0; -- sock->info.lsa->remote.sa.sin_addr.s_addr = 0; -+ addr_zero_host(&sock->info.lsa->actual.dest); -+ addr_zero_host(&sock->info.lsa->remote); - - resolve_remote (sock, 1, NULL, signal_received); - -@@ -1526,7 +1972,7 @@ - if (remote_changed) - { - msg (M_INFO, "TCP/UDP: Dynamic remote address changed during TCP connection establishment"); -- sock->info.lsa->remote.sa.sin_addr.s_addr = sock->info.lsa->actual.dest.sa.sin_addr.s_addr; -+ addr_copy_host(&sock->info.lsa->remote, &sock->info.lsa->actual.dest); - } - } - -@@ -1708,13 +2154,20 @@ - { - struct gc_arena gc = gc_new (); - -- msg (D_LINK_ERRORS, -- "TCP/UDP: Incoming packet rejected from %s[%d], expected peer address: %s (allow this incoming source address/port by removing --remote or adding --float)", -- print_link_socket_actual (from_addr, &gc), -- (int)from_addr->dest.sa.sin_family, -- print_sockaddr (&info->lsa->remote, &gc)); -+ switch(from_addr->dest.addr.sa.sa_family) -+ { -+ case AF_INET: -+#ifdef USE_PF_INET6 -+ case AF_INET6: -+#endif -+ msg (D_LINK_ERRORS, -+ "TCP/UDP: Incoming packet rejected from %s[%d], expected peer address: %s (allow this incoming source address/port by removing --remote or adding --float)", -+ print_link_socket_actual (from_addr, &gc), -+ (int)from_addr->dest.addr.sa.sa_family, -+ print_sockaddr (&info->lsa->remote, &gc)); -+ break; -+ } - buf->len = 0; -- - gc_free (&gc); - } - -@@ -1729,10 +2182,25 @@ - { - const struct link_socket_addr *lsa = info->lsa; - -+/* -+ * This logic supports "redirect-gateway" semantic, which -+ * makes sense only for PF_INET routes over PF_INET endpoints -+ * -+ * Maybe in the future consider PF_INET6 endpoints also ... -+ * by now just ignore it -+ * -+ */ -+#ifdef USE_PF_INET6 -+ if (lsa->actual.dest.addr.sa.sa_family != AF_INET) -+ return IPV4_INVALID_ADDR; -+#else -+ ASSERT (lsa->actual.dest.addr.sa.sa_family == AF_INET); -+#endif -+ - if (link_socket_actual_defined (&lsa->actual)) -- return ntohl (lsa->actual.dest.sa.sin_addr.s_addr); -+ return ntohl (lsa->actual.dest.addr.in4.sin_addr.s_addr); - else if (addr_defined (&lsa->remote)) -- return ntohl (lsa->remote.sa.sin_addr.s_addr); -+ return ntohl (lsa->remote.addr.in4.sin_addr.s_addr); - else - return 0; - } -@@ -1959,26 +2427,61 @@ - const unsigned int flags, - struct gc_arena *gc) - { -- if (addr) -+ struct buffer out = alloc_buf_gc (128, gc); -+ bool addr_is_defined; -+ addr_is_defined = addr_defined (addr); -+ if (!addr_is_defined) { -+ return "[undef]"; -+ } -+#ifdef USE_PF_INET6 -+ switch(addr->addr.sa.sa_family) - { -- struct buffer out = alloc_buf_gc (64, gc); -- const int port = ntohs (addr->sa.sin_port); -+ case AF_INET: -+#endif -+ { -+ const int port= ntohs (addr->addr.in4.sin_port); -+ buf_puts (&out, "[AF_INET]"); - -- if (!(flags & PS_DONT_SHOW_ADDR)) -- buf_printf (&out, "%s", (addr_defined (addr) ? inet_ntoa (addr->sa.sin_addr) : "[undef]")); -+ if (!(flags & PS_DONT_SHOW_ADDR)) -+ buf_printf (&out, "%s", (addr_defined (addr) ? inet_ntoa (addr->addr.in4.sin_addr) : "[undef]")); - -- if (((flags & PS_SHOW_PORT) || (addr_defined (addr) && (flags & PS_SHOW_PORT_IF_DEFINED))) -- && port) -+ if (((flags & PS_SHOW_PORT) || (addr_defined (addr) && (flags & PS_SHOW_PORT_IF_DEFINED))) -+ && port) -+ { -+ if (separator) -+ buf_printf (&out, "%s", separator); -+ -+ buf_printf (&out, "%d", port); -+ } -+ } -+#ifdef USE_PF_INET6 -+ break; -+ case AF_INET6: - { -- if (separator) -- buf_printf (&out, "%s", separator); -+ const int port= ntohs (addr->addr.in6.sin6_port); -+ char buf[INET6_ADDRSTRLEN] = ""; -+ buf_puts (&out, "[AF_INET6]"); -+ if (addr_is_defined) -+ { -+ getnameinfo(&addr->addr.sa, sizeof (struct sockaddr_in6), -+ buf, sizeof (buf), NULL, 0, NI_NUMERICHOST); -+ buf_puts (&out, buf); -+ } -+ if (((flags & PS_SHOW_PORT) || (addr_is_defined && (flags & PS_SHOW_PORT_IF_DEFINED))) -+ && port) -+ { -+ if (separator) -+ buf_puts (&out, separator); - -- buf_printf (&out, "%d", port); -+ buf_printf (&out, "%d", port); -+ } - } -- return BSTR (&out); -+ break; -+ default: -+ ASSERT(0); - } -- else -- return "[NULL]"; -+#endif -+ return BSTR (&out); - } - - const char * -@@ -1987,6 +2490,10 @@ - return print_link_socket_actual_ex (act, ":", PS_SHOW_PORT|PS_SHOW_PKTINFO, gc); - } - -+#ifndef IF_NAMESIZE -+#define IF_NAMESIZE 16 -+#endif -+ - const char * - print_link_socket_actual_ex (const struct link_socket_actual *act, - const char *separator, -@@ -1995,15 +2502,54 @@ - { - if (act) - { -+ char ifname[IF_NAMESIZE] = "[undef]"; - struct buffer out = alloc_buf_gc (128, gc); - buf_printf (&out, "%s", print_sockaddr_ex (&act->dest, separator, flags, gc)); - #if ENABLE_IP_PKTINFO -- if ((flags & PS_SHOW_PKTINFO) && act->pi.ipi_spec_dst.s_addr) -+ if ((flags & PS_SHOW_PKTINFO) && addr_defined_ipi(act)) - { -- struct openvpn_sockaddr sa; -- CLEAR (sa); -- sa.sa.sin_addr = act->pi.ipi_spec_dst; -- buf_printf (&out, " (via %s)", print_sockaddr_ex (&sa, separator, 0, gc)); -+#ifdef USE_PF_INET6 -+ switch(act->dest.addr.sa.sa_family) -+ { -+ case AF_INET: -+#endif -+ { -+ struct openvpn_sockaddr sa; -+ CLEAR (sa); -+ sa.addr.in4.sin_family = AF_INET; -+#ifdef IP_PKTINFO -+ sa.addr.in4.sin_addr = act->pi.in4.ipi_spec_dst; -+ if_indextoname(act->pi.in4.ipi_ifindex, ifname); -+#elif defined(IP_RECVDSTADDR) -+ sa.addr.in4.sin_addr = act->pi.in4; -+ ifname[0]=0; -+#else -+#error ENABLE_IP_PKTINFO is set without IP_PKTINFO xor IP_RECVDSTADDR (fix syshead.h) -+#endif -+ buf_printf (&out, " (via %s%%%s)", -+ print_sockaddr_ex (&sa, separator, 0, gc), -+ ifname); -+ } -+#ifdef USE_PF_INET6 -+ break; -+ case AF_INET6: -+ { -+ struct sockaddr_in6 sin6; -+ char buf[INET6_ADDRSTRLEN] = "[undef]"; -+ CLEAR(sin6); -+ sin6.sin6_family = AF_INET6; -+ sin6.sin6_addr = act->pi.in6.ipi6_addr; -+ if_indextoname(act->pi.in6.ipi6_ifindex, ifname); -+ if (getnameinfo((struct sockaddr *)&sin6, sizeof (struct sockaddr_in6), -+ buf, sizeof (buf), NULL, 0, NI_NUMERICHOST) == 0) -+ buf_printf (&out, " (via %s%%%s)", buf, ifname); -+ else -+ buf_printf (&out, " (via [getnameinfo() err]%%%s)", ifname); -+ } -+ break; -+ } -+#endif /* USE_PF_INET6 */ -+ - } - #endif - return BSTR (&out); -@@ -2038,18 +2584,40 @@ - { - char name_buf[256]; - -- if (flags & SA_IP_PORT) -- openvpn_snprintf (name_buf, sizeof (name_buf), "%s_ip", name_prefix); -- else -- openvpn_snprintf (name_buf, sizeof (name_buf), "%s", name_prefix); -+#ifdef USE_PF_INET6 -+ char buf[128]; -+ switch(addr->addr.sa.sa_family) -+ { -+ case AF_INET: -+#endif -+ if (flags & SA_IP_PORT) -+ openvpn_snprintf (name_buf, sizeof (name_buf), "%s_ip", name_prefix); -+ else -+ openvpn_snprintf (name_buf, sizeof (name_buf), "%s", name_prefix); - -- setenv_str (es, name_buf, inet_ntoa (addr->sa.sin_addr)); -+ setenv_str (es, name_buf, inet_ntoa (addr->addr.in4.sin_addr)); - -- if ((flags & SA_IP_PORT) && addr->sa.sin_port) -- { -- openvpn_snprintf (name_buf, sizeof (name_buf), "%s_port", name_prefix); -- setenv_int (es, name_buf, ntohs (addr->sa.sin_port)); -+ if ((flags & SA_IP_PORT) && addr->addr.in4.sin_port) -+ { -+ openvpn_snprintf (name_buf, sizeof (name_buf), "%s_port", name_prefix); -+ setenv_int (es, name_buf, ntohs (addr->addr.in4.sin_port)); -+ } -+#ifdef USE_PF_INET6 -+ break; -+ case AF_INET6: -+ openvpn_snprintf (name_buf, sizeof (name_buf), "%s_ip6", name_prefix); -+ getnameinfo(&addr->addr.sa, sizeof (struct sockaddr_in6), -+ buf, sizeof(buf), NULL, 0, NI_NUMERICHOST); -+ setenv_str (es, name_buf, buf); -+ -+ if ((flags & SA_IP_PORT) && addr->addr.in6.sin6_port) -+ { -+ openvpn_snprintf (name_buf, sizeof (name_buf), "%s_port", name_prefix); -+ setenv_int (es, name_buf, ntohs (addr->addr.in6.sin6_port)); -+ } -+ break; - } -+#endif - } - - void -@@ -2059,7 +2627,8 @@ - { - struct openvpn_sockaddr si; - CLEAR (si); -- si.sa.sin_addr.s_addr = htonl (addr); -+ si.addr.in4.sin_family = AF_INET; -+ si.addr.in4.sin_addr.s_addr = htonl (addr); - setenv_sockaddr (es, name_prefix, &si, flags); - } - } -@@ -2080,16 +2649,63 @@ - struct proto_names { - const char *short_form; - const char *display_form; -+ bool is_dgram; -+ bool is_net; -+ unsigned short proto_af; - }; - - /* Indexed by PROTO_x */ --static const struct proto_names proto_names[] = { -- {"udp", "UDPv4"}, -- {"tcp-server", "TCPv4_SERVER"}, -- {"tcp-client", "TCPv4_CLIENT"}, -- {"tcp", "TCPv4"} -+static const struct proto_names proto_names[PROTO_N] = { -+ {"proto-uninitialized", "proto-NONE",0,0, AF_UNSPEC}, -+ {"udp", "UDPv4",1,1, AF_INET}, -+ {"tcp-server", "TCPv4_SERVER",0,1, AF_INET}, -+ {"tcp-client", "TCPv4_CLIENT",0,1, AF_INET}, -+ {"tcp", "TCPv4",0,1, AF_INET}, -+#ifdef USE_PF_INET6 -+ {"udp6" ,"UDPv6",1,1, AF_INET6}, -+ {"tcp6-server","TCPv6_SERVER",0,1, AF_INET6}, -+ {"tcp6-client","TCPv6_CLIENT",0,1, AF_INET6}, -+ {"tcp6" ,"TCPv6",0,1, AF_INET6}, -+#endif - }; - -+bool -+proto_is_net(int proto) -+{ -+ if (proto < 0 || proto >= PROTO_N) -+ ASSERT(0); -+ return proto_names[proto].is_net; -+} -+bool -+proto_is_dgram(int proto) -+{ -+ if (proto < 0 || proto >= PROTO_N) -+ ASSERT(0); -+ return proto_names[proto].is_dgram; -+} -+bool -+proto_is_udp(int proto) -+{ -+ if (proto < 0 || proto >= PROTO_N) -+ ASSERT(0); -+ return proto_names[proto].is_dgram&&proto_names[proto].is_net; -+} -+bool -+proto_is_tcp(int proto) -+{ -+ if (proto < 0 || proto >= PROTO_N) -+ ASSERT(0); -+ return (!proto_names[proto].is_dgram)&&proto_names[proto].is_net; -+} -+ -+unsigned short -+proto_sa_family(int proto) -+{ -+ if (proto < 0 || proto >= PROTO_N) -+ ASSERT(0); -+ return proto_names[proto].proto_af; -+} -+ - int - ascii2proto (const char* proto_name) - { -@@ -2129,6 +2745,45 @@ - return BSTR (&out); - } - -+int -+addr_guess_family(int proto, const char *name) -+{ -+#ifdef USE_PF_INET6 -+ unsigned short ret; -+#endif -+ if (proto) -+ { -+ return proto_sa_family(proto); /* already stamped */ -+ } -+#ifdef USE_PF_INET6 -+ else -+ { -+ struct addrinfo hints , *ai; -+ int err; -+ CLEAR(hints); -+ hints.ai_flags = AI_NUMERICHOST; -+ err = getaddrinfo(name, NULL, &hints, &ai); -+ if ( 0 == err ) -+ { -+ ret=ai->ai_family; -+ freeaddrinfo(ai); -+ return ret; -+ } -+ } -+#endif -+ return AF_INET; /* default */ -+} -+const char * -+addr_family_name (int af) -+{ -+ switch (af) -+ { -+ case AF_INET: return "AF_INET"; -+ case AF_INET6: return "AF_INET6"; -+ } -+ return "AF_UNSPEC"; -+} -+ - /* - * Given a local proto, return local proto - * if !remote, or compatible remote proto -@@ -2143,10 +2798,15 @@ - ASSERT (proto >= 0 && proto < PROTO_N); - if (remote) - { -- if (proto == PROTO_TCPv4_SERVER) -- return PROTO_TCPv4_CLIENT; -- if (proto == PROTO_TCPv4_CLIENT) -- return PROTO_TCPv4_SERVER; -+ switch (proto) -+ { -+ case PROTO_TCPv4_SERVER: return PROTO_TCPv4_CLIENT; -+ case PROTO_TCPv4_CLIENT: return PROTO_TCPv4_SERVER; -+#ifdef USE_PF_INET6 -+ case PROTO_TCPv6_SERVER: return PROTO_TCPv6_CLIENT; -+ case PROTO_TCPv6_CLIENT: return PROTO_TCPv6_SERVER; -+#endif -+ } - } - return proto; - } -@@ -2205,10 +2865,29 @@ - #if ENABLE_IP_PKTINFO - - #pragma pack(1) /* needed to keep structure size consistent for 32 vs. 64-bit architectures */ --struct openvpn_pktinfo -+struct openvpn_in4_pktinfo -+{ -+ struct cmsghdr cmsghdr; -+#ifdef HAVE_IN_PKTINFO -+ struct in_pktinfo pi4; -+#endif -+#ifdef IP_RECVDSTADDR -+ struct in_addr pi4; -+#endif -+}; -+#ifdef USE_PF_INET6 -+struct openvpn_in6_pktinfo - { - struct cmsghdr cmsghdr; -- struct in_pktinfo in_pktinfo; -+ struct in6_pktinfo pi6; -+}; -+#endif -+ -+union openvpn_pktinfo { -+ struct openvpn_in4_pktinfo msgpi4; -+#ifdef USE_PF_INET6 -+ struct openvpn_in6_pktinfo msgpi6; -+#endif - }; - #pragma pack() - -@@ -2219,18 +2898,18 @@ - struct link_socket_actual *from) - { - struct iovec iov; -- struct openvpn_pktinfo opi; -+ union openvpn_pktinfo opi; - struct msghdr mesg; -- socklen_t fromlen = sizeof (from->dest.sa); -+ socklen_t fromlen = sizeof (from->dest.addr); - - iov.iov_base = BPTR (buf); - iov.iov_len = maxsize; - mesg.msg_iov = &iov; - mesg.msg_iovlen = 1; -- mesg.msg_name = &from->dest.sa; -+ mesg.msg_name = &from->dest.addr; - mesg.msg_namelen = fromlen; - mesg.msg_control = &opi; -- mesg.msg_controllen = sizeof (opi); -+ mesg.msg_controllen = sizeof opi; - buf->len = recvmsg (sock->sd, &mesg, 0); - if (buf->len >= 0) - { -@@ -2239,14 +2918,39 @@ - cmsg = CMSG_FIRSTHDR (&mesg); - if (cmsg != NULL - && CMSG_NXTHDR (&mesg, cmsg) == NULL -+#ifdef IP_PKTINFO - && cmsg->cmsg_level == SOL_IP - && cmsg->cmsg_type == IP_PKTINFO -- && cmsg->cmsg_len >= sizeof (opi)) -+#elif defined(IP_RECVDSTADDR) -+ && cmsg->cmsg_level == IPPROTO_IP -+ && cmsg->cmsg_type == IP_RECVDSTADDR -+#else -+#error ENABLE_IP_PKTINFO is set without IP_PKTINFO xor IP_RECVDSTADDR (fix syshead.h) -+#endif -+ && cmsg->cmsg_len >= sizeof (struct openvpn_in4_pktinfo)) - { -+#ifdef IP_PKTINFO - struct in_pktinfo *pkti = (struct in_pktinfo *) CMSG_DATA (cmsg); -- from->pi.ipi_ifindex = pkti->ipi_ifindex; -- from->pi.ipi_spec_dst = pkti->ipi_spec_dst; -+ from->pi.in4.ipi_ifindex = pkti->ipi_ifindex; -+ from->pi.in4.ipi_spec_dst = pkti->ipi_spec_dst; -+#elif defined(IP_RECVDSTADDR) -+ from->pi.in4 = *(struct in_addr*) CMSG_DATA (cmsg); -+#else -+#error ENABLE_IP_PKTINFO is set without IP_PKTINFO xor IP_RECVDSTADDR (fix syshead.h) -+#endif - } -+#ifdef USE_PF_INET6 -+ else if (cmsg != NULL -+ && CMSG_NXTHDR (&mesg, cmsg) == NULL -+ && cmsg->cmsg_level == IPPROTO_IPV6 -+ && cmsg->cmsg_type == IPV6_PKTINFO -+ && cmsg->cmsg_len >= sizeof (struct openvpn_in6_pktinfo)) -+ { -+ struct in6_pktinfo *pkti6 = (struct in6_pktinfo *) CMSG_DATA (cmsg); -+ from->pi.in6.ipi6_ifindex = pkti6->ipi6_ifindex; -+ from->pi.in6.ipi6_addr = pkti6->ipi6_addr; -+ } -+#endif - } - return fromlen; - } -@@ -2258,18 +2962,20 @@ - int maxsize, - struct link_socket_actual *from) - { -- socklen_t fromlen = sizeof (from->dest.sa); -- from->dest.sa.sin_addr.s_addr = 0; -+ socklen_t fromlen = sizeof (from->dest.addr); -+ socklen_t expectedlen = af_addr_size(proto_sa_family(sock->info.proto)); -+ addr_zero_host(&from->dest); - ASSERT (buf_safe (buf, maxsize)); - #if ENABLE_IP_PKTINFO -- if (sock->sockflags & SF_USE_IP_PKTINFO) -+ /* Both PROTO_UDPv4 and PROTO_UDPv6 */ -+ if (proto_is_udp(sock->info.proto) && sock->sockflags & SF_USE_IP_PKTINFO) - fromlen = link_socket_read_udp_posix_recvmsg (sock, buf, maxsize, from); - else - #endif - buf->len = recvfrom (sock->sd, BPTR (buf), maxsize, 0, -- (struct sockaddr *) &from->dest.sa, &fromlen); -- if (fromlen != sizeof (from->dest.sa)) -- bad_address_length (fromlen, sizeof (from->dest.sa)); -+ &from->dest.addr.sa, &fromlen); -+ if (buf->len >= 0 && expectedlen && fromlen != expectedlen) -+ bad_address_length (fromlen, expectedlen); - return buf->len; - } - -@@ -2306,26 +3012,64 @@ - struct iovec iov; - struct msghdr mesg; - struct cmsghdr *cmsg; -- struct in_pktinfo *pkti; -- struct openvpn_pktinfo opi; - - iov.iov_base = BPTR (buf); - iov.iov_len = BLEN (buf); - mesg.msg_iov = &iov; - mesg.msg_iovlen = 1; -- mesg.msg_name = &to->dest.sa; -- mesg.msg_namelen = sizeof (to->dest.sa); -- mesg.msg_control = &opi; -- mesg.msg_controllen = sizeof (opi); -- mesg.msg_flags = 0; -- cmsg = CMSG_FIRSTHDR (&mesg); -- cmsg->cmsg_len = sizeof (opi); -- cmsg->cmsg_level = SOL_IP; -- cmsg->cmsg_type = IP_PKTINFO; -- pkti = (struct in_pktinfo *) CMSG_DATA (cmsg); -- pkti->ipi_ifindex = to->pi.ipi_ifindex; -- pkti->ipi_spec_dst = to->pi.ipi_spec_dst; -- pkti->ipi_addr.s_addr = 0; -+ switch (sock->info.lsa->remote.addr.sa.sa_family) -+ { -+ case AF_INET: -+ { -+ struct openvpn_in4_pktinfo msgpi4; -+ mesg.msg_name = &to->dest.addr.sa; -+ mesg.msg_namelen = sizeof (struct sockaddr_in); -+ mesg.msg_control = &msgpi4; -+ mesg.msg_controllen = sizeof msgpi4; -+ mesg.msg_flags = 0; -+ cmsg = CMSG_FIRSTHDR (&mesg); -+ cmsg->cmsg_len = sizeof (struct openvpn_in4_pktinfo); -+#ifdef HAVE_IN_PKTINFO -+ cmsg->cmsg_level = SOL_IP; -+ cmsg->cmsg_type = IP_PKTINFO; -+ { -+ struct in_pktinfo *pkti; -+ pkti = (struct in_pktinfo *) CMSG_DATA (cmsg); -+ pkti->ipi_ifindex = to->pi.in4.ipi_ifindex; -+ pkti->ipi_spec_dst = to->pi.in4.ipi_spec_dst; -+ pkti->ipi_addr.s_addr = 0; -+ } -+#elif defined(IP_RECVDSTADDR) -+ cmsg->cmsg_level = IPPROTO_IP; -+ cmsg->cmsg_type = IP_RECVDSTADDR; -+ *(struct in_addr *) CMSG_DATA (cmsg) = to->pi.in4; -+#else -+#error ENABLE_IP_PKTINFO is set without IP_PKTINFO xor IP_RECVDSTADDR (fix syshead.h) -+#endif -+ break; -+ } -+#ifdef USE_PF_INET6 -+ case AF_INET6: -+ { -+ struct openvpn_in6_pktinfo msgpi6; -+ struct in6_pktinfo *pkti6; -+ mesg.msg_name = &to->dest.addr.sa; -+ mesg.msg_namelen = sizeof (struct sockaddr_in6); -+ mesg.msg_control = &msgpi6; -+ mesg.msg_controllen = sizeof msgpi6; -+ mesg.msg_flags = 0; -+ cmsg = CMSG_FIRSTHDR (&mesg); -+ cmsg->cmsg_len = sizeof (struct openvpn_in6_pktinfo); -+ cmsg->cmsg_level = IPPROTO_IPV6; -+ cmsg->cmsg_type = IPV6_PKTINFO; -+ pkti6 = (struct in6_pktinfo *) CMSG_DATA (cmsg); -+ pkti6->ipi6_ifindex = to->pi.in6.ipi6_ifindex; -+ pkti6->ipi6_addr = to->pi.in6.ipi6_addr; -+ break; -+ } -+#endif -+ default: ASSERT(0); -+ } - return sendmsg (sock->sd, &mesg, 0); - } - -@@ -2346,11 +3090,11 @@ - int status; - - /* reset buf to its initial state */ -- if (sock->info.proto == PROTO_UDPv4) -+ if (proto_is_udp(sock->info.proto)) - { - sock->reads.buf = sock->reads.buf_init; - } -- else if (sock->info.proto == PROTO_TCPv4_CLIENT || sock->info.proto == PROTO_TCPv4_SERVER) -+ else if (proto_is_tcp(sock->info.proto)) - { - stream_buf_get_next (&sock->stream_buf, &sock->reads.buf); - } -@@ -2370,10 +3114,15 @@ - ASSERT (ResetEvent (sock->reads.overlapped.hEvent)); - sock->reads.flags = 0; - -- if (sock->info.proto == PROTO_UDPv4) -+ if (proto_is_udp(sock->info.proto)) - { - sock->reads.addr_defined = true; -- sock->reads.addrlen = sizeof (sock->reads.addr); -+#ifdef USE_PF_INET6 -+ if (sock->info.proto == PROTO_UDPv6) -+ sock->reads.addrlen = sizeof (sock->reads.addr6); -+ else -+#endif -+ sock->reads.addrlen = sizeof (sock->reads.addr); - status = WSARecvFrom( - sock->sd, - wsabuf, -@@ -2385,7 +3134,7 @@ - &sock->reads.overlapped, - NULL); - } -- else if (sock->info.proto == PROTO_TCPv4_CLIENT || sock->info.proto == PROTO_TCPv4_SERVER) -+ else if (proto_is_tcp(sock->info.proto)) - { - sock->reads.addr_defined = false; - status = WSARecv( -@@ -2405,8 +3154,14 @@ - - if (!status) /* operation completed immediately? */ - { -+#ifdef USE_PF_INET6 -+ int addrlen = af_addr_size(sock->info.lsa->local.addr.sa.sa_family); -+ if (sock->reads.addr_defined && sock->reads.addrlen != addrlen) -+ bad_address_length (sock->reads.addrlen, addrlen); -+#else - if (sock->reads.addr_defined && sock->reads.addrlen != sizeof (sock->reads.addr)) - bad_address_length (sock->reads.addrlen, sizeof (sock->reads.addr)); -+#endif - - sock->reads.iostate = IOSTATE_IMMEDIATE_RETURN; - -@@ -2465,12 +3220,22 @@ - ASSERT (ResetEvent (sock->writes.overlapped.hEvent)); - sock->writes.flags = 0; - -- if (sock->info.proto == PROTO_UDPv4) -+ if (proto_is_udp(sock->info.proto)) - { - /* set destination address for UDP writes */ - sock->writes.addr_defined = true; -- sock->writes.addr = to->dest.sa; -- sock->writes.addrlen = sizeof (sock->writes.addr); -+#ifdef USE_PF_INET6 -+ if (sock->info.proto == PROTO_UDPv6) -+ { -+ sock->writes.addr6 = to->dest.addr.in6; -+ sock->writes.addrlen = sizeof (sock->writes.addr6); -+ } -+ else -+#endif -+ { -+ sock->writes.addr = to->dest.addr.in4; -+ sock->writes.addrlen = sizeof (sock->writes.addr); -+ } - - status = WSASendTo( - sock->sd, -@@ -2483,7 +3248,7 @@ - &sock->writes.overlapped, - NULL); - } -- else if (sock->info.proto == PROTO_TCPv4_CLIENT || sock->info.proto == PROTO_TCPv4_SERVER) -+ else if (proto_is_tcp(sock->info.proto)) - { - /* destination address for TCP writes was established on connection initiation */ - sock->writes.addr_defined = false; -@@ -2622,13 +3387,44 @@ - if (from) - { - if (ret >= 0 && io->addr_defined) -+#ifdef USE_PF_INET6 -+ { -+ /* TODO(jjo): streamline this mess */ -+ /* in this func we dont have relevant info about the PF_ of this -+ * endpoint, as link_socket_actual will be zero for the 1st received packet -+ * -+ * Test for inets PF_ possible sizes -+ */ -+ switch (io->addrlen) -+ { -+ case sizeof(struct sockaddr_in): -+ case sizeof(struct sockaddr_in6): -+ /* TODO(jjo): for some reason (?) I'm getting 24,28 for AF_INET6 */ -+ case sizeof(struct sockaddr_in6)-4: -+ break; -+ default: -+ bad_address_length (io->addrlen, af_addr_size(io->addr.sin_family)); -+ } -+ -+ switch (io->addr.sin_family) -+ { -+ case AF_INET: -+ from->dest.addr.in4 = io->addr; -+ break; -+ case AF_INET6: -+ from->dest.addr.in6 = io->addr6; -+ break; -+ } -+ } -+#else - { - if (io->addrlen != sizeof (io->addr)) - bad_address_length (io->addrlen, sizeof (io->addr)); -- from->dest.sa = io->addr; -+ from->dest.addr.in4 = io->addr; - } -+#endif - else -- CLEAR (from->dest.sa); -+ CLEAR (from->dest.addr); - } - - if (buf) -Index: openvpn-2.2.1/socket.h -=================================================================== ---- openvpn-2.2.1.orig/socket.h 2011-06-24 08:13:39.000000000 +0200 -+++ openvpn-2.2.1/socket.h 2011-12-13 12:23:07.382080084 +0100 -@@ -70,7 +70,13 @@ - struct openvpn_sockaddr - { - /*int dummy;*/ /* add offset to force a bug if sa not explicitly dereferenced */ -- struct sockaddr_in sa; -+ union { -+ struct sockaddr sa; -+ struct sockaddr_in in4; -+#ifdef USE_PF_INET6 -+ struct sockaddr_in6 in6; -+#endif -+ } addr; - }; - - /* actual address of remote, based on source address of received packets */ -@@ -79,7 +85,17 @@ - /*int dummy;*/ /* add offset to force a bug if dest not explicitly dereferenced */ - struct openvpn_sockaddr dest; - #if ENABLE_IP_PKTINFO -- struct in_pktinfo pi; -+ union { -+#ifdef HAVE_IN_PKTINFO -+ struct in_pktinfo in4; -+#endif -+#ifdef IP_RECVDSTADDR -+ struct in_addr in4; -+#endif -+#ifdef USE_PF_INET6 -+ struct in6_pktinfo in6; -+#endif -+ } pi; - #endif - }; - -@@ -199,6 +215,7 @@ - # define SF_TCP_NODELAY (1<<1) - # define SF_PORT_SHARE (1<<2) - # define SF_HOST_RANDOMIZE (1<<3) -+# define SF_GETADDRINFO_DGRAM (1<<4) - unsigned int sockflags; - - /* for stream sockets */ -@@ -371,6 +388,12 @@ - - void bad_address_length (int actual, int expected); - -+#ifdef USE_PF_INET6 -+/* IPV4_INVALID_ADDR: returned by link_socket_current_remote() -+ * to ease redirect-gateway logic for ipv4 tunnels on ipv6 endpoints -+ */ -+#define IPV4_INVALID_ADDR 0xffffffff -+#endif - in_addr_t link_socket_current_remote (const struct link_socket_info *info); - - void link_socket_connection_initiated (const struct buffer *buf, -@@ -410,6 +433,14 @@ - socket_descriptor_t socket_do_accept (socket_descriptor_t sd, - struct link_socket_actual *act, - const bool nowait); -+/* -+ * proto related -+ */ -+bool proto_is_net(int proto); -+bool proto_is_dgram(int proto); -+bool proto_is_udp(int proto); -+bool proto_is_tcp(int proto); -+ - - #if UNIX_SOCK_SUPPORT - -@@ -455,6 +486,11 @@ - #define GETADDR_UPDATE_MANAGEMENT_STATE (1<<8) - #define GETADDR_RANDOMIZE (1<<9) - -+/* [ab]use flags bits to get socktype info downstream */ -+/* TODO(jjo): resolve tradeoff between hackiness|args-overhead */ -+#define GETADDR_DGRAM (1<<10) -+#define dnsflags_to_socktype(flags) ((flags & GETADDR_DGRAM) ? SOCK_DGRAM : SOCK_STREAM) -+ - in_addr_t getaddr (unsigned int flags, - const char *hostname, - int resolve_retry_seconds, -@@ -472,23 +508,38 @@ - * Transport protocol naming and other details. - */ - --#define PROTO_UDPv4 0 --#define PROTO_TCPv4_SERVER 1 --#define PROTO_TCPv4_CLIENT 2 --#define PROTO_TCPv4 3 --#define PROTO_N 4 -+/* -+ * Use enum's instead of #define to allow for easier -+ * optional proto support -+ */ -+enum proto_num { -+ PROTO_NONE, /* catch for uninitialized */ -+ PROTO_UDPv4, -+ PROTO_TCPv4_SERVER, -+ PROTO_TCPv4_CLIENT, -+ PROTO_TCPv4, -+#ifdef USE_PF_INET6 -+ PROTO_UDPv6, -+ PROTO_TCPv6_SERVER, -+ PROTO_TCPv6_CLIENT, -+ PROTO_TCPv6, -+#endif -+ PROTO_N -+}; - - int ascii2proto (const char* proto_name); - const char *proto2ascii (int proto, bool display_form); - const char *proto2ascii_all (struct gc_arena *gc); - int proto_remote (int proto, bool remote); -+const char *addr_family_name(int af); - - /* - * Overhead added to packets by various protocols. - */ - #define IPv4_UDP_HEADER_SIZE 28 - #define IPv4_TCP_HEADER_SIZE 40 --#define IPv6_UDP_HEADER_SIZE 40 -+#define IPv6_UDP_HEADER_SIZE 48 -+#define IPv6_TCP_HEADER_SIZE 60 - - extern const int proto_overhead[]; - -@@ -518,7 +569,7 @@ - static inline bool - link_socket_proto_connection_oriented (int proto) - { -- return proto == PROTO_TCPv4_SERVER || proto == PROTO_TCPv4_CLIENT; -+ return !proto_is_dgram(proto); - } - - static inline bool -@@ -533,7 +584,36 @@ - static inline bool - addr_defined (const struct openvpn_sockaddr *addr) - { -- return addr->sa.sin_addr.s_addr != 0; -+ if (!addr) return 0; -+ switch (addr->addr.sa.sa_family) { -+ case AF_INET: return addr->addr.in4.sin_addr.s_addr != 0; -+#ifdef USE_PF_INET6 -+ case AF_INET6: return !IN6_IS_ADDR_UNSPECIFIED(&addr->addr.in6.sin6_addr); -+#endif -+ default: return 0; -+ } -+} -+static inline bool -+addr_defined_ipi (const struct link_socket_actual *lsa) -+{ -+#if ENABLE_IP_PKTINFO -+ if (!lsa) return 0; -+ switch (lsa->dest.addr.sa.sa_family) { -+#ifdef HAVE_IN_PKTINFO -+ case AF_INET: return lsa->pi.in4.ipi_spec_dst.s_addr != 0; -+#endif -+#ifdef IP_RECVDSTADDR -+ case AF_INET: return lsa->pi.in4.s_addr != 0; -+#endif -+#ifdef USE_PF_INET6 -+ case AF_INET6: return !IN6_IS_ADDR_UNSPECIFIED(&lsa->pi.in6.ipi6_addr); -+#endif -+ default: return 0; -+ } -+#else -+ ASSERT(0); -+#endif -+ return false; - } - - static inline bool -@@ -545,20 +625,50 @@ - static inline bool - addr_match (const struct openvpn_sockaddr *a1, const struct openvpn_sockaddr *a2) - { -- return a1->sa.sin_addr.s_addr == a2->sa.sin_addr.s_addr; -+ switch(a1->addr.sa.sa_family) { -+ case AF_INET: -+ return a1->addr.in4.sin_addr.s_addr == a2->addr.in4.sin_addr.s_addr; -+#ifdef USE_PF_INET6 -+ case AF_INET6: -+ return IN6_ARE_ADDR_EQUAL(&a1->addr.in6.sin6_addr, &a2->addr.in6.sin6_addr); -+#endif -+ } -+ ASSERT(0); -+ return false; - } - - static inline in_addr_t --addr_host (const struct openvpn_sockaddr *s) -+addr_host (const struct openvpn_sockaddr *addr) - { -- return ntohl (s->sa.sin_addr.s_addr); -+ /* -+ * "public" addr returned is checked against ifconfig for -+ * possible clash: non sense for now given -+ * that we do ifconfig only IPv4 -+ */ -+#if defined(USE_PF_INET6) -+ if(addr->addr.sa.sa_family != AF_INET) -+ return 0; -+#else -+ ASSERT(addr->addr.sa.sa_family == AF_INET); -+#endif -+ return ntohl (addr->addr.in4.sin_addr.s_addr); - } - - static inline bool - addr_port_match (const struct openvpn_sockaddr *a1, const struct openvpn_sockaddr *a2) - { -- return a1->sa.sin_addr.s_addr == a2->sa.sin_addr.s_addr -- && a1->sa.sin_port == a2->sa.sin_port; -+ switch(a1->addr.sa.sa_family) { -+ case AF_INET: -+ return a1->addr.in4.sin_addr.s_addr == a2->addr.in4.sin_addr.s_addr -+ && a1->addr.in4.sin_port == a2->addr.in4.sin_port; -+#ifdef USE_PF_INET6 -+ case AF_INET6: -+ return IN6_ARE_ADDR_EQUAL(&a1->addr.in6.sin6_addr, &a2->addr.in6.sin6_addr) -+ && a1->addr.in6.sin6_port == a2->addr.in6.sin6_port; -+#endif -+ } -+ ASSERT(0); -+ return false; - } - - static inline bool -@@ -571,6 +681,74 @@ - : addr_port_match (a1, a2); - } - -+static inline void -+addr_zero_host(struct openvpn_sockaddr *addr) -+{ -+ switch(addr->addr.sa.sa_family) { -+ case AF_INET: -+ addr->addr.in4.sin_addr.s_addr = 0; -+ break; -+#ifdef USE_PF_INET6 -+ case AF_INET6: -+ memset(&addr->addr.in6.sin6_addr, 0, sizeof (struct in6_addr)); -+ break; -+#endif -+ } -+} -+ -+static inline void -+addr_copy_sa(struct openvpn_sockaddr *dst, const struct openvpn_sockaddr *src) -+{ -+ dst->addr = src->addr; -+} -+ -+static inline void -+addr_copy_host(struct openvpn_sockaddr *dst, const struct openvpn_sockaddr *src) -+{ -+ switch(src->addr.sa.sa_family) { -+ case AF_INET: -+ dst->addr.in4.sin_addr.s_addr = src->addr.in4.sin_addr.s_addr; -+ break; -+#ifdef USE_PF_INET6 -+ case AF_INET6: -+ dst->addr.in6.sin6_addr = src->addr.in6.sin6_addr; -+ break; -+#endif -+ } -+} -+ -+static inline bool -+addr_inet4or6(struct sockaddr *addr) -+{ -+ return addr->sa_family == AF_INET || addr->sa_family == AF_INET6; -+} -+ -+int addr_guess_family(int proto, const char *name); -+static inline int -+af_addr_size(unsigned short af) -+{ -+#if defined(USE_PF_INET6) || defined (USE_PF_UNIX) -+ switch(af) { -+ case AF_INET: return sizeof (struct sockaddr_in); -+#ifdef USE_PF_UNIX -+ case AF_UNIX: return sizeof (struct sockaddr_un); -+#endif -+#ifdef USE_PF_INET6 -+ case AF_INET6: return sizeof (struct sockaddr_in6); -+#endif -+ default: -+#if 0 -+ /* could be called from socket_do_accept() with empty addr */ -+ msg (M_ERR, "Bad address family: %d\n", af); -+ ASSERT(0); -+#endif -+ return 0; -+ } -+#else /* only AF_INET */ -+ return sizeof(struct sockaddr_in); -+#endif -+} -+ - static inline bool - link_socket_actual_match (const struct link_socket_actual *a1, const struct link_socket_actual *a2) - { -@@ -627,14 +805,18 @@ - { - if (buf->len > 0) - { -- if (from_addr->dest.sa.sin_family != AF_INET) -- return false; -- if (!link_socket_actual_defined (from_addr)) -- return false; -- if (info->remote_float || !addr_defined (&info->lsa->remote)) -- return true; -- if (addr_match_proto (&from_addr->dest, &info->lsa->remote, info->proto)) -- return true; -+ switch (from_addr->dest.addr.sa.sa_family) { -+#ifdef USE_PF_INET6 -+ case AF_INET6: -+#endif -+ case AF_INET: -+ if (!link_socket_actual_defined (from_addr)) -+ return false; -+ if (info->remote_float || !addr_defined (&info->lsa->remote)) -+ return true; -+ if (addr_match_proto (&from_addr->dest, &info->lsa->remote, info->proto)) -+ return true; -+ } - } - return false; - } -@@ -740,7 +922,7 @@ - int maxsize, - struct link_socket_actual *from) - { -- if (sock->info.proto == PROTO_UDPv4) -+ if (proto_is_udp(sock->info.proto)) /* unified UDPv4 and UDPv6 */ - { - int res; - -@@ -751,10 +933,10 @@ - #endif - return res; - } -- else if (sock->info.proto == PROTO_TCPv4_SERVER || sock->info.proto == PROTO_TCPv4_CLIENT) -+ else if (proto_is_tcp(sock->info.proto)) /* unified TCPv4 and TCPv6 */ - { - /* from address was returned by accept */ -- from->dest.sa = sock->info.lsa->actual.dest.sa; -+ addr_copy_sa(&from->dest, &sock->info.lsa->actual.dest); - return link_socket_read_tcp (sock, buf); - } - else -@@ -809,13 +991,14 @@ - struct buffer *buf, - struct link_socket_actual *to); - -- if (sock->sockflags & SF_USE_IP_PKTINFO) -+ if (proto_is_udp(sock->info.proto) && (sock->sockflags & SF_USE_IP_PKTINFO) -+ && addr_defined_ipi(to)) - return link_socket_write_udp_posix_sendmsg (sock, buf, to); - else - #endif - return sendto (sock->sd, BPTR (buf), BLEN (buf), 0, -- (struct sockaddr *) &to->dest.sa, -- (socklen_t) sizeof (to->dest.sa)); -+ (struct sockaddr *) &to->dest.addr.sa, -+ (socklen_t) af_addr_size(to->dest.addr.sa.sa_family)); - } - - static inline int -@@ -846,11 +1029,11 @@ - struct buffer *buf, - struct link_socket_actual *to) - { -- if (sock->info.proto == PROTO_UDPv4) -+ if (proto_is_udp(sock->info.proto)) /* unified UDPv4 and UDPv6 */ - { - return link_socket_write_udp (sock, buf, to); - } -- else if (sock->info.proto == PROTO_TCPv4_SERVER || sock->info.proto == PROTO_TCPv4_CLIENT) -+ else if (proto_is_tcp(sock->info.proto)) /* unified TCPv4 and TCPv6 */ - { - return link_socket_write_tcp (sock, buf, to); - } -Index: openvpn-2.2.1/socks.c -=================================================================== ---- openvpn-2.2.1.orig/socks.c 2011-06-24 08:13:39.000000000 +0200 -+++ openvpn-2.2.1/socks.c 2011-12-13 12:23:07.386080032 +0100 -@@ -299,9 +299,9 @@ - - if (addr != NULL) - { -- addr->sa.sin_family = AF_INET; -- addr->sa.sin_addr.s_addr = htonl (INADDR_ANY); -- addr->sa.sin_port = htons (0); -+ addr->addr.in4.sin_family = AF_INET; -+ addr->addr.in4.sin_addr.s_addr = htonl (INADDR_ANY); -+ addr->addr.in4.sin_port = htons (0); - } - - while (len < 4 + alen + 2) -@@ -388,8 +388,8 @@ - /* ATYP == 1 (IP V4 address) */ - if (atyp == '\x01' && addr != NULL) - { -- memcpy (&addr->sa.sin_addr, buf + 4, sizeof (addr->sa.sin_addr)); -- memcpy (&addr->sa.sin_port, buf + 8, sizeof (addr->sa.sin_port)); -+ memcpy (&addr->addr.in4.sin_addr, buf + 4, sizeof (addr->addr.in4.sin_addr)); -+ memcpy (&addr->addr.in4.sin_port, buf + 8, sizeof (addr->addr.in4.sin_port)); - } - - -@@ -507,8 +507,8 @@ - if (atyp != 1) /* ATYP == 1 (IP V4) */ - goto error; - -- buf_read (buf, &from->dest.sa.sin_addr, sizeof (from->dest.sa.sin_addr)); -- buf_read (buf, &from->dest.sa.sin_port, sizeof (from->dest.sa.sin_port)); -+ buf_read (buf, &from->dest.addr.in4.sin_addr, sizeof (from->dest.addr.in4.sin_addr)); -+ buf_read (buf, &from->dest.addr.in4.sin_port, sizeof (from->dest.addr.in4.sin_port)); - - return; - -@@ -540,8 +540,8 @@ - buf_write_u16 (&head, 0); /* RSV = 0 */ - buf_write_u8 (&head, 0); /* FRAG = 0 */ - buf_write_u8 (&head, '\x01'); /* ATYP = 1 (IP V4) */ -- buf_write (&head, &to->dest.sa.sin_addr, sizeof (to->dest.sa.sin_addr)); -- buf_write (&head, &to->dest.sa.sin_port, sizeof (to->dest.sa.sin_port)); -+ buf_write (&head, &to->dest.addr.in4.sin_addr, sizeof (to->dest.addr.in4.sin_addr)); -+ buf_write (&head, &to->dest.addr.in4.sin_port, sizeof (to->dest.addr.in4.sin_port)); - - return 10; - } -Index: openvpn-2.2.1/syshead.h -=================================================================== ---- openvpn-2.2.1.orig/syshead.h 2011-06-24 08:13:39.000000000 +0200 -+++ openvpn-2.2.1/syshead.h 2011-12-13 12:23:07.389079996 +0100 -@@ -28,6 +28,10 @@ - /* - * Only include if not during configure - */ -+#ifdef WIN32 -+/* USE_PF_INET6: win32 ipv6 exists only after 0x0501 (XP) */ -+#define WINVER 0x0501 -+#endif - #ifndef PACKAGE_NAME - #include "config.h" - #endif -@@ -339,6 +343,9 @@ - #ifdef WIN32 - #include <iphlpapi.h> - #include <wininet.h> -+/* The following two headers are needed of USE_PF_INET6 */ -+#include <winsock2.h> -+#include <ws2tcpip.h> - #endif - - #ifdef HAVE_SYS_MMAN_H -@@ -383,9 +390,10 @@ - #endif - - /* -- * Does this platform support linux-style IP_PKTINFO? -+ * Does this platform support linux-style IP_PKTINFO -+ * or bsd-style IP_RECVDSTADDR ? - */ --#if defined(ENABLE_MULTIHOME) && defined(HAVE_IN_PKTINFO) && defined(IP_PKTINFO) && defined(HAVE_MSGHDR) && defined(HAVE_CMSGHDR) && defined(HAVE_IOVEC) && defined(CMSG_FIRSTHDR) && defined(CMSG_NXTHDR) && defined(HAVE_RECVMSG) && defined(HAVE_SENDMSG) -+#if defined(ENABLE_MULTIHOME) && ((defined(HAVE_IN_PKTINFO)&&defined(IP_PKTINFO)) || defined(IP_RECVDSTADDR)) && defined(HAVE_MSGHDR) && defined(HAVE_CMSGHDR) && defined(HAVE_IOVEC) && defined(CMSG_FIRSTHDR) && defined(CMSG_NXTHDR) && defined(HAVE_RECVMSG) && defined(HAVE_SENDMSG) - #define ENABLE_IP_PKTINFO 1 - #else - #define ENABLE_IP_PKTINFO 0 -Index: openvpn-2.2.1/tun.c -=================================================================== ---- openvpn-2.2.1.orig/tun.c 2011-06-24 08:13:39.000000000 +0200 -+++ openvpn-2.2.1/tun.c 2011-12-13 12:23:07.394079932 +0100 -@@ -1688,7 +1688,9 @@ - strerror(errno)); - } - -+#ifdef IFF_MULTICAST /* openbsd 4.x doesn't have this */ - info.flags |= IFF_MULTICAST; -+#endif - - if (ioctl (tt->fd, TUNSIFINFO, &info) < 0) { - msg (M_WARN | M_ERRNO, "Can't set interface info: %s", -Index: openvpn-2.2.1/win32.h -=================================================================== ---- openvpn-2.2.1.orig/win32.h 2011-06-24 08:13:39.000000000 +0200 -+++ openvpn-2.2.1/win32.h 2011-12-13 12:23:07.396079908 +0100 -@@ -195,7 +195,10 @@ - DWORD flags; - int status; - bool addr_defined; -- struct sockaddr_in addr; -+ union { -+ struct sockaddr_in addr; -+ struct sockaddr_in6 addr6; -+ }; - int addrlen; - struct buffer buf_init; - struct buffer buf; |