summaryrefslogtreecommitdiff
path: root/debian
diff options
context:
space:
mode:
Diffstat (limited to 'debian')
-rw-r--r--debian/patches/0001-Drop-too-short-control-channel-packets-instead-of-as.patch42
-rw-r--r--debian/patches/attemping_typo13
-rw-r--r--debian/patches/client_hang_when_server_dont_push.patch53
-rw-r--r--debian/patches/counter_type_for_bytes.patch15
-rw-r--r--debian/patches/debian_openssl_vulnkeys.patch102
-rw-r--r--debian/patches/eurephia.patch81
-rw-r--r--debian/patches/ipv6-payload.patch4049
-rw-r--r--debian/patches/jjo-ipv6-support.patch4011
-rw-r--r--debian/patches/manpage_dash_escaping.patch20
-rw-r--r--debian/patches/remote_env.patch15
-rw-r--r--debian/patches/update_sample_certs.patch532
-rw-r--r--debian/patches/use-dpkg-buildflags.patch39
12 files changed, 0 insertions, 8972 deletions
diff --git a/debian/patches/0001-Drop-too-short-control-channel-packets-instead-of-as.patch b/debian/patches/0001-Drop-too-short-control-channel-packets-instead-of-as.patch
deleted file mode 100644
index 0c80ee0..0000000
--- a/debian/patches/0001-Drop-too-short-control-channel-packets-instead-of-as.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From c5590a6821e37f3b29735f55eb0c2b9c0924138c Mon Sep 17 00:00:00 2001
-From: Steffan Karger <steffan.karger@fox-it.com>
-Date: Thu, 20 Nov 2014 13:43:05 +0100
-Subject: [PATCH] Drop too-short control channel packets instead of asserting
- out.
-
-This fixes a denial-of-service vulnerability where an authenticated client
-could stop the server by triggering a server-side ASSERT().
-
-OpenVPN would previously ASSERT() that control channel packets have a
-payload of at least 4 bytes. An authenticated client could trigger this
-assert by sending a too-short control channel packet to the server.
-
-Thanks to Dragana Damjanovic for reporting the issue.
-
-This bug has been assigned CVE-2014-8104.
-
-Signed-off-by: Steffan Karger <steffan.karger@fox-it.com>
-Acked-by: Gert Doering <gert@greenie.muc.de>
-Message-Id: <1CED409804E2164C8104F9E623B08B9018803B0FE7@FOXDFT02.FOX.local>
-Signed-off-by: Gert Doering <gert@greenie.muc.de>
----
- src/openvpn/ssl.c | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
-Index: openvpn/src/openvpn/ssl.c
-===================================================================
---- openvpn.orig/src/openvpn/ssl.c 2014-12-01 16:09:43.031080162 +0100
-+++ openvpn/src/openvpn/ssl.c 2014-12-01 16:09:43.027080161 +0100
-@@ -2028,7 +2028,11 @@
- ASSERT (session->opt->key_method == 2);
-
- /* discard leading uint32 */
-- ASSERT (buf_advance (buf, 4));
-+ if (!buf_advance (buf, 4)) {
-+ msg (D_TLS_ERRORS, "TLS ERROR: Plaintext buffer too short (%d bytes).",
-+ buf->len);
-+ goto error;
-+ }
-
- /* get key method */
- key_method_flags = buf_read_u8 (buf);
diff --git a/debian/patches/attemping_typo b/debian/patches/attemping_typo
deleted file mode 100644
index da3ec7e..0000000
--- a/debian/patches/attemping_typo
+++ /dev/null
@@ -1,13 +0,0 @@
-Index: openvpn-2.1.3/socket.c
-===================================================================
---- openvpn-2.1.3.orig/socket.c 2010-09-29 13:08:31.548460785 +0200
-+++ openvpn-2.1.3/socket.c 2010-09-29 13:11:08.149458043 +0200
-@@ -1894,7 +1894,7 @@
-
- if (sb->len < 1 || sb->len > sb->maxlen)
- {
-- msg (M_WARN, "WARNING: Bad encapsulated packet length from peer (%d), which must be > 0 and <= %d -- please ensure that --tun-mtu or --link-mtu is equal on both peers -- this condition could also indicate a possible active attack on the TCP link -- [Attemping restart...]", sb->len, sb->maxlen);
-+ msg (M_WARN, "WARNING: Bad encapsulated packet length from peer (%d), which must be > 0 and <= %d -- please ensure that --tun-mtu or --link-mtu is equal on both peers -- this condition could also indicate a possible active attack on the TCP link -- [Attempting restart...]", sb->len, sb->maxlen);
- stream_buf_reset (sb);
- sb->error = true;
- return false;
diff --git a/debian/patches/client_hang_when_server_dont_push.patch b/debian/patches/client_hang_when_server_dont_push.patch
deleted file mode 100644
index 3e56613..0000000
--- a/debian/patches/client_hang_when_server_dont_push.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-Description: When the client sends PUSH_REQUESTS, it waits until the server
- sends PUSH_REPLY. If the server do not have anything to push to the client
- nothing happens. The client will then regularly send new PUSH_REQUESTS until
- it gets an answer, which results in not completing the connection negotiation.
- This patch makes the server send an empty PUSH_REPLY when it has nothing
- more to push to the client.
-Author: David Sommerseth <dazo@users.sourceforge.net>
-Origin: upstream, https://community.openvpn.net/openvpn/attachment/ticket/13/0001-Fixed-client-hang-when-server-don-t-PUSH-aka-the-NO_.patch
-Bug: https://community.openvpn.net/openvpn/ticket/13
-Reviewed-By: James Yonan <james@openvpn.net>
-
-Index: openvpn-2.1.3/push.c
-===================================================================
---- openvpn-2.1.3.orig/push.c 2010-05-31 09:05:55.000000000 +0200
-+++ openvpn-2.1.3/push.c 2010-09-29 13:15:46.788461606 +0200
-@@ -177,6 +177,7 @@
- static char cmd[] = "PUSH_REPLY";
- const int extra = 64; /* extra space for possible trailing ifconfig and push-continuation */
- const int safe_cap = BCAP (&buf) - extra;
-+ bool push_sent = false;
-
- buf_printf (&buf, cmd);
-
-@@ -192,6 +193,7 @@
- const bool status = send_control_channel_string (c, BSTR (&buf), D_PUSH);
- if (!status)
- goto fail;
-+ push_sent = true;
- multi_push = true;
- buf_reset_len (&buf);
- buf_printf (&buf, cmd);
-@@ -218,6 +220,21 @@
- {
- const bool status = send_control_channel_string (c, BSTR (&buf), D_PUSH);
- if (!status)
-+ goto fail;
-+ push_sent = true;
-+ }
-+
-+ /* If nothing have been pushed, send an empty push,
-+ * as the client is expecting a response
-+ */
-+ if (!push_sent)
-+ {
-+ bool status = false;
-+
-+ buf_reset_len (&buf);
-+ buf_printf (&buf, cmd);
-+ status = send_control_channel_string (c, BSTR(&buf), D_PUSH);
-+ if (!status)
- goto fail;
- }
-
diff --git a/debian/patches/counter_type_for_bytes.patch b/debian/patches/counter_type_for_bytes.patch
deleted file mode 100644
index 7763c9a..0000000
--- a/debian/patches/counter_type_for_bytes.patch
+++ /dev/null
@@ -1,15 +0,0 @@
-Index: openvpn-2.1.3/ssl.h
-===================================================================
---- openvpn-2.1.3.orig/ssl.h 2011-03-11 12:35:32.000000000 +0100
-+++ openvpn-2.1.3/ssl.h 2011-03-11 12:59:08.883318001 +0100
-@@ -378,8 +378,8 @@
-
- struct buffer_list *paybuf;
-
-- int n_bytes; /* how many bytes sent/recvd since last key exchange */
-- int n_packets; /* how many packets sent/recvd since last key exchange */
-+ counter_type n_bytes; /* how many bytes sent/recvd since last key exchange */
-+ counter_type n_packets; /* how many packets sent/recvd since last key exchange */
-
- /*
- * If bad username/password, TLS connection will come up but 'authenticated' will be false.
diff --git a/debian/patches/debian_openssl_vulnkeys.patch b/debian/patches/debian_openssl_vulnkeys.patch
deleted file mode 100644
index b0d3045..0000000
--- a/debian/patches/debian_openssl_vulnkeys.patch
+++ /dev/null
@@ -1,102 +0,0 @@
-Index: openvpn-2.1.3/init.c
-===================================================================
---- openvpn-2.1.3.orig/init.c 2010-07-21 21:08:41.000000000 +0200
-+++ openvpn-2.1.3/init.c 2010-09-29 13:11:02.373457337 +0200
-@@ -1796,6 +1796,29 @@
- const struct options *options = &c->options;
- ASSERT (options->shared_secret_file);
-
-+ /* CVE-2008-0166 (Debian weak key checks) */
-+ /* Only check if we can actually read the key file. Unless the file does not
-+ * exist in the first place, this should never happen (since static keys do
-+ * not work with multi-client mode), but we test it anyway to be on the safe
-+ * side and avoid wrong -vulnkey alerts. */
-+ if (access (options->shared_secret_file, R_OK) == 0)
-+ {
-+ struct argv argv = argv_new ();
-+ int ret;
-+ argv_printf (&argv, "/usr/sbin/openvpn-vulnkey -q %s", options->shared_secret_file);
-+ argv_msg (M_INFO, &argv);
-+ ret = openvpn_execve (&argv, c->c2.es, 0);
-+ if (WEXITSTATUS (ret) == 1)
-+ {
-+ msg (M_WARN, "******* WARNING *******: '%s' is a known vulnerable key. See 'man openvpn-vulnkey' for details.", options->shared_secret_file);
-+ }
-+ else if (WEXITSTATUS (ret) != 0)
-+ {
-+ msg (M_WARN, "******* WARNING *******: '%s' cannot be verified as a non-vulnerable key. See 'man openvpn-vulnkey' for details.", options->shared_secret_file);
-+ }
-+ argv_reset (&argv);
-+ }
-+
- init_crypto_pre (c, flags);
-
- /* Initialize packet ID tracking */
-@@ -1881,6 +1904,7 @@
- do_init_crypto_tls_c1 (struct context *c)
- {
- const struct options *options = &c->options;
-+ SSL *ssl;
-
- if (!c->c1.ks.ssl_ctx)
- {
-@@ -1920,6 +1944,59 @@
- /* Initialize PRNG with config-specified digest */
- prng_init (options->prng_hash, options->prng_nonce_secret_len);
-
-+ /* CVE-2008-0166 (Debian weak key checks)
-+ * Obtain the modulus and bits from the certificate that was initialized,
-+ * and send that to openssl-vulnkey.
-+ */
-+ ssl = SSL_new(c->c1.ks.ssl_ctx);
-+ if (ssl != NULL)
-+ {
-+ X509* cert = NULL;
-+ char *bn;
-+ int bits;
-+
-+ cert = SSL_get_certificate(ssl);
-+ if (cert != NULL)
-+ {
-+ EVP_PKEY *pkey = X509_get_pubkey (cert);
-+ if (pkey != NULL)
-+ {
-+ if (pkey->type == EVP_PKEY_RSA && pkey->pkey.rsa != NULL
-+ && pkey->pkey.rsa->n != NULL)
-+ {
-+ bits = BN_num_bits(pkey->pkey.rsa->n);
-+ bn = BN_bn2hex(pkey->pkey.rsa->n);
-+ }
-+ else if (pkey->type == EVP_PKEY_DSA && pkey->pkey.dsa != NULL
-+ && pkey->pkey.dsa->p != NULL)
-+ {
-+ bits = BN_num_bits(pkey->pkey.dsa->p);
-+ bn = BN_bn2hex(pkey->pkey.dsa->p);
-+ }
-+ if (bn != NULL)
-+ {
-+ int ret;
-+ struct argv argv = argv_new ();
-+ argv_printf (&argv, "/usr/bin/openssl-vulnkey -q -b %d -m %s", bits, bn);
-+ OPENSSL_free(bn);
-+ msg (M_INFO, "/usr/bin/openssl-vulnkey -q -b %d -m <modulus omitted>", bits);
-+ ret = openvpn_execve (&argv, NULL, 0);
-+ if (WEXITSTATUS (ret) == 1)
-+ {
-+ msg (M_WARN, "******* WARNING *******: '%s' is a known vulnerable key. See 'man openssl-vulnkey' for details.", options->priv_key_file);
-+ }
-+ else if (WEXITSTATUS (ret) != 0)
-+ {
-+ msg (M_WARN, "******* WARNING *******: '%s' cannot be verified as a non-vulnerable key. See 'man openssl-vulnkey' for details.", options->priv_key_file);
-+ }
-+ argv_reset (&argv);
-+ }
-+ EVP_PKEY_free (pkey);
-+ }
-+ }
-+ SSL_free(ssl);
-+ }
-+
- /* TLS handshake authentication (--tls-auth) */
- if (options->tls_auth_file)
- {
diff --git a/debian/patches/eurephia.patch b/debian/patches/eurephia.patch
deleted file mode 100644
index 78340df..0000000
--- a/debian/patches/eurephia.patch
+++ /dev/null
@@ -1,81 +0,0 @@
-Index: openvpn-2.2.0/README.eurephia
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ openvpn-2.2.0/README.eurephia 2011-05-10 16:33:23.900007905 +0200
-@@ -0,0 +1,24 @@
-+
-+ OpenVPN - eurephia version
-+==============================
-+
-+This is the official OpenVPN version, patched with a
-+patch to implement one needed feature for the eurephia
-+plug-in.
-+
-+All this patch does is to provide the plug-in environment
-+with a variable containing the SHA1 hash of the
-+certificates in use for the session.
-+
-+eurephia is an authentication and security plug-in which
-+enhances the security in OpenVPN even more. It provides
-+user name/password authentication, automatic blacklisting
-+of user account, certificates and IP addresses. In
-+provides in addition automatic updates of the iptables
-+firewall on Linux, with specific iptables profile per
-+user and certificate.
-+
-+For more information about eurephia, have a look at:
-+
-+ http://www.eurephia.net/
-+
-Index: openvpn-2.2.0/options.c
-===================================================================
---- openvpn-2.2.0.orig/options.c 2011-05-10 16:30:14.928001206 +0200
-+++ openvpn-2.2.0/options.c 2011-05-10 16:33:23.900007905 +0200
-@@ -10,6 +10,9 @@
- * Additions for eurephia plugin done by:
- * David Sommerseth <dazo@users.sourceforge.net> Copyright (C) 2009
- *
-+ * Additions for eurephia plugin done by:
-+ * David Sommerseth <dazo@users.sourceforge.net> Copyright (C) 2009
-+ *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
-@@ -85,6 +88,7 @@
- #ifdef USE_PF_INET6
- " [PF_INET6]"
- #endif
-+ " [eurephia]"
- " built on " __DATE__
- ;
-
-Index: openvpn-2.2.0/ssl.c
-===================================================================
---- openvpn-2.2.0.orig/ssl.c 2011-04-21 21:13:34.000000000 +0200
-+++ openvpn-2.2.0/ssl.c 2011-05-10 16:33:23.904007483 +0200
-@@ -11,6 +11,10 @@
- * David Sommerseth <dazo@users.sourceforge.net> Copyright (C) 2008-2009
- *
- *
-+ * Additions for eurephia plugin done by:
-+ * David Sommerseth <dazo@users.sourceforge.net> Copyright (C) 2008-2009
-+ *
-+ *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
-@@ -388,6 +392,14 @@
- }
- }
-
-+ /* export X509 cert SHA1 fingerprint */
-+ {
-+ struct gc_arena gc = gc_new ();
-+ openvpn_snprintf (envname, sizeof(envname), "tls_digest_%d", ctx->error_depth);
-+ setenv_str (opt->es, envname,
-+ format_hex_ex(ctx->current_cert->sha1_hash, SHA_DIGEST_LENGTH, 0, 1, ":", &gc));
-+ gc_free(&gc);
-+ }
- #if 0
- static void
- cert_hash_print (const struct cert_hash_set *chs, int msglevel)
diff --git a/debian/patches/ipv6-payload.patch b/debian/patches/ipv6-payload.patch
deleted file mode 100644
index cdc396a..0000000
--- a/debian/patches/ipv6-payload.patch
+++ /dev/null
@@ -1,4049 +0,0 @@
-Description: IPv6 payload support
-Author: Gert Döring
-URL: http://www.greenie.net/ipv6/openvpn.html
-Index: openvpn-2.2.1/ChangeLog.IPv6
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ openvpn-2.2.1/ChangeLog.IPv6 2011-12-13 12:24:54.608739565 +0100
-@@ -0,0 +1,394 @@
-+Do 31. Dez 15:32:40 CET 2009 Gert Doering
-+
-+ * Basic IPv6 p2mp functionality implemented
-+
-+ * new options:
-+ - server-ipv6
-+ - ifconfig-ipv6
-+ - ifconfig-ipv6-pool
-+ - route-ipv6
-+ - iroute-ipv6
-+
-+ * modules touched:
-+ - init.c: init & setup IPv6 route list & add/delete IPv6 routes
-+ - tun.c: add "ifconfig" and "route" handling for IPv6
-+ - multi.c: IPv6 ifconfig-pool assignments
-+ put to route-hash table
-+ push to client
-+ - pool.c: extend pools to handle IPv4+IPv6, and also return IPv6 address
-+ IPv6 address saved to file if ifconfig-pool-persist is set
-+ (but ignored on read due to the way pools work)
-+ - mroute.c: handle reading src/dst addresses from IPv6 packets
-+ (so multi.c can check against route-hash table)
-+ handle printing of IPv6 mroute_addr structure
-+ - helper.c: implement "server-ipv6" macro (->ifconfig-ipv6, pool, ...)
-+ - options.c: implement all the new options
-+ add helper functions for IPv6 address handling
-+ - forward.c: tell do_route() about IPv6 routes
-+ - route.c: handle IPv6 route lists + route option lists
-+ extend add_routes() to do IPv4 + IPv6 route lists
-+ extend delete_routes() to do IPv4 + IPv6 route lists
-+ implement add_route_ipv6(), delete_route_ipv6() to call
-+ system-dependend external program to do the work
-+ - push.c: handle pushing of "ifconfig-ipv6" option
-+ - socket.c: helper function to check & print IPv6 address strings
-+
-+ * known issues:
-+ - operating system support on all but Linux (ifconfig, route)
-+ - route-ipv6 gateway handling
-+ - iroute-ipv6 not implemented
-+ - TAP support: ifconfig, routing (route needs gateway!)
-+
-+ * release as patch 20091231-1
-+
-+Thu Dec 31 17:02:08 CET 2009
-+
-+ * NetBSD port (NetBSD 3.1 on Sparc64)
-+
-+ * mroute.c, socket.c: make byte/word access to in6_addr more portable
-+
-+ * tun.c: fix IPv6 ifconfig arguments on NetBSD
-+
-+ still doesn't work on NetBSD 3.1, "ifconfig tun0 inet6..." errors with
-+
-+ ifconfig: SIOCAIFADDR: Address family not supported by protocol family
-+
-+ (sys/net/if_tun.c, needs to be revision 1.80 or later, NetBSD PR 32944,
-+ included in NetBSD 4.0 and up)
-+
-+
-+Fri Jan 1 14:07:15 CET 2010
-+
-+ * FreeBSD port (FreeBSD 6.3-p12 on i386)
-+
-+ * tun.c: implement IPv6 ifconfig setting for FreeBSD
-+
-+ * route.c: fix %s/%s argument to IPv6 route add/delete command for *BSD
-+
-+ * TEST SUCCESS: FreeBSD 6.3-p12, server-ipv6, route-ipv6, ccd/iroute-ipv6
-+
-+ * multi.c: implement setting and deleting of iroute-ipv6
-+ (multi_add_iroutes(), multi_del_iroutes())
-+ * mroute.c: add mroute_helper_add_iroute6(), mroute_helper_del_iroute6()
-+ * mroute.h: add prototypes, increase MR_HELPER_NET_LEN to 129 (/0.../128)
-+ * multi.c: zeroize host part of IPv6 iroutes in multi_learn_in6_addr()
-+ * mroute.c: implement mroute_addr_mask_host_bits() for IPv6
-+
-+ * TEST SUCCESS: Linux 2.6.30 (Gentoo)/iproute2, server-ipv6, ccd/iroute-ipv6
-+
-+ * TEST SUCCESS: Linux 2.6.30 (Gentoo)/ifconfig, client-ipv6
-+
-+ * TEST FAIL: NetBSD 5.0, IPv6 client
-+ - "ifconfig tun0 .../64" does not create a "connected" route
-+ - adding routes fails
-+
-+ --> more work to do here.
-+
-+ * release as patch 20100101-1
-+
-+ * TEST FAIL:
-+ FreeBSD 6.3-p12 server "--topology subnet"
-+ Linux/ifconfig client
-+ - BSD sends ICMP6 neighbor solicitations, which are ignored by Linux
-+ - server tun interface is not in p2p mode, client tun interface *is*
-+
-+ * TEST SUCCESS: non-ipv6 enabled client -> "--server-ipv6" server
-+ (warnings in the log file, but no malfunctions)
-+
-+
-+Sat Jan 2 19:48:35 CET 2010
-+
-+ * tun.c: change "ipv6_support()", do not turn off tt->ipv6 unconditionally
-+ if we don't know about OS IPv6 support - just log warning
-+
-+ * tun.c: implement "ifconfig inet6" setting for MacOS X / Darwin
-+
-+ * route.c: split *BSD system dependent part of add/delete_route_ipv6()
-+ into FreeBSD/Dragonfly and NetBSD/Darwin/OpenBSD variants
-+ ("2001:db8::/64" vs. "2001:db8:: --prefixlen 64").
-+
-+ * tun.c: on MacOS X, NetBSD and OpenBSD, explicitely set on-link route
-+
-+ * TEST SUCCESS: MacOS X, client-ipv6 with route-ipv6
-+
-+
-+Sun Jan 3 10:55:31 CET 2010
-+
-+ * route.c: NetBSD fails with "-iface tun0", needs gateway address
-+ (assume that the same syntax is needed for OpenBSD)
-+
-+ * route.h: introduce "remote_endpoint_ipv6" into "struct route_ipv6_list"
-+
-+ * init.c: pass "ifconfig_ipv6_remote" as gateway to init_route_ipv6_list()
-+
-+ * route.c:
-+ - init_route_ipv6(): use "remote_endpoint_ipv6" as IPv6 gateway address
-+ if no gateway was specified explicitely
-+
-+ - init_route_ipv6_list(): fill in "remote_endpoint_ipv6", if parseable
-+
-+ - get rid of "GATEWAY-LESS ROUTE6" warning
-+
-+ * route.c, add_route_ipv6()
-+ - explicitely clear host bits of base address, to be able to more
-+ easily set up "connected" /64 routes on NetBSD+Darwin
-+
-+ - split system-dependent part between Darwin and NetBSD/OpenBSD
-+ (Darwin can use "-iface tun0", NetBSD/OpenBSD get gateway address)
-+
-+ - change Solaris comments from "known-broken" to "unknown"
-+
-+ * tun.c: rework NetBSD tunnel initialization and tun_read() / tun_write()
-+ to work the same way OpenBSD and NetBSD do - tunnel is put into
-+ "multi-af" mode, and all packet read/write activity is prepended by
-+ a 32 bit value specifying the address family.
-+
-+ * TEST SUCCESS: NetBSD 5.0/Sparc64: client-ipv6 with route-ipv6
-+
-+ * TEST SUCCESS: MacOS X 10.5: client-ipv6 with route-ipv6
-+
-+ * (RE-)TEST SUCCESS: Linux/iproute2: server-ipv6
-+ Linux/ifconfig: client-ipv6
-+ FreeBSD 6.3: server-ipv6
-+
-+ * release as patch 20100103-1
-+
-+ * options.c: document all new options in "--help"
-+
-+ * tun.c: fix typo in Solaris-specific section
-+
-+ * socket.h, socket.c: change u_int32_t to uint32_t
-+ (Solaris - and all the rest of the code uses "uintNN" anyway)
-+
-+Mon Jan 4 17:46:58 CET 2010
-+
-+ * socket.c: rework add_in6_addr() to use 32-bit access to struct in6_addr
-+ (Solaris has no 16-bit values in union, but this is more elegant as well)
-+
-+ * tun.c: fix "ifconfig inet6" command for Solaris
-+
-+ * tun.c: make sure "tun0 inet6" is unplumbed first, cleanup leftovers
-+
-+ * route.c: add routes with "metric 0" on solaris, otherwise they just
-+ don't work (someone who understands Solaris might want to fix this).
-+
-+ * Solaris "sort of" works now - ifconfig works, route add does not give
-+ errors, "netstat -rn" looks right, but packets are discarded unless
-+ the routes are installed with "metric 0". So we just use "metric 0"...
-+
-+ * CAVEAT: Solaris "ifconfig ... preferred" interferes with source address
-+ selection. So if there are any active IPv6 interfaces configured with
-+ "preferred", packets leaving out the tunnel will use the wrong source
-+ IPv6 address. Not fixable from within OpenVPN.
-+
-+ * CAVEAT2: Solaris insists on doing DHCPv6 on tun0 interfaces by default,
-+ so DHCPv6 solicitation packets will be seen. Since the server end has
-+ no idea what to do with them, they are a harmless nuisance. Fixable
-+ on the Solaris side via "ndpd.conf" (see ``man ifconfig'').
-+
-+ * release as patch 20100104-1
-+
-+Fri Jan 8 10:00:50 CET 2010
-+
-+ * import into git repository
-+
-+ * options.c: add sanity checks for most typical error cases
-+ (--ifconfig-ipv6-pool configured with no --ifconfig-ipv6, etc)
-+
-+ * options.c: modify get_ipv6_addr() to be more flexible about netbits
-+ (optional now, default to /64) and to return the address-without-netbits
-+ string now (-> for options that want the IPv6 address in printable
-+ form, but without /nn)
-+
-+ * options.c: modify --ifconfig-ipv6 to optionally accept /netbits,
-+ you can do now "ifconfig-ipv6 2001:df8::1/64 2001:df8::2" or just
-+ "ifconfig-ipv6 2001:df8::5 2001:df8::7", defaulting to /64
-+
-+ * options.h: add necessary structure elements for --ifconfig-ipv6-push
-+
-+ * options.c: implement "parse options" side of --ifconfig-ipv6-push
-+
-+Tue Jan 12 22:42:09 CET 2010
-+
-+ * tun.c: in TARGET_NETBSD #ifdef, distinguish between "old" code
-+ (IPv4 only, but unmodified read/write) and "new" code (multi-af,
-+ extra 32 bit AF on read/write of the tun interface) - pre-4.0
-+ NetBSD systems don't have TUNSIFHEAD, no way to have common code.
-+
-+ * TEST SUCCESS: NetBSD 5.0/Sparc64: client-ipv6 with route-ipv6 (v4+v6)
-+
-+ * TEST SUCCESS: NetBSD 3.1/Sparc64: client-ipv6 with route-ipv6 (v4-only)
-+
-+Thu Jan 14 15:41:50 CET 2010
-+
-+ * multi.c: if "--ifconfig-push" is used together with "--ifconfig-ipv6-pool"
-+ and no "--ifconfig-ipv6-push" is seen, issue warning - the current
-+ implementation of pools has IPv6 tied to IPv4, so if v4 does not use
-+ the pool, it breaks for IPv6. Not a *big* problem (since there is
-+ enough v6, just give those users a static v6 address as well), but needs
-+ to be pointed out clearly.
-+
-+ * release as patch 20100114-1
-+
-+Tue Feb 16 14:43:28 CET 2010
-+
-+ * options.c: print "IPv6 payload patch" release date in "--version"
-+
-+ * tun.c: undo change to init_tun() (moving "bool tun" and call to
-+ "is_tun_p2p()" further up) - it wasn't needed and breaks "make check"
-+
-+ * git stuff: rebase on David Sommerseth's openvpn-testing git tree
-+
-+ * release as patch 20100216-1
-+
-+Fri Feb 26 19:59:01 CET 2010
-+
-+ * init.c: initialize tuntap->ipv6 in do_init_tun() (to make sure it's
-+ always initialized early-enough, independent of the sequence of
-+ do_ifconfig()/open_tun() [see ifconfig_order() in tun.h])
-+
-+ * tun.c, init.c: remove "bool ipv6" argument to tuncfg(), open_tun()
-+ and open_tun_generic() - obsoleted by previous change
-+
-+ * tun.c: remove ipv6_support() - original purpose was unclear, and all
-+ current platforms (except linux-very-old) fully support IPv6 now :-)
-+
-+ * tun.c: initial implementation of "netsh" IPv6-ifconfig for Win32
-+
-+ * RE-TEST SUCCESS: Linux/i386/ifconfig, client-tun/net30, v4+v6
-+
-+Sun Feb 28 17:05:57 CET 2010
-+
-+ * tun.c: NetBSD dependent part: correct destroying/re-creation of tun dev
-+
-+ * tun.c: move adding of "connected" IPv6 prefix to new helper function,
-+ add_route_connected_v6_net()
-+
-+ * RE-TEST SUCCESS: NetBSD 5.0/Sparc64, client-tun/net30, v4+v6
-+
-+ * RE-TEST SUCCESS: NetBSD 3.1/Sparc64: client-tun/net30, v4-only
-+
-+ * RE-TEST SUCCESS: Linux/i386/iproute2: server-tun/net30, v4+v6
-+
-+ * tun.c: add #ifdef TARGET_DARWIN block for *_tun() functions, to
-+ be able to modify close_tun() for unconfiguring IPv6
-+
-+ * tun.c: on close_tun() on MacOS X, need to de-configure "lo0" route for
-+ configured IPv6 address
-+
-+ * RE-TEST SUCCESS: MacOS X (10.5)/i386: client-tun/net30, v4+v6
-+
-+ * route.c: implement ipv6 route adding / deletion via "netsh" for WIN32
-+
-+ * TEST FAIL: Windows XP fails, because the tun/tap driver does not
-+ forward IPv6 frames kernel->userland if in "tun" mode
-+
-+ * options.c: set IPv6 version to 20100228-1
-+
-+ * release as patch 20100228-1
-+
-+Sun Mar 7 19:17:33 CET 2010
-+
-+ * options.c: set IPv6 version to 20100307-1
-+
-+ * TODO.IPv6: add note about OpenBSD TODO (#16)
-+
-+ * route.c: set (and remove) "magic next hop" fe80::8 for IPv6 routes on
-+ Win32
-+
-+ * install-win32/settings.in: bump TAP driver version from 9.6 to 9.7
-+ and TAP_RELDATE to "07/03/2010"
-+
-+ * tap-win32/proto.h: add data types and definitions needed for IPv6
-+
-+ * tap-win32/types.h: add m_UserToTap_IPv6 ethernet header for IPv6 packets
-+
-+ * tap-win32/tapdrvr.c: implement support for IPv6 in TUN mode:
-+ - IPv6 packets User->OS need correct ether type
-+ - IPv6 packets OS->User get correctly forwarded
-+ - IPv6 neighbour discovery packets for "fe80::8" (magic address
-+ installed as route-nexthop by OpenVPN.exe) get answered locally
-+
-+ * TEST SUCCESS: WindowsXP/32bit: client-tun/net30, v4+v6
-+
-+ * tun.c: if IPv6 requested in TUN mode, and TUN/TAP driver version
-+ is older than 9.7, log warning and disable IPv6 (won't work anyway).
-+
-+ * release as patch 20100307-1
-+
-+Sat Jul 10 14:37:52 CEST 2010
-+
-+ * TEST SUCCESS: point-to-point tun mode with --ifconfig-ipv6 between
-+ Solaris10/sparc and Linux (Michal Ludvig)
-+ (using the whiteboard tun driver on Solaris, otherwise "no IPv6")
-+
-+Sun Aug 8 12:30:44 CEST 2010
-+
-+ * route.c: split NetBSD and OpenBSD parts of add_route_ipv6() and
-+ delete_route_ipv6(), implement OpenBSD variant
-+ (needs "-prefixlen nn" while NetBSD uses "/nn")
-+
-+ * tun.c: implement IPv6 ifconfig for OpenBSD
-+
-+ * tun.c: destroy tunX interface at tun_close() on OpenBSD (cleanup)
-+
-+ * TEST SUCCESS: OpenBSD 4.7: client-tun/net30, v4+v6
-+
-+Thu Sep 2 21:18:32 CEST 2010
-+
-+ * tun.c: the TAP binary in 2.2-beta3 has the IPv6 related changes, but
-+ the version number is 9.8 now -> check for 9.8, not 9.7
-+
-+Wed Sep 22 22:20:37 CEST 2010
-+
-+ * tun.c: bugfix for Linux/iproute2/"topology subnet". Works :-)
-+
-+ * TEST SUCCESS: Linux/ifconfig: client-tun/net30+subnet, v4+v6
-+
-+ * TEST SUCCESS: Linux/iproute2: client-tun/net30+subnet, v4+v6
-+
-+ * options.c: tag as 20100922-1 so "allmerged" users can see IPv6 change
-+
-+Fri Sep 24 17:57:41 CEST 2010
-+
-+ * TEST SUCCESS: Linux/<both>: client-tap, v4+v6, ping6 on connected addr
-+
-+ * TEST FAIL: Linux/<both>: client-tap, v6, route6 (gateway missing)
-+
-+Do 21. Okt 19:36:49 CEST 2010
-+
-+ * t_client.sh.in: cherrypick commit f25fe91a40aa3f and 6f1e61b41be52
-+ (proper exit codes to signal "SKIP" if we do not want to run)
-+
-+So 16. Jan 17:25:23 CET 2011
-+
-+ * tun.c, route.c: cherrypick 121755c2cb4891f and f0eac1a5979096c67
-+ (TAP driver and "topology subnet" support for Solaris)
-+
-+ * tun.c: add IPv6 configuration for TAP interfaces (<device>:1 inet6)
-+
-+ * tun.c: on close_tun on Solaris, unplumb IPv6 TUN or TAP interfaces
-+
-+ * TEST SUCCESS: OpenSolaris: client-tun, v4+v6
-+ TEST SUCCESS: OpenSolaris: client-tap, v4+v6, ping6 on connected addr
-+ TEST FAIL: OpenSolaris: client-tap, v6, route6 (gateway missing)
-+
-+So 24. Apr 16:51:45 CEST 2011
-+
-+ * rebase to "beta2.2" branch (at 2.2RC2 tag)
-+
-+ * mroute.c: remove mroute_helper_lock/_unlock() calls for IPv6
-+ * socket.c: remove locking with L_INET_NTOA mutex
-+ (all the threading stuff got removed by David Sommerseth for 2.2)
-+
-+ * mroute.c: remove duplicate mroute_helper_add_iroute6() and
-+ mroute_helper_del_iroute6() - "git rebase" artefact
-+
-+ * ChangeLog.IPv6 and TODO.IPv6: add to commit
-+
-+ * options.c: tag as 20110424-2 (2.2RC2)
-+
-+ * TEST SUCCESS: Linux/ifconfig: client-tun/net30+subnet, v4+v6
-+
-+ * TEST SUCCESS: Linux/iproute2: client-tun/net30+subnet, v4+v6
-+
-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:24:54.608739565 +0100
-@@ -0,0 +1,8 @@
-+This is an experimentally patched version of OpenVPN 2.1 with IPv6
-+payload support.
-+
-+Go here for release notes and documentation:
-+
-+ http://www.greenie.net/ipv6/openvpn.html
-+
-+Gert Doering, 31.12.2009
-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:24:54.609739553 +0100
-@@ -0,0 +1,149 @@
-+known issues for IPv6 payload support in OpenVPN
-+-----------------------------------------------
-+
-+1.) "--topology subnet" doesn't work together with IPv6 payload on FreeBSD
-+ (verified for FreeBSD server, Linux/ifconfig client, problems
-+ with ICMP6 neighbor solicitations from BSD not being answered by Linux)
-+
-+2.) NetBSD IPv6 support doesn't work
-+ ("connected" route is not auto-created, "route-ipv6" adding fails)
-+
-+ * fixed, 3.1.10 *
-+
-+3.) route deletion for IPv6 routes is not yet done
-+
-+ * fixed for configured routes, 3.1.10 *
-+ * missing for manual-ifconfig-connected (NetBSD, Darwin, Win32)
-+
-+4.) do "ifconfig tun0 inet6 unplumb" or "ifconfig tun0 destroy" for
-+ Solaris, *BSD, ... at program termination time, to clean up leftovers
-+ (unless tunnel persistance is desired).
-+
-+ For Solaris, only the "ipv6 tun0" is affected, for the *BSDs all tun0
-+ stay around.
-+
-+4a.) deconfigure IPv6 on tun interface on session termination, otherwise
-+ one could end up with something like this (on NetBSD):
-+
-+tun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1500
-+ inet 10.9.0.18 -> 10.9.0.17 netmask 0xffffffff
-+ inet6 fe80::a00:20ff:fece:d299%tun0 -> prefixlen 64 scopeid 0x3
-+ inet6 2001:608:4:eff::2000:3 -> prefixlen 64
-+ inet6 2001:608:4:eff::1:3 -> prefixlen 64
-+
-+ (pool was changed, previous address still active on tun0, breakage)
-+
-+ * semi-fixed for NetBSD, 28.2.10, always do tun0 destroy / tun0 create
-+ before actual ifconfig -- tunnel still lingers after OpenVPN quits
-+
-+4b.) verify this - on FreeBSD, tun0 is auto-destroyed if created by
-+ opening /dev/tun (and lingers if created by "ifconfig tun0 create")
-+
-+ -> use for persistant tunnels on not-linux?
-+
-+5.) add new option "ifconfig-ipv6-push"
-+ (per-client static IPv6 assignment, -> radiusplugin, etc)
-+
-+ * implemented, 14.1.10 *
-+
-+6.) add new option "route-ipv6-gateway"
-+
-+7.) add "full" gateway handling for IPv6 in route.c
-+ (right now, the routes are just sent down the tun interface, if the
-+ operating system in questions supports that, without care for the
-+ gateway address - which does not work for gateways that are supposed
-+ to point elsewhere. Also, it doesn't work for TAP interfaces.
-+
-+8.) full IPv6 support for TAP interfaces
-+ (main issue should be routes+gateway - and testing :-) )
-+
-+ test 2010/09/24: TAP itself works on linux/ifconfig+iproute2, but
-+ route-via-tap doesn't work at all (route points to "tap0" which fails)
-+
-+17:51:14.075412 fe:ab:6e:c5:53:71 > 33:33:ff:00:00:01, ethertype IPv6 (0x86dd), length 86: 2001:608:4:a053::1:0 > ff02::1:ff00:1: ICMP6, neighbor solicitation, who has 2001:608:4:a001::1, length 32
-+
-+ how is iroute-via-tap supposed to work??
-+
-+9.) verify that iroute-ipv6 and route-ipv6 interact in the same way as
-+ documented for iroute/route:
-+
-+ A's subnet, OpenVPN must push this route to all clients
-+ EXCEPT for A, since the subnet is already owned by A.
-+ OpenVPN accomplishes this by not
-+ not pushing a route to a client
-+ if it matches one of the client's iroutes.
-+
-+10.) extend "ifconfig-ipv6" to handle specification of /netbits, pushing
-+ of /netbits, and correctly ifconfig'ing this
-+ (default, if not specified: /64)
-+
-+11.) do not add ipv6-routes if tun-ipv6 is not set - complain instead
-+
-+ * done * 12.1.10
-+
-+12.) handle incoming [::] and [fe80:...] packets in tun-p2mp MULTI mode
-+ (most likely those are DAD packets)
-+ silently ignore DAD?
-+ Or accept-and-forward iff (multicast && client2client)?
-+ handle NS/NA
-+
-+13.) from Martin List-Petersen:
-+
-+ One thing, and I guess this requires modifications in
-+ network-manager-openvpn: It also works, BUT ignores "push
-+ route-ipv6-gateway" and "push route-ipv6 ...." (obviously routes pushed
-+ from the server) entirely.
-+
-+14.) from ##openvpn-discussion:
-+
-+ new features should be #ifdef'ed
-+
-+ (check whether this is feasible at all)
-+
-+15.) IPv6 related environment variables
-+
-+ - document all of them in openvpn.8
-+ - make sure that all existing IPv4 stuff has IPv6 counterparts
-+
-+16.) OpenBSD
-+ - implement ifconfig/route for IPv6
-+ - revert ifconfig/open_tun order to "normal" (separate commit!!!)
-+ (openvpn-devel, Subject: OpenBSD)
-+ - test
-+
-+17.) client-option (Elwood)
-+ - ignore-v6-push-options yes/no
-+ - ignore-v6-route-push ("as for IPv4 routes")
-+
-+18.) fail-save? "what if 'ip -6 addr add' fails" -> fail, or fallback to v4?
-+ (-> recomment setting "ignore-v6-push-options yes")
-+
-+19.) safety check: if connecting over IPv6 (v6 transport) and the pushed
-+ route-ipv6 network encompasses the server IPv6 address, make sure
-+ we at least log a warning (until we can fiddle with external routing
-+ to make this work correctly).
-+
-+20.) show "route add" / "route delete" commands for IPv6 in log file
-+ (we show the "ifconfig" commands, so why not the routes?)
-+
-+ 2010-08-07: this is a null-feature - it's already there, but with
-+ different debug level (M_INFO vs. D_ROUTE) so user
-+ didn't notice
-+
-+21.) enable ipv6-only server operations
-+ - decouple ipv6 pool handling from ipv4 pool
-+ - make sure Rest of OpenVPN doesn't assume "there will always be IPv4"
-+
-+22.) implement --learn-address for IPv6
-+
-+23.) FreeBSD 8 seems to require explicit setting of the "ifconfig" IPv6
-+ route, while FreeBSD 6+7 don't --> more testing, and code fix
-+
-+ workaround for the time being: just add
-+
-+ server-ipv6 2001:608:4:a051::/64
-+ route-ipv6 2001:608:4:a051::/64
-+
-+ to the config
-+
-+ (problem + workaround applies both to tun and tap style devices)
-Index: openvpn-2.2.1/forward.c
-===================================================================
---- openvpn-2.2.1.orig/forward.c 2011-06-24 08:13:38.000000000 +0200
-+++ openvpn-2.2.1/forward.c 2011-12-13 12:24:54.611739529 +0100
-@@ -262,7 +262,8 @@
- static void
- check_add_routes_action (struct context *c, const bool errors)
- {
-- do_route (&c->options, c->c1.route_list, c->c1.tuntap, c->plugins, c->c2.es);
-+ do_route (&c->options, c->c1.route_list, c->c1.route_ipv6_list,
-+ c->c1.tuntap, c->plugins, c->c2.es);
- update_time ();
- event_timeout_clear (&c->c2.route_wakeup);
- event_timeout_clear (&c->c2.route_wakeup_expire);
-Index: openvpn-2.2.1/helper.c
-===================================================================
---- openvpn-2.2.1.orig/helper.c 2011-06-24 08:13:38.000000000 +0200
-+++ openvpn-2.2.1/helper.c 2011-12-13 12:24:54.612739516 +0100
-@@ -142,6 +142,55 @@
-
- #if P2MP
- #if P2MP_SERVER
-+
-+ /*
-+ *
-+ * HELPER DIRECTIVE for IPv6
-+ *
-+ * server-ipv6 2001:db8::/64
-+ *
-+ * EXPANDS TO:
-+ *
-+ * tun-ipv6
-+ * push "tun-ipv6"
-+ * ifconfig-ipv6 2001:db8::1 2001:db8::2
-+ * if !nopool:
-+ * ifconfig-ipv6-pool 2001:db8::1:0/64
-+ *
-+ */
-+ if ( o->server_ipv6_defined )
-+ {
-+ if ( ! o->server_defined )
-+ {
-+ msg (M_USAGE, "--server-ipv6 must be used together with --server");
-+ }
-+ if ( o->server_flags & SF_NOPOOL )
-+ {
-+ msg( M_USAGE, "--server-ipv6 is incompatible with 'nopool' option" );
-+ }
-+ if ( o->ifconfig_ipv6_pool_defined )
-+ {
-+ msg( M_USAGE, "--server-ipv6 already defines an ifconfig-ipv6-pool, so you can't also specify --ifconfig-pool explicitly");
-+ }
-+
-+ /* local ifconfig is "base address + 1" and "+2" */
-+ o->ifconfig_ipv6_local =
-+ print_in6_addr( add_in6_addr( o->server_network_ipv6, 1), 0, &o->gc );
-+ o->ifconfig_ipv6_remote =
-+ print_in6_addr( add_in6_addr( o->server_network_ipv6, 2), 0, &o->gc );
-+
-+ /* pool starts at "base address + 0x10000" */
-+ ASSERT( o->server_netbits_ipv6 < 96 ); /* want 32 bits */
-+ o->ifconfig_ipv6_pool_defined = true;
-+ o->ifconfig_ipv6_pool_base =
-+ add_in6_addr( o->server_network_ipv6, 0x10000 );
-+ o->ifconfig_ipv6_pool_netbits = o->server_netbits_ipv6;
-+
-+ o->tun_ipv6 = true;
-+
-+ push_option( o, "tun-ipv6", M_USAGE );
-+ }
-+
- /*
- *
- * HELPER DIRECTIVE:
-Index: openvpn-2.2.1/init.c
-===================================================================
---- openvpn-2.2.1.orig/init.c 2011-12-13 12:23:07.000000000 +0100
-+++ openvpn-2.2.1/init.c 2011-12-13 12:24:54.615739477 +0100
-@@ -843,7 +843,7 @@
- msg (M_FATAL|M_OPTERR,
- "options --mktun or --rmtun should only be used together with --dev");
- tuncfg (options->dev, options->dev_type, options->dev_node,
-- options->tun_ipv6, options->persist_mode,
-+ options->persist_mode,
- options->username, options->groupname, &options->tuntap_options);
- if (options->persist_mode && options->lladdr)
- set_lladdr(options->dev, options->lladdr, NULL);
-@@ -1066,6 +1066,8 @@
- {
- if (c->options.routes && !c->c1.route_list)
- c->c1.route_list = new_route_list (c->options.max_routes, &c->gc);
-+ if (c->options.routes_ipv6 && !c->c1.route_ipv6_list)
-+ c->c1.route_ipv6_list = new_route_ipv6_list (c->options.max_routes, &c->gc);
- }
-
-
-@@ -1108,6 +1110,45 @@
- }
- }
-
-+static void
-+do_init_route_ipv6_list (const struct options *options,
-+ struct route_ipv6_list *route_ipv6_list,
-+ bool fatal,
-+ struct env_set *es)
-+{
-+ const char *gw = NULL;
-+ int dev = dev_type_enum (options->dev, options->dev_type);
-+ int metric = 0;
-+
-+ if (dev != DEV_TYPE_TUN )
-+ msg( M_WARN, "IPv6 routes on TAP devices are going to fail on some platforms (need gateway spec)" ); /* TODO-GERT */
-+
-+ gw = options->ifconfig_ipv6_remote; /* default GW = remote end */
-+#if 0 /* not yet done for IPv6 - TODO!*/
-+ if ( options->route_ipv6_default_gateway ) /* override? */
-+ gw = options->route_ipv6_default_gateway;
-+#endif
-+
-+ if (options->route_default_metric)
-+ metric = options->route_default_metric;
-+
-+ if (!init_route_ipv6_list (route_ipv6_list,
-+ options->routes_ipv6,
-+ gw,
-+ metric,
-+ es))
-+ {
-+ if (fatal)
-+ openvpn_exit (OPENVPN_EXIT_STATUS_ERROR); /* exit point */
-+ }
-+ else
-+ {
-+ /* copy routes to environment */
-+ setenv_routes_ipv6 (es, route_ipv6_list);
-+ }
-+}
-+
-+
- /*
- * Called after all initialization has been completed.
- */
-@@ -1177,12 +1218,13 @@
- void
- do_route (const struct options *options,
- struct route_list *route_list,
-+ struct route_ipv6_list *route_ipv6_list,
- const struct tuntap *tt,
- const struct plugin_list *plugins,
- struct env_set *es)
- {
-- if (!options->route_noexec && route_list)
-- add_routes (route_list, tt, ROUTE_OPTION_FLAGS (options), es);
-+ if (!options->route_noexec && ( route_list || route_ipv6_list ) )
-+ add_routes (route_list, route_ipv6_list, tt, ROUTE_OPTION_FLAGS (options), es);
-
- if (plugin_defined (plugins, OPENVPN_PLUGIN_ROUTE_UP))
- {
-@@ -1239,11 +1281,16 @@
- c->options.topology,
- c->options.ifconfig_local,
- c->options.ifconfig_remote_netmask,
-+ c->options.ifconfig_ipv6_local,
-+ c->options.ifconfig_ipv6_remote,
- addr_host (&c->c1.link_socket_addr.local),
- addr_host (&c->c1.link_socket_addr.remote),
- !c->options.ifconfig_nowarn,
- c->c2.es);
-
-+ /* flag tunnel for IPv6 config if --tun-ipv6 is set */
-+ c->c1.tuntap->ipv6 = c->options.tun_ipv6;
-+
- init_tun_post (c->c1.tuntap,
- &c->c2.frame,
- &c->options.tuntap_options);
-@@ -1275,6 +1322,8 @@
- /* parse and resolve the route option list */
- if (c->options.routes && c->c1.route_list && c->c2.link_socket)
- do_init_route_list (&c->options, c->c1.route_list, &c->c2.link_socket->info, false, c->c2.es);
-+ if (c->options.routes_ipv6 && c->c1.route_ipv6_list )
-+ do_init_route_ipv6_list (&c->options, c->c1.route_ipv6_list, false, c->c2.es);
-
- /* do ifconfig */
- if (!c->options.ifconfig_noexec
-@@ -1291,7 +1340,7 @@
-
- /* open the tun device */
- open_tun (c->options.dev, c->options.dev_type, c->options.dev_node,
-- c->options.tun_ipv6, c->c1.tuntap);
-+ c->c1.tuntap);
-
- /* set the hardware address */
- if (c->options.lladdr)
-@@ -1320,7 +1369,8 @@
-
- /* possibly add routes */
- if (!c->options.route_delay_defined)
-- do_route (&c->options, c->c1.route_list, c->c1.tuntap, c->plugins, c->c2.es);
-+ do_route (&c->options, c->c1.route_list, c->c1.route_ipv6_list,
-+ c->c1.tuntap, c->plugins, c->c2.es);
-
- /*
- * Did tun/tap driver give us an MTU?
-@@ -1394,8 +1444,9 @@
- #endif
-
- /* delete any routes we added */
-- if (c->c1.route_list)
-- delete_routes (c->c1.route_list, c->c1.tuntap, ROUTE_OPTION_FLAGS (&c->options), c->c2.es);
-+ if (c->c1.route_list || c->c1.route_ipv6_list )
-+ delete_routes (c->c1.route_list, c->c1.route_ipv6_list,
-+ c->c1.tuntap, ROUTE_OPTION_FLAGS (&c->options), c->c2.es);
-
- /* actually close tun/tap device based on --down-pre flag */
- if (!c->options.down_pre)
-Index: openvpn-2.2.1/init.h
-===================================================================
---- openvpn-2.2.1.orig/init.h 2011-06-24 08:13:38.000000000 +0200
-+++ openvpn-2.2.1/init.h 2011-12-13 12:24:54.615739477 +0100
-@@ -63,6 +63,7 @@
-
- void do_route (const struct options *options,
- struct route_list *route_list,
-+ struct route_ipv6_list *route_ipv6_list,
- const struct tuntap *tt,
- const struct plugin_list *plugins,
- struct env_set *es);
-Index: openvpn-2.2.1/misc.c
-===================================================================
---- openvpn-2.2.1.orig/misc.c 2011-06-24 08:13:38.000000000 +0200
-+++ openvpn-2.2.1/misc.c 2011-12-13 12:24:54.617739452 +0100
-@@ -1001,7 +1001,9 @@
- {
- const char *str = construct_name_value (name_tmp, val_tmp, &gc);
- env_set_add (es, str);
-- /*msg (M_INFO, "SETENV_ES '%s'", str);*/
-+#if DEBUG_VERBOSE_SETENV
-+ msg (M_INFO, "SETENV_ES '%s'", str);
-+#endif
- }
- else
- env_set_del (es, name_tmp);
-Index: openvpn-2.2.1/mroute.c
-===================================================================
---- openvpn-2.2.1.orig/mroute.c 2011-12-13 12:23:07.000000000 +0100
-+++ openvpn-2.2.1/mroute.c 2011-12-13 12:24:54.618739440 +0100
-@@ -88,12 +88,33 @@
- }
- }
-
-+static inline void
-+mroute_get_in6_addr (struct mroute_addr *ma, const struct in6_addr src, unsigned int mask)
-+{
-+ if (ma)
-+ {
-+ ma->type = MR_ADDR_IPV6 | mask;
-+ ma->netbits = 0;
-+ ma->len = 16;
-+ *(struct in6_addr *)ma->addr = src;
-+ }
-+}
-+
- static inline bool
- mroute_is_mcast (const in_addr_t addr)
- {
- return ((addr & htonl(IP_MCAST_SUBNET_MASK)) == htonl(IP_MCAST_NETWORK));
- }
-
-+/* RFC 4291, 2.7, "binary 11111111 at the start of an address identifies
-+ * the address as being a multicast address"
-+ */
-+static inline bool
-+mroute_is_mcast_ipv6 (const struct in6_addr addr)
-+{
-+ return (addr.s6_addr[0] == 0xff);
-+}
-+
- #ifdef ENABLE_PF
-
- static unsigned int
-@@ -155,10 +176,29 @@
- }
- break;
- case 6:
-- {
-- msg (M_WARN, "Need IPv6 code in mroute_extract_addr_from_packet");
-- break;
-- }
-+ if (BLEN (buf) >= (int) sizeof (struct openvpn_ipv6hdr))
-+ {
-+ const struct openvpn_ipv6hdr *ipv6 = (const struct openvpn_ipv6hdr *) BPTR (buf);
-+#if 0 /* very basic debug */
-+ struct gc_arena gc = gc_new ();
-+ msg( M_INFO, "IPv6 packet! src=%s, dst=%s",
-+ print_in6_addr( ipv6->saddr, 0, &gc ),
-+ print_in6_addr( ipv6->daddr, 0, &gc ));
-+ gc_free (&gc);
-+#endif
-+
-+ mroute_get_in6_addr (src, ipv6->saddr, 0);
-+ mroute_get_in6_addr (dest, ipv6->daddr, 0);
-+
-+ if (mroute_is_mcast_ipv6 (ipv6->daddr))
-+ ret |= MROUTE_EXTRACT_MCAST;
-+
-+ ret |= MROUTE_EXTRACT_SUCCEEDED;
-+ }
-+ break;
-+ default:
-+ msg (M_WARN, "IP packet with unknown IP version=%d seen",
-+ OPENVPN_IPH_GET_VER (*BPTR(buf)));
- }
- }
- return ret;
-@@ -274,14 +314,36 @@
- * Zero off the host bits in an address, leaving
- * only the network bits, using the netbits member of
- * struct mroute_addr as the controlling parameter.
-+ *
-+ * TODO: this is called for route-lookup for every yet-unhashed
-+ * destination address, so for lots of active net-iroutes, this
-+ * might benefit from some "zeroize 32 bit at a time" improvements
- */
- void
- mroute_addr_mask_host_bits (struct mroute_addr *ma)
- {
- in_addr_t addr = ntohl(*(in_addr_t*)ma->addr);
-- ASSERT ((ma->type & MR_ADDR_MASK) == MR_ADDR_IPV4);
-- addr &= netbits_to_netmask (ma->netbits);
-- *(in_addr_t*)ma->addr = htonl (addr);
-+ if ((ma->type & MR_ADDR_MASK) == MR_ADDR_IPV4)
-+ {
-+ addr &= netbits_to_netmask (ma->netbits);
-+ *(in_addr_t*)ma->addr = htonl (addr);
-+ }
-+ else if ((ma->type & MR_ADDR_MASK) == MR_ADDR_IPV6)
-+ {
-+ int byte = ma->len-1; /* rightmost byte in address */
-+ int bits_to_clear = 128 - ma->netbits;
-+
-+ while( byte >= 0 && bits_to_clear > 0 )
-+ {
-+ if ( bits_to_clear >= 8 )
-+ { ma->addr[byte--] = 0; bits_to_clear -= 8; }
-+ else
-+ { ma->addr[byte--] &= (~0 << bits_to_clear); bits_to_clear = 0; }
-+ }
-+ ASSERT( bits_to_clear == 0 );
-+ }
-+ else
-+ ASSERT(0);
- }
-
- /*
-@@ -359,17 +421,24 @@
- }
- break;
- case MR_ADDR_IPV6:
-- buf_printf (&out, "IPV6");
-- break;
-- default:
-- buf_printf (&out, "UNKNOWN");
-- break;
-- }
-- return BSTR (&out);
-- }
-- else
-- return "[NULL]";
--}
-+ {
-+ buf_printf (&out, "%s",
-+ print_in6_addr( *(struct in6_addr*)&maddr.addr, 0, gc));
-+ if (maddr.type & MR_WITH_NETBITS)
-+ {
-+ buf_printf (&out, "/%d", maddr.netbits);
-+ }
-+ }
-+ break;
-+ default:
-+ buf_printf (&out, "UNKNOWN");
-+ break;
-+ }
-+ return BSTR (&out);
-+ }
-+ else
-+ return "[NULL]";
-+ }
-
- /*
- * mroute_helper's main job is keeping track of
-@@ -439,6 +508,40 @@
- mroute_helper_regenerate (mh);
- }
- }
-+
-+/* this is a bit inelegant, we really should have a helper to that
-+ * is only passed the netbits value, and not the whole struct iroute *
-+ * - thus one helper could do IPv4 and IPv6. For the sake of "not change
-+ * code unrelated to IPv4" this is left for later cleanup, for now.
-+ */
-+void
-+mroute_helper_add_iroute6 (struct mroute_helper *mh,
-+ const struct iroute_ipv6 *ir6)
-+{
-+ if (ir6->netbits >= 0)
-+ {
-+ ASSERT (ir6->netbits < MR_HELPER_NET_LEN);
-+ ++mh->cache_generation;
-+ ++mh->net_len_refcount[ir6->netbits];
-+ if (mh->net_len_refcount[ir6->netbits] == 1)
-+ mroute_helper_regenerate (mh);
-+ }
-+}
-+
-+void
-+mroute_helper_del_iroute6 (struct mroute_helper *mh,
-+ const struct iroute_ipv6 *ir6)
-+{
-+ if (ir6->netbits >= 0)
-+ {
-+ ASSERT (ir6->netbits < MR_HELPER_NET_LEN);
-+ ++mh->cache_generation;
-+ --mh->net_len_refcount[ir6->netbits];
-+ ASSERT (mh->net_len_refcount[ir6->netbits] >= 0);
-+ if (!mh->net_len_refcount[ir6->netbits])
-+ mroute_helper_regenerate (mh);
-+ }
-+}
-
- void
- mroute_helper_free (struct mroute_helper *mh)
-Index: openvpn-2.2.1/mroute.h
-===================================================================
---- openvpn-2.2.1.orig/mroute.h 2011-06-24 08:13:38.000000000 +0200
-+++ openvpn-2.2.1/mroute.h 2011-12-13 12:24:54.618739440 +0100
-@@ -85,7 +85,7 @@
- /*
- * Number of bits in an address. Should be raised for IPv6.
- */
--#define MR_HELPER_NET_LEN 32
-+#define MR_HELPER_NET_LEN 129
-
- /*
- * Used to help maintain CIDR routing table.
-@@ -127,6 +127,8 @@
- void mroute_helper_free (struct mroute_helper *mh);
- void mroute_helper_add_iroute (struct mroute_helper *mh, const struct iroute *ir);
- void mroute_helper_del_iroute (struct mroute_helper *mh, const struct iroute *ir);
-+void mroute_helper_add_iroute6 (struct mroute_helper *mh, const struct iroute_ipv6 *ir6);
-+void mroute_helper_del_iroute6 (struct mroute_helper *mh, const struct iroute_ipv6 *ir6);
-
- /*
- * Given a raw packet in buf, return the src and dest
-Index: openvpn-2.2.1/multi.c
-===================================================================
---- openvpn-2.2.1.orig/multi.c 2011-12-13 12:23:07.000000000 +0100
-+++ openvpn-2.2.1/multi.c 2011-12-13 12:24:54.621739404 +0100
-@@ -316,25 +316,18 @@
- */
- if (t->options.ifconfig_pool_defined)
- {
-- if (dev == DEV_TYPE_TAP)
-- {
-- m->ifconfig_pool = ifconfig_pool_init (IFCONFIG_POOL_INDIV,
-- t->options.ifconfig_pool_start,
-- t->options.ifconfig_pool_end,
-- t->options.duplicate_cn);
-- }
-- else if (dev == DEV_TYPE_TUN)
-- {
-- m->ifconfig_pool = ifconfig_pool_init (
-- (t->options.topology == TOP_NET30) ? IFCONFIG_POOL_30NET : IFCONFIG_POOL_INDIV,
-- t->options.ifconfig_pool_start,
-- t->options.ifconfig_pool_end,
-- t->options.duplicate_cn);
-- }
-- else
-- {
-- ASSERT (0);
-- }
-+ int pool_type = IFCONFIG_POOL_INDIV;
-+
-+ if ( dev == DEV_TYPE_TUN && t->options.topology == TOP_NET30 )
-+ pool_type = IFCONFIG_POOL_30NET;
-+
-+ m->ifconfig_pool = ifconfig_pool_init (pool_type,
-+ t->options.ifconfig_pool_start,
-+ t->options.ifconfig_pool_end,
-+ t->options.duplicate_cn,
-+ t->options.ifconfig_ipv6_pool_defined,
-+ t->options.ifconfig_ipv6_pool_base,
-+ t->options.ifconfig_ipv6_pool_netbits );
-
- /* reload pool data from file */
- if (t->c1.ifconfig_pool_persist)
-@@ -429,10 +422,14 @@
- struct multi_instance *mi)
- {
- const struct iroute *ir;
-+ const struct iroute_ipv6 *ir6;
- if (TUNNEL_TYPE (mi->context.c1.tuntap) == DEV_TYPE_TUN)
- {
- for (ir = mi->context.options.iroutes; ir != NULL; ir = ir->next)
- mroute_helper_del_iroute (m->route_helper, ir);
-+
-+ for ( ir6 = mi->context.options.iroutes_ipv6; ir6 != NULL; ir6 = ir6->next )
-+ mroute_helper_del_iroute6 (m->route_helper, ir6);
- }
- }
-
-@@ -1078,6 +1075,37 @@
- }
- }
-
-+static struct multi_instance *
-+multi_learn_in6_addr (struct multi_context *m,
-+ struct multi_instance *mi,
-+ struct in6_addr a6,
-+ int netbits, /* -1 if host route, otherwise # of network bits in address */
-+ bool primary)
-+{
-+ struct mroute_addr addr;
-+
-+ addr.len = 16;
-+ addr.type = MR_ADDR_IPV6;
-+ addr.netbits = 0;
-+ memcpy( &addr.addr, &a6, sizeof(a6) );
-+
-+ if (netbits >= 0)
-+ {
-+ addr.type |= MR_WITH_NETBITS;
-+ addr.netbits = (uint8_t) netbits;
-+ mroute_addr_mask_host_bits( &addr );
-+ }
-+
-+ {
-+ struct multi_instance *owner = multi_learn_addr (m, mi, &addr, 0);
-+#ifdef MANAGEMENT_DEF_AUTH
-+ if (management && owner)
-+ management_learn_addr (management, &mi->context.c2.mda_context, &addr, primary);
-+#endif
-+ return owner;
-+ }
-+}
-+
- /*
- * A new client has connected, add routes (server -> client)
- * to internal routing table.
-@@ -1088,6 +1116,7 @@
- {
- struct gc_arena gc = gc_new ();
- const struct iroute *ir;
-+ const struct iroute_ipv6 *ir6;
- if (TUNNEL_TYPE (mi->context.c1.tuntap) == DEV_TYPE_TUN)
- {
- mi->did_iroutes = true;
-@@ -1107,6 +1136,22 @@
-
- multi_learn_in_addr_t (m, mi, ir->network, ir->netbits, false);
- }
-+ for ( ir6 = mi->context.options.iroutes_ipv6; ir6 != NULL; ir6 = ir6->next )
-+ {
-+ if (ir6->netbits >= 0)
-+ msg (D_MULTI_LOW, "MULTI: internal route %s/%d -> %s",
-+ print_in6_addr (ir6->network, 0, &gc),
-+ ir6->netbits,
-+ multi_instance_string (mi, false, &gc));
-+ else
-+ msg (D_MULTI_LOW, "MULTI: internal route %s -> %s",
-+ print_in6_addr (ir6->network, 0, &gc),
-+ multi_instance_string (mi, false, &gc));
-+
-+ mroute_helper_add_iroute6 (m->route_helper, ir6);
-+
-+ multi_learn_in6_addr (m, mi, ir6->network, ir6->netbits, false);
-+ }
- }
- gc_free (&gc);
- }
-@@ -1192,21 +1237,37 @@
- mi->context.c2.push_ifconfig_defined = true;
- mi->context.c2.push_ifconfig_local = mi->context.options.push_ifconfig_local;
- mi->context.c2.push_ifconfig_remote_netmask = mi->context.options.push_ifconfig_remote_netmask;
-+
-+ /* the current implementation does not allow "static IPv4, pool IPv6",
-+ * (see below) so issue a warning if that happens - don't break the
-+ * session, though, as we don't even know if this client WANTS IPv6
-+ */
-+ if ( mi->context.c1.tuntap->ipv6 &&
-+ mi->context.options.ifconfig_ipv6_pool_defined &&
-+ ! mi->context.options.push_ifconfig_ipv6_defined )
-+ {
-+ msg( M_INFO, "MULTI_sva: WARNING: if --ifconfig-push is used for IPv4, automatic IPv6 assignment from --ifconfig-ipv6-pool does not work. Use --ifconfig-ipv6-push for IPv6 then." );
-+ }
- }
- else if (m->ifconfig_pool && mi->vaddr_handle < 0) /* otherwise, choose a pool address */
- {
- in_addr_t local=0, remote=0;
-+ struct in6_addr remote_ipv6;
- const char *cn = NULL;
-
- if (!mi->context.options.duplicate_cn)
- cn = tls_common_name (mi->context.c2.tls_multi, true);
-
-- mi->vaddr_handle = ifconfig_pool_acquire (m->ifconfig_pool, &local, &remote, cn);
-+ mi->vaddr_handle = ifconfig_pool_acquire (m->ifconfig_pool, &local, &remote, &remote_ipv6, cn);
- if (mi->vaddr_handle >= 0)
- {
- const int tunnel_type = TUNNEL_TYPE (mi->context.c1.tuntap);
- const int tunnel_topology = TUNNEL_TOPOLOGY (mi->context.c1.tuntap);
-
-+ msg( M_INFO, "MULTI_sva: pool returned IPv4=%s, IPv6=%s",
-+ print_in_addr_t( remote, 0, &gc ),
-+ print_in6_addr( remote_ipv6, 0, &gc ) );
-+
- /* set push_ifconfig_remote_netmask from pool ifconfig address(es) */
- mi->context.c2.push_ifconfig_local = remote;
- if (tunnel_type == DEV_TYPE_TAP || (tunnel_type == DEV_TYPE_TUN && tunnel_topology == TOP_SUBNET))
-@@ -1228,12 +1289,46 @@
- else
- msg (D_MULTI_ERRORS, "MULTI: no --ifconfig-pool netmask parameter is available to push to %s",
- multi_instance_string (mi, false, &gc));
-+
-+ if ( mi->context.options.ifconfig_ipv6_pool_defined )
-+ {
-+ mi->context.c2.push_ifconfig_ipv6_local = remote_ipv6;
-+ mi->context.c2.push_ifconfig_ipv6_remote =
-+ mi->context.c1.tuntap->local_ipv6;
-+ mi->context.c2.push_ifconfig_ipv6_netbits =
-+ mi->context.options.ifconfig_ipv6_pool_netbits;
-+ mi->context.c2.push_ifconfig_ipv6_defined = true;
-+ }
- }
- else
- {
- msg (D_MULTI_ERRORS, "MULTI: no free --ifconfig-pool addresses are available");
- }
- }
-+
-+ /* IPv6 push_ifconfig is a bit problematic - since IPv6 shares the
-+ * pool handling with IPv4, the combination "static IPv4, dynamic IPv6"
-+ * will fail (because no pool will be allocated in this case).
-+ * OTOH, this doesn't make too much sense in reality - and the other
-+ * way round ("dynamic IPv4, static IPv6") or "both static" makes sense
-+ * -> and so it's implemented right now
-+ */
-+ if ( mi->context.c1.tuntap->ipv6 &&
-+ mi->context.options.push_ifconfig_ipv6_defined )
-+ {
-+ mi->context.c2.push_ifconfig_ipv6_local =
-+ mi->context.options.push_ifconfig_ipv6_local;
-+ mi->context.c2.push_ifconfig_ipv6_remote =
-+ mi->context.options.push_ifconfig_ipv6_remote;
-+ mi->context.c2.push_ifconfig_ipv6_netbits =
-+ mi->context.options.push_ifconfig_ipv6_netbits;
-+ mi->context.c2.push_ifconfig_ipv6_defined = true;
-+
-+ msg( M_INFO, "MULTI_sva: push_ifconfig_ipv6 %s/%d",
-+ print_in6_addr( mi->context.c2.push_ifconfig_ipv6_local, 0, &gc ),
-+ mi->context.c2.push_ifconfig_ipv6_netbits );
-+ }
-+
- gc_free (&gc);
- }
-
-@@ -1272,6 +1367,11 @@
- SA_SET_IF_NONZERO);
- }
- }
-+
-+ /* TODO: I'm not exactly sure what these environment variables are
-+ * used for, but if we have them for IPv4, we should also have
-+ * them for IPv6, no?
-+ */
- }
-
- /*
-@@ -1661,6 +1761,15 @@
- print_in_addr_t (mi->context.c2.push_ifconfig_local, 0, &gc));
- }
-
-+ if (mi->context.c2.push_ifconfig_ipv6_defined)
-+ {
-+ multi_learn_in6_addr (m, mi, mi->context.c2.push_ifconfig_ipv6_local, -1, true);
-+ /* TODO: find out where addresses are "unlearned"!! */
-+ msg (D_MULTI_LOW, "MULTI: primary virtual IPv6 for %s: %s",
-+ multi_instance_string (mi, false, &gc),
-+ print_in6_addr (mi->context.c2.push_ifconfig_ipv6_local, 0, &gc));
-+ }
-+
- /* add routes locally, pointing to new client, if
- --iroute options have been specified */
- multi_add_iroutes (m, mi);
-Index: openvpn-2.2.1/openvpn.8
-===================================================================
---- openvpn-2.2.1.orig/openvpn.8 2011-12-13 12:24:20.000000000 +0100
-+++ openvpn-2.2.1/openvpn.8 2011-12-13 12:24:54.628739315 +0100
-@@ -794,6 +794,8 @@
- .B \-\-dev tunX.
- A warning will be displayed
- if no specific IPv6 TUN support for your OS has been compiled into OpenVPN.
-+
-+See below for further IPv6-related configuration options.
- .\"*********************************************************
- .TP
- .B \-\-dev-node node
-@@ -4949,6 +4951,57 @@
- .B \-\-verb
- option can be used BEFORE this option to produce debugging information.
- .\"*********************************************************
-+.SS IPv6 Related Options
-+.\"*********************************************************
-+The following options exist to support IPv6 tunneling in peer-to-peer
-+and client-server mode. As of now, this is just very basic
-+documentation of the IPv6-related options. More documentation can be
-+found on http://www.greenie.net/ipv6/openvpn.html.
-+.TP
-+.B --ifconfig-ipv6 ipv6addr/bits ipv6remote
-+configure IPv6 address
-+.B ipv6addr/bits
-+on the ``tun'' device. The second parameter is used as route target for
-+.B --route-ipv6
-+if no gateway is specified.
-+.TP
-+.B --route-ipv6 ipv6addr/bits [gateway] [metric]
-+setup IPv6 routing in the system to send the specified IPv6 network
-+into OpenVPN's ``tun'' device
-+.TP
-+.B --server-ipv6 ipv6addr/bits
-+convenience-function to enable a number of IPv6 related options at
-+once, namely
-+.B --ifconfig-ipv6, --ifconfig-ipv6-pool, --tun-ipv6
-+and
-+.B --push tun-ipv6
-+Is only accepted if ``--mode server'' or ``--server'' is set.
-+.TP
-+.B --ifconfig-ipv6-pool ipv6addr/bits
-+Specify an IPv6 address pool for dynamic assignment to clients. The
-+pool starts at
-+.B ipv6addr
-+and increments by +1 for every new client (linear mode). The
-+.B /bits
-+setting controls the size of the pool.
-+.TP
-+.B --ifconfig-ipv6-push ipv6addr/bits ipv6remote
-+for ccd/ per-client static IPv6 interface configuration, see
-+.B --client-config-dir
-+and
-+.B --ifconfig-push
-+for more details.
-+.TP
-+.B --iroute-ipv6 ipv6addr/bits
-+for ccd/ per-client static IPv6 route configuration, see
-+.B --iroute
-+for more details how to setup and use this, and how
-+.B --iroute
-+and
-+.B --route
-+interact.
-+
-+.\"*********************************************************
- .SH SCRIPTING AND ENVIRONMENTAL VARIABLES
- OpenVPN exports a series
- of environmental variables for use by user-defined scripts.
-Index: openvpn-2.2.1/openvpn.h
-===================================================================
---- openvpn-2.2.1.orig/openvpn.h 2011-06-24 08:13:39.000000000 +0200
-+++ openvpn-2.2.1/openvpn.h 2011-12-13 12:24:54.629739303 +0100
-@@ -165,6 +165,9 @@
- /* list of --route directives */
- struct route_list *route_list;
-
-+ /* list of --route-ipv6 directives */
-+ struct route_ipv6_list *route_ipv6_list;
-+
- /* --status file */
- struct status_output *status_output;
- bool status_output_owned;
-@@ -417,6 +420,11 @@
- in_addr_t push_ifconfig_local;
- in_addr_t push_ifconfig_remote_netmask;
-
-+ bool push_ifconfig_ipv6_defined;
-+ struct in6_addr push_ifconfig_ipv6_local;
-+ int push_ifconfig_ipv6_netbits;
-+ struct in6_addr push_ifconfig_ipv6_remote;
-+
- /* client authentication state, CAS_SUCCEEDED must be 0 */
- # define CAS_SUCCEEDED 0
- # define CAS_PENDING 1
-Index: openvpn-2.2.1/options.c
-===================================================================
---- openvpn-2.2.1.orig/options.c 2011-12-13 12:23:07.000000000 +0100
-+++ openvpn-2.2.1/options.c 2011-12-13 12:24:54.635739227 +0100
-@@ -85,6 +85,7 @@
- #ifdef USE_PF_INET6
- " [PF_INET6]"
- #endif
-+ " [IPv6 payload 20110424-2 (2.2RC2)]"
- " built on " __DATE__
- ;
-
-@@ -181,6 +182,8 @@
- " addresses outside of the subnets used by either peer.\n"
- " TAP: configure device to use IP address l as a local\n"
- " endpoint and rn as a subnet mask.\n"
-+ "--ifconfig-ipv6 l r : configure device to use IPv6 address l as local\n"
-+ " endpoint (as a /64) and r as remote endpoint\n"
- "--ifconfig-noexec : Don't actually execute ifconfig/netsh command, instead\n"
- " pass --ifconfig parms by environment to scripts.\n"
- "--ifconfig-nowarn : Don't warn if the --ifconfig option on this side of the\n"
-@@ -191,6 +194,10 @@
- " netmask default: 255.255.255.255\n"
- " gateway default: taken from --route-gateway or --ifconfig\n"
- " Specify default by leaving blank or setting to \"nil\".\n"
-+ "--route-ipv6 network/bits [gateway] [metric] :\n"
-+ " Add IPv6 route to routing table after connection\n"
-+ " is established. Multiple routes can be specified.\n"
-+ " gateway default: taken from --route-ipv6-gateway or --ifconfig\n"
- "--max-routes n : Specify the maximum number of routes that may be defined\n"
- " or pulled from a server.\n"
- "--route-gateway gw|'dhcp' : Specify a default gateway for use with --route.\n"
-@@ -379,6 +386,7 @@
- "\n"
- "Multi-Client Server options (when --mode server is used):\n"
- "--server network netmask : Helper option to easily configure server mode.\n"
-+ "--server-ipv6 network/bits : Configure IPv6 server mode.\n"
- "--server-bridge [IP netmask pool-start-IP pool-end-IP] : Helper option to\n"
- " easily configure ethernet bridging server mode.\n"
- "--push \"option\" : Push a config file option back to the peer for remote\n"
-@@ -392,10 +400,16 @@
- "--ifconfig-pool-persist file [seconds] : Persist/unpersist ifconfig-pool\n"
- " data to file, at seconds intervals (default=600).\n"
- " If seconds=0, file will be treated as read-only.\n"
-+ "--ifconfig-ipv6-pool base-IP/bits : set aside an IPv6 network block\n"
-+ " to be dynamically allocated to connecting clients.\n"
- "--ifconfig-push local remote-netmask : Push an ifconfig option to remote,\n"
- " overrides --ifconfig-pool dynamic allocation.\n"
- " Only valid in a client-specific config file.\n"
-+ "--ifconfig-ipv6-push local/bits remote : Push an ifconfig-ipv6 option to\n"
-+ " remote, overrides --ifconfig-ipv6-pool allocation.\n"
-+ " Only valid in a client-specific config file.\n"
- "--iroute network [netmask] : Route subnet to client.\n"
-+ "--iroute-ipv6 network/bits : Route IPv6 subnet to client.\n"
- " Sets up internal routes only.\n"
- " Only valid in a client-specific config file.\n"
- "--disable : Client is disabled.\n"
-@@ -880,6 +894,78 @@
- return ret;
- }
-
-+/* helper: parse a text string containing an IPv6 address + netbits
-+ * in "standard format" (2001:dba::/32)
-+ * "/nn" is optional, default to /64 if missing
-+ *
-+ * return true if parsing succeeded, modify *network and *netbits
-+ * return address part without "/nn" in *printable_ipv6 (if != NULL)
-+ */
-+bool
-+get_ipv6_addr( const char * prefix_str, struct in6_addr *network,
-+ unsigned int * netbits, char ** printable_ipv6, int msglevel )
-+{
-+ int rc;
-+ char * sep, * endp;
-+ int bits;
-+ struct in6_addr t_network;
-+
-+ sep = strchr( prefix_str, '/' );
-+ if ( sep == NULL )
-+ {
-+ bits = 64;
-+ }
-+ else
-+ {
-+ bits = strtol( sep+1, &endp, 10 );
-+ if ( *endp != '\0' || bits < 0 || bits > 128 )
-+ {
-+ msg (msglevel, "IPv6 prefix '%s': invalid '/bits' spec", prefix_str);
-+ return false;
-+ }
-+ }
-+
-+ /* temporary replace '/' in caller-provided string with '\0', otherwise
-+ * inet_pton() will refuse prefix string
-+ * (alternative would be to strncpy() the prefix to temporary buffer)
-+ */
-+
-+ if ( sep != NULL ) *sep = '\0';
-+
-+ rc = inet_pton( AF_INET6, prefix_str, &t_network );
-+
-+ if ( rc == 1 && printable_ipv6 != NULL )
-+ {
-+ *printable_ipv6 = string_alloc( prefix_str, NULL );
-+ }
-+
-+ if ( sep != NULL ) *sep = '/';
-+
-+ if ( rc != 1 )
-+ {
-+ msg (msglevel, "IPv6 prefix '%s': invalid IPv6 address", prefix_str);
-+ return false;
-+ }
-+
-+ if ( netbits != NULL )
-+ {
-+ *netbits = bits;
-+ }
-+ if ( network != NULL )
-+ {
-+ *network = t_network;
-+ }
-+ return true; /* parsing OK, values set */
-+}
-+
-+static bool ipv6_addr_safe_hexplusbits( const char * ipv6_prefix_spec )
-+{
-+ struct in6_addr t_addr;
-+ unsigned int t_bits;
-+
-+ return get_ipv6_addr( ipv6_prefix_spec, &t_addr, &t_bits, NULL, M_WARN );
-+}
-+
- static char *
- string_substitute (const char *src, int from, int to, struct gc_arena *gc)
- {
-@@ -998,6 +1084,8 @@
- #if P2MP_SERVER
- msg (D_SHOW_PARMS, " server_network = %s", print_in_addr_t (o->server_network, 0, &gc));
- msg (D_SHOW_PARMS, " server_netmask = %s", print_in_addr_t (o->server_netmask, 0, &gc));
-+ msg (D_SHOW_PARMS, " server_network_ipv6 = %s", print_in6_addr (o->server_network_ipv6, 0, &gc) );
-+ SHOW_INT (server_netbits_ipv6);
- msg (D_SHOW_PARMS, " server_bridge_ip = %s", print_in_addr_t (o->server_bridge_ip, 0, &gc));
- msg (D_SHOW_PARMS, " server_bridge_netmask = %s", print_in_addr_t (o->server_bridge_netmask, 0, &gc));
- msg (D_SHOW_PARMS, " server_bridge_pool_start = %s", print_in_addr_t (o->server_bridge_pool_start, 0, &gc));
-@@ -1018,6 +1106,9 @@
- msg (D_SHOW_PARMS, " ifconfig_pool_netmask = %s", print_in_addr_t (o->ifconfig_pool_netmask, 0, &gc));
- SHOW_STR (ifconfig_pool_persist_filename);
- SHOW_INT (ifconfig_pool_persist_refresh_freq);
-+ SHOW_BOOL (ifconfig_ipv6_pool_defined);
-+ msg (D_SHOW_PARMS, " ifconfig_ipv6_pool_base = %s", print_in6_addr (o->ifconfig_ipv6_pool_base, 0, &gc));
-+ SHOW_INT (ifconfig_ipv6_pool_netbits);
- SHOW_INT (n_bcast_buf);
- SHOW_INT (tcp_queue_limit);
- SHOW_INT (real_hash_size);
-@@ -1031,6 +1122,9 @@
- SHOW_BOOL (push_ifconfig_defined);
- msg (D_SHOW_PARMS, " push_ifconfig_local = %s", print_in_addr_t (o->push_ifconfig_local, 0, &gc));
- msg (D_SHOW_PARMS, " push_ifconfig_remote_netmask = %s", print_in_addr_t (o->push_ifconfig_remote_netmask, 0, &gc));
-+ SHOW_BOOL (push_ifconfig_ipv6_defined);
-+ msg (D_SHOW_PARMS, " push_ifconfig_ipv6_local = %s/%d", print_in6_addr (o->push_ifconfig_ipv6_local, 0, &gc), o->push_ifconfig_ipv6_netbits );
-+ msg (D_SHOW_PARMS, " push_ifconfig_ipv6_remote = %s", print_in6_addr (o->push_ifconfig_ipv6_remote, 0, &gc));
- SHOW_BOOL (enable_c2c);
- SHOW_BOOL (duplicate_cn);
- SHOW_INT (cf_max);
-@@ -1085,6 +1179,25 @@
- o->iroutes = ir;
- }
-
-+static void
-+option_iroute_ipv6 (struct options *o,
-+ const char *prefix_str,
-+ int msglevel)
-+{
-+ struct iroute_ipv6 *ir;
-+
-+ ALLOC_OBJ_GC (ir, struct iroute_ipv6, &o->gc);
-+
-+ if ( get_ipv6_addr (prefix_str, &ir->network, &ir->netbits, NULL, msglevel ) < 0 )
-+ {
-+ msg (msglevel, "in --iroute-ipv6 %s: Bad IPv6 prefix specification",
-+ prefix_str);
-+ return;
-+ }
-+
-+ ir->next = o->iroutes_ipv6;
-+ o->iroutes_ipv6 = ir;
-+}
- #endif /* P2MP_SERVER */
- #endif /* P2MP */
-
-@@ -1122,6 +1235,13 @@
- options->routes = new_route_option_list (options->max_routes, &options->gc);
- }
-
-+void
-+rol6_check_alloc (struct options *options)
-+{
-+ if (!options->routes_ipv6)
-+ options->routes_ipv6 = new_route_ipv6_option_list (options->max_routes, &options->gc);
-+}
-+
- #ifdef ENABLE_DEBUG
- static void
- show_connection_entry (const struct connection_entry *o)
-@@ -1212,6 +1332,9 @@
- SHOW_STR (ifconfig_remote_netmask);
- SHOW_BOOL (ifconfig_noexec);
- SHOW_BOOL (ifconfig_nowarn);
-+ SHOW_STR (ifconfig_ipv6_local);
-+ SHOW_INT (ifconfig_ipv6_netbits);
-+ SHOW_STR (ifconfig_ipv6_remote);
-
- #ifdef HAVE_GETTIMEOFDAY
- SHOW_INT (shaper);
-@@ -1915,8 +2038,10 @@
- if (options->connection_list)
- msg (M_USAGE, "<connection> cannot be used with --mode server");
- #endif
-+#if 0
- if (options->tun_ipv6)
- msg (M_USAGE, "--tun-ipv6 cannot be used with --mode server");
-+#endif
- if (options->shaper)
- msg (M_USAGE, "--shaper cannot be used with --mode server");
- if (options->inetd)
-@@ -1949,6 +2074,11 @@
- msg (M_USAGE, "--up-delay cannot be used with --mode server");
- if (!options->ifconfig_pool_defined && options->ifconfig_pool_persist_filename)
- msg (M_USAGE, "--ifconfig-pool-persist must be used with --ifconfig-pool");
-+ if (options->ifconfig_ipv6_pool_defined && !options->ifconfig_ipv6_local )
-+ msg (M_USAGE, "--ifconfig-ipv6-pool needs --ifconfig-ipv6");
-+ if (options->ifconfig_ipv6_local && !options->tun_ipv6 )
-+ msg (M_INFO, "Warning: --ifconfig-ipv6 without --tun-ipv6 will not do IPv6");
-+
- if (options->auth_user_pass_file)
- msg (M_USAGE, "--auth-user-pass cannot be used with --mode server (it should be used on the client side only)");
- if (options->ccd_exclusive && !options->client_config_dir)
-@@ -1980,6 +2110,8 @@
- */
- if (options->ifconfig_pool_defined || options->ifconfig_pool_persist_filename)
- msg (M_USAGE, "--ifconfig-pool/--ifconfig-pool-persist requires --mode server");
-+ if (options->ifconfig_ipv6_pool_defined)
-+ msg (M_USAGE, "--ifconfig-ipv6-pool requires --mode server");
- if (options->real_hash_size != defaults.real_hash_size
- || options->virtual_hash_size != defaults.virtual_hash_size)
- msg (M_USAGE, "--hash-size requires --mode server");
-@@ -2525,6 +2657,8 @@
- o->topology,
- o->ifconfig_local,
- o->ifconfig_remote_netmask,
-+ o->ifconfig_ipv6_local,
-+ o->ifconfig_ipv6_remote,
- (in_addr_t)0,
- (in_addr_t)0,
- false,
-@@ -3850,6 +3984,30 @@
- goto err;
- }
- }
-+ else if (streq (p[0], "ifconfig-ipv6") && p[1] && p[2] )
-+ {
-+ unsigned int netbits;
-+ char * ipv6_local;
-+
-+ VERIFY_PERMISSION (OPT_P_UP);
-+ if ( get_ipv6_addr( p[1], NULL, &netbits, &ipv6_local, msglevel ) &&
-+ ipv6_addr_safe( p[2] ) )
-+ {
-+ if ( netbits < 64 || netbits > 124 )
-+ {
-+ msg( msglevel, "ifconfig-ipv6: /netbits must be between 64 and 124, not '/%d'", netbits );
-+ goto err;
-+ }
-+ options->ifconfig_ipv6_local = ipv6_local;
-+ options->ifconfig_ipv6_netbits = netbits;
-+ options->ifconfig_ipv6_remote = p[2];
-+ }
-+ else
-+ {
-+ msg (msglevel, "ifconfig-ipv6 parms '%s' and '%s' must be valid addresses", p[1], p[2]);
-+ goto err;
-+ }
-+ }
- else if (streq (p[0], "ifconfig-noexec"))
- {
- VERIFY_PERMISSION (OPT_P_UP);
-@@ -4650,6 +4808,26 @@
- }
- add_route_to_option_list (options->routes, p[1], p[2], p[3], p[4]);
- }
-+ else if (streq (p[0], "route-ipv6") && p[1])
-+ {
-+ VERIFY_PERMISSION (OPT_P_ROUTE);
-+ rol6_check_alloc (options);
-+ if (pull_mode)
-+ {
-+ if (!ipv6_addr_safe_hexplusbits (p[1]))
-+ {
-+ msg (msglevel, "route-ipv6 parameter network/IP '%s' must be a valid address", p[1]);
-+ goto err;
-+ }
-+ if (p[2] && !ipv6_addr_safe (p[2]))
-+ {
-+ msg (msglevel, "route-ipv6 parameter gateway '%s' must be a valid address", p[2]);
-+ goto err;
-+ }
-+ /* p[3] is metric, if present */
-+ }
-+ add_route_ipv6_to_option_list (options->routes_ipv6, p[1], p[2], p[3]);
-+ }
- else if (streq (p[0], "max-routes") && p[1])
- {
- int max_routes;
-@@ -4861,6 +5039,33 @@
- }
- }
- }
-+ else if (streq (p[0], "server-ipv6") && p[1] )
-+ {
-+ const int lev = M_WARN;
-+ struct in6_addr network;
-+ unsigned int netbits = 0;
-+
-+ VERIFY_PERMISSION (OPT_P_GENERAL);
-+ if ( ! get_ipv6_addr (p[1], &network, &netbits, NULL, lev) )
-+ {
-+ msg (msglevel, "error parsing --server-ipv6 parameter");
-+ goto err;
-+ }
-+ if ( netbits != 64 )
-+ {
-+ msg( msglevel, "--server-ipv6 settings: only /64 supported right now (not /%d)", netbits );
-+ goto err;
-+ }
-+ options->server_ipv6_defined = true;
-+ options->server_network_ipv6 = network;
-+ options->server_netbits_ipv6 = netbits;
-+
-+ if (p[2]) /* no "nopool" options or similar for IPv6 */
-+ {
-+ msg (msglevel, "error parsing --server-ipv6: %s is not a recognized flag", p[3]);
-+ goto err;
-+ }
-+ }
- else if (streq (p[0], "server-bridge") && p[1] && p[2] && p[3] && p[4])
- {
- const int lev = M_WARN;
-@@ -4945,6 +5150,28 @@
- VERIFY_PERMISSION (OPT_P_GENERAL);
- options->topology = TOP_P2P;
- }
-+ else if (streq (p[0], "ifconfig-ipv6-pool") && p[1] )
-+ {
-+ const int lev = M_WARN;
-+ struct in6_addr network;
-+ unsigned int netbits = 0;
-+
-+ VERIFY_PERMISSION (OPT_P_GENERAL);
-+ if ( ! get_ipv6_addr (p[1], &network, &netbits, NULL, lev ) )
-+ {
-+ msg (msglevel, "error parsing --ifconfig-ipv6-pool parameters");
-+ goto err;
-+ }
-+ if ( netbits != 64 )
-+ {
-+ msg( msglevel, "--ifconfig-ipv6-pool settings: only /64 supported right now (not /%d)", netbits );
-+ goto err;
-+ }
-+
-+ options->ifconfig_ipv6_pool_defined = true;
-+ options->ifconfig_ipv6_pool_base = network;
-+ options->ifconfig_ipv6_pool_netbits = netbits;
-+ }
- else if (streq (p[0], "hash-size") && p[1] && p[2])
- {
- int real, virtual;
-@@ -5140,6 +5367,11 @@
- }
- option_iroute (options, p[1], netmask, msglevel);
- }
-+ else if (streq (p[0], "iroute-ipv6") && p[1])
-+ {
-+ VERIFY_PERMISSION (OPT_P_INSTANCE);
-+ option_iroute_ipv6 (options, p[1], msglevel);
-+ }
- else if (streq (p[0], "ifconfig-push") && p[1] && p[2])
- {
- in_addr_t local, remote_netmask;
-@@ -5178,6 +5410,43 @@
- goto err;
- }
- }
-+ else if (streq (p[0], "ifconfig-ipv6-push") && p[1] )
-+ {
-+ struct in6_addr local, remote;
-+ unsigned int netbits;
-+
-+ VERIFY_PERMISSION (OPT_P_INSTANCE);
-+
-+ if ( ! get_ipv6_addr( p[1], &local, &netbits, NULL, msglevel ) )
-+ {
-+ msg (msglevel, "cannot parse --ifconfig-ipv6-push addresses");
-+ goto err;
-+ }
-+
-+ if ( p[2] )
-+ {
-+ if ( !get_ipv6_addr( p[2], &remote, NULL, NULL, msglevel ) )
-+ {
-+ msg( msglevel, "cannot parse --ifconfig-ipv6-push addresses");
-+ goto err;
-+ }
-+ }
-+ else
-+ {
-+ if ( ! options->ifconfig_ipv6_local ||
-+ ! get_ipv6_addr( options->ifconfig_ipv6_local, &remote,
-+ NULL, NULL, msglevel ) )
-+ {
-+ msg( msglevel, "second argument to --ifconfig-ipv6-push missing and no global --ifconfig-ipv6 address set");
-+ goto err;
-+ }
-+ }
-+
-+ options->push_ifconfig_ipv6_defined = true;
-+ options->push_ifconfig_ipv6_local = local;
-+ options->push_ifconfig_ipv6_netbits = netbits;
-+ options->push_ifconfig_ipv6_remote = remote;
-+ }
- else if (streq (p[0], "disable"))
- {
- VERIFY_PERMISSION (OPT_P_INSTANCE);
-Index: openvpn-2.2.1/options.h
-===================================================================
---- openvpn-2.2.1.orig/options.h 2011-06-24 08:13:39.000000000 +0200
-+++ openvpn-2.2.1/options.h 2011-12-13 12:24:54.636739214 +0100
-@@ -205,6 +205,9 @@
- int topology; /* one of the TOP_x values from proto.h */
- const char *ifconfig_local;
- const char *ifconfig_remote_netmask;
-+ const char *ifconfig_ipv6_local;
-+ int ifconfig_ipv6_netbits;
-+ const char *ifconfig_ipv6_remote;
- bool ifconfig_noexec;
- bool ifconfig_nowarn;
- #ifdef HAVE_GETTIMEOFDAY
-@@ -326,6 +329,7 @@
- bool route_delay_defined;
- int max_routes;
- struct route_option_list *routes;
-+ struct route_ipv6_option_list *routes_ipv6; /* IPv6 */
- bool route_nopull;
- bool route_gateway_via_dhcp;
- bool allow_pull_fqdn; /* as a client, allow server to push a FQDN for certain parameters */
-@@ -363,6 +367,9 @@
- bool server_defined;
- in_addr_t server_network;
- in_addr_t server_netmask;
-+ bool server_ipv6_defined; /* IPv6 */
-+ struct in6_addr server_network_ipv6; /* IPv6 */
-+ unsigned int server_netbits_ipv6; /* IPv6 */
-
- # define SF_NOPOOL (1<<0)
- # define SF_TCP_NODELAY_HELPER (1<<1)
-@@ -384,6 +391,11 @@
- in_addr_t ifconfig_pool_netmask;
- const char *ifconfig_pool_persist_filename;
- int ifconfig_pool_persist_refresh_freq;
-+
-+ bool ifconfig_ipv6_pool_defined; /* IPv6 */
-+ struct in6_addr ifconfig_ipv6_pool_base; /* IPv6 */
-+ int ifconfig_ipv6_pool_netbits; /* IPv6 */
-+
- int real_hash_size;
- int virtual_hash_size;
- const char *client_connect_script;
-@@ -395,12 +407,17 @@
- int n_bcast_buf;
- int tcp_queue_limit;
- struct iroute *iroutes;
-+ struct iroute_ipv6 *iroutes_ipv6; /* IPv6 */
- bool push_ifconfig_defined;
- in_addr_t push_ifconfig_local;
- in_addr_t push_ifconfig_remote_netmask;
- bool push_ifconfig_constraint_defined;
- in_addr_t push_ifconfig_constraint_network;
- in_addr_t push_ifconfig_constraint_netmask;
-+ bool push_ifconfig_ipv6_defined; /* IPv6 */
-+ struct in6_addr push_ifconfig_ipv6_local; /* IPv6 */
-+ int push_ifconfig_ipv6_netbits; /* IPv6 */
-+ struct in6_addr push_ifconfig_ipv6_remote; /* IPv6 */
- bool enable_c2c;
- bool duplicate_cn;
- int cf_max;
-@@ -723,6 +740,10 @@
- unsigned int *option_types_found,
- struct env_set *es);
-
-+bool get_ipv6_addr( const char * prefix_str, struct in6_addr *network,
-+ unsigned int * netbits, char ** printable_ipv6,
-+ int msglevel );
-+
- /*
- * inline functions
- */
-Index: openvpn-2.2.1/pool.c
-===================================================================
---- openvpn-2.2.1.orig/pool.c 2011-06-24 08:13:39.000000000 +0200
-+++ openvpn-2.2.1/pool.c 2011-12-13 12:24:54.637739202 +0100
-@@ -132,7 +132,10 @@
- }
-
- struct ifconfig_pool *
--ifconfig_pool_init (int type, in_addr_t start, in_addr_t end, const bool duplicate_cn)
-+ifconfig_pool_init (int type, in_addr_t start, in_addr_t end,
-+ const bool duplicate_cn,
-+ const bool ipv6_pool, const struct in6_addr ipv6_base,
-+ const int ipv6_netbits )
- {
- struct gc_arena gc = gc_new ();
- struct ifconfig_pool *pool = NULL;
-@@ -157,11 +160,31 @@
- ASSERT (0);
- }
-
-+ /* IPv6 pools are always "INDIV" type */
-+ pool->ipv6 = ipv6_pool;
-+
-+ if ( pool->ipv6 )
-+ {
-+ pool->base_ipv6 = ipv6_base;
-+ pool->size_ipv6 = ipv6_netbits>96? ( 1<<(128-ipv6_netbits) )
-+ : IFCONFIG_POOL_MAX;
-+
-+ msg( D_IFCONFIG_POOL, "IFCONFIG POOL IPv6: (IPv4) size=%d, size_ipv6=%d, netbits=%d, base_ipv6=%s",
-+ pool->size, pool->size_ipv6, ipv6_netbits,
-+ print_in6_addr( pool->base_ipv6, 0, &gc ));
-+
-+ /* the current code is very simple and assumes that the IPv6
-+ * pool is at least as big as the IPv4 pool, and we don't need
-+ * to do separate math etc. for IPv6
-+ */
-+ ASSERT( pool->size < pool->size_ipv6 );
-+ }
-+
- ALLOC_ARRAY_CLEAR (pool->list, struct ifconfig_pool_entry, pool->size);
-
-- msg (D_IFCONFIG_POOL, "IFCONFIG POOL: base=%s size=%d",
-+ msg (D_IFCONFIG_POOL, "IFCONFIG POOL: base=%s size=%d, ipv6=%d",
- print_in_addr_t (pool->base, 0, &gc),
-- pool->size);
-+ pool->size, pool->ipv6 );
-
- gc_free (&gc);
- return pool;
-@@ -181,7 +204,7 @@
- }
-
- ifconfig_pool_handle
--ifconfig_pool_acquire (struct ifconfig_pool *pool, in_addr_t *local, in_addr_t *remote, const char *common_name)
-+ifconfig_pool_acquire (struct ifconfig_pool *pool, in_addr_t *local, in_addr_t *remote, struct in6_addr *remote_ipv6, const char *common_name)
- {
- int i;
-
-@@ -214,6 +237,12 @@
- default:
- ASSERT (0);
- }
-+
-+ /* IPv6 pools are always INDIV (--linear) */
-+ if ( pool->ipv6 && remote_ipv6 )
-+ {
-+ *remote_ipv6 = add_in6_addr( pool->base_ipv6, i );
-+ }
- }
- return i;
- }
-@@ -288,6 +317,19 @@
- return ret;
- }
-
-+static struct in6_addr
-+ifconfig_pool_handle_to_ipv6_base (const struct ifconfig_pool* pool, ifconfig_pool_handle hand)
-+{
-+ struct in6_addr ret = in6addr_any;
-+
-+ /* IPv6 pools are always INDIV (--linear) */
-+ if (hand >= 0 && hand < pool->size_ipv6 )
-+ {
-+ ret = add_in6_addr( pool->base_ipv6, hand );
-+ }
-+ return ret;
-+}
-+
- static void
- ifconfig_pool_set (struct ifconfig_pool* pool, const char *cn, const in_addr_t addr, const bool fixed)
- {
-@@ -317,9 +359,20 @@
- if (e->common_name)
- {
- const in_addr_t ip = ifconfig_pool_handle_to_ip_base (pool, i);
-- status_printf (out, "%s,%s",
-- e->common_name,
-- print_in_addr_t (ip, 0, &gc));
-+ if ( pool->ipv6 )
-+ {
-+ struct in6_addr ip6 = ifconfig_pool_handle_to_ipv6_base (pool, i);
-+ status_printf (out, "%s,%s,%s",
-+ e->common_name,
-+ print_in_addr_t (ip, 0, &gc),
-+ print_in6_addr (ip6, 0, &gc));
-+ }
-+ else
-+ {
-+ status_printf (out, "%s,%s",
-+ e->common_name,
-+ print_in_addr_t (ip, 0, &gc));
-+ }
- }
- }
- gc_free (&gc);
-@@ -409,6 +462,9 @@
- int c = *BSTR(&in);
- if (c == '#' || c == ';')
- continue;
-+ msg( M_INFO, "ifconfig_pool_read(), in='%s', TODO: IPv6",
-+ BSTR(&in) );
-+
- if (buf_parse (&in, ',', cn_buf, buf_size)
- && buf_parse (&in, ',', ip_buf, buf_size))
- {
-@@ -416,6 +472,7 @@
- const in_addr_t addr = getaddr (GETADDR_HOST_ORDER, ip_buf, 0, &succeeded, NULL);
- if (succeeded)
- {
-+ msg( M_INFO, "succeeded -> ifconfig_pool_set()");
- ifconfig_pool_set (pool, cn_buf, addr, persist->fixed);
- }
- }
-@@ -471,7 +528,7 @@
- #else
- cn = buf;
- #endif
-- h = ifconfig_pool_acquire (p, &local, &remote, cn);
-+ h = ifconfig_pool_acquire (p, &local, &remote, NULL, cn);
- if (h < 0)
- break;
- msg (M_INFO | M_NOPREFIX, "IFCONFIG_POOL TEST pass 1: l=%s r=%s cn=%s",
-@@ -506,7 +563,7 @@
- #else
- cn = buf;
- #endif
-- h = ifconfig_pool_acquire (p, &local, &remote, cn);
-+ h = ifconfig_pool_acquire (p, &local, &remote, NULL, cn);
- if (h < 0)
- break;
- msg (M_INFO | M_NOPREFIX, "IFCONFIG_POOL TEST pass 3: l=%s r=%s cn=%s",
-Index: openvpn-2.2.1/pool.h
-===================================================================
---- openvpn-2.2.1.orig/pool.h 2011-06-24 08:13:39.000000000 +0200
-+++ openvpn-2.2.1/pool.h 2011-12-13 12:24:54.637739202 +0100
-@@ -52,6 +52,9 @@
- int size;
- int type;
- bool duplicate_cn;
-+ bool ipv6;
-+ struct in6_addr base_ipv6;
-+ unsigned int size_ipv6;
- struct ifconfig_pool_entry *list;
- };
-
-@@ -63,13 +66,13 @@
-
- typedef int ifconfig_pool_handle;
-
--struct ifconfig_pool *ifconfig_pool_init (int type, in_addr_t start, in_addr_t end, const bool duplicate_cn);
-+struct ifconfig_pool *ifconfig_pool_init (int type, in_addr_t start, in_addr_t end, const bool duplicate_cn, const bool ipv6_pool, const struct in6_addr ipv6_base, const int ipv6_netbits );
-
- void ifconfig_pool_free (struct ifconfig_pool *pool);
-
- bool ifconfig_pool_verify_range (const int msglevel, const in_addr_t start, const in_addr_t end);
-
--ifconfig_pool_handle ifconfig_pool_acquire (struct ifconfig_pool *pool, in_addr_t *local, in_addr_t *remote, const char *common_name);
-+ifconfig_pool_handle ifconfig_pool_acquire (struct ifconfig_pool *pool, in_addr_t *local, in_addr_t *remote, struct in6_addr *remote_ipv6, const char *common_name);
-
- bool ifconfig_pool_release (struct ifconfig_pool* pool, ifconfig_pool_handle hand, const bool hard);
-
-Index: openvpn-2.2.1/proto.h
-===================================================================
---- openvpn-2.2.1.orig/proto.h 2011-06-24 08:13:39.000000000 +0200
-+++ openvpn-2.2.1/proto.h 2011-12-13 12:24:54.638739190 +0100
-@@ -108,6 +108,21 @@
- };
-
- /*
-+ * IPv6 header
-+ */
-+struct openvpn_ipv6hdr {
-+ uint8_t version_prio;
-+ uint8_t flow_lbl[3];
-+ uint16_t payload_len;
-+ uint8_t nexthdr;
-+ uint8_t hop_limit;
-+
-+ struct in6_addr saddr;
-+ struct in6_addr daddr;
-+};
-+
-+
-+/*
- * UDP header
- */
- struct openvpn_udphdr {
-Index: openvpn-2.2.1/push.c
-===================================================================
---- openvpn-2.2.1.orig/push.c 2011-06-24 08:13:39.000000000 +0200
-+++ openvpn-2.2.1/push.c 2011-12-13 12:24:54.638739190 +0100
-@@ -189,8 +189,26 @@
- const int safe_cap = BCAP (&buf) - extra;
- bool push_sent = false;
-
-+ msg( M_INFO, "send_push_reply(): safe_cap=%d", safe_cap );
-+
- buf_printf (&buf, "%s", cmd);
-
-+ if ( c->c2.push_ifconfig_ipv6_defined )
-+ {
-+ /* IPv6 is put into buffer first, could be lengthy */
-+ /* TODO: push "/netbits" as well, to allow non-/64 subnet sizes
-+ * (needs changes in options.c, options.h, and other places)
-+ */
-+ buf_printf( &buf, ",ifconfig-ipv6 %s %s",
-+ print_in6_addr( c->c2.push_ifconfig_ipv6_local, 0, &gc),
-+ print_in6_addr( c->c2.push_ifconfig_ipv6_remote, 0, &gc) );
-+ if (BLEN (&buf) >= safe_cap)
-+ {
-+ msg (M_WARN, "--push ifconfig-ipv6 option is too long");
-+ goto fail;
-+ }
-+ }
-+
- while (e)
- {
- if (e->enable)
-Index: openvpn-2.2.1/route.c
-===================================================================
---- openvpn-2.2.1.orig/route.c 2011-12-13 12:24:33.000000000 +0100
-+++ openvpn-2.2.1/route.c 2011-12-13 12:24:54.641739154 +0100
-@@ -35,10 +35,12 @@
- #include "socket.h"
- #include "manage.h"
- #include "win32.h"
-+#include "options.h"
-
- #include "memdbg.h"
-
- static void delete_route (const struct route *r, const struct tuntap *tt, unsigned int flags, const struct env_set *es);
-+static void delete_route_ipv6 (const struct route_ipv6 *r, const struct tuntap *tt, unsigned int flags, const struct env_set *es);
- static void get_bypass_addresses (struct route_bypass *rb, const unsigned int flags);
-
- #ifdef ENABLE_DEBUG
-@@ -68,6 +70,15 @@
- return ret;
- }
-
-+struct route_ipv6_option_list *
-+new_route_ipv6_option_list (const int max_routes, struct gc_arena *a)
-+{
-+ struct route_ipv6_option_list *ret;
-+ ALLOC_VAR_ARRAY_CLEAR_GC (ret, struct route_ipv6_option_list, struct route_ipv6_option, max_routes, a);
-+ ret->capacity = max_routes;
-+ return ret;
-+}
-+
- struct route_option_list *
- clone_route_option_list (const struct route_option_list *src, struct gc_arena *a)
- {
-@@ -95,6 +106,15 @@
- return ret;
- }
-
-+struct route_ipv6_list *
-+new_route_ipv6_list (const int max_routes, struct gc_arena *a)
-+{
-+ struct route_ipv6_list *ret;
-+ ALLOC_VAR_ARRAY_CLEAR_GC (ret, struct route_ipv6_list, struct route_ipv6, max_routes, a);
-+ ret->capacity = max_routes;
-+ return ret;
-+}
-+
- static const char *
- route_string (const struct route *r, struct gc_arena *gc)
- {
-@@ -311,6 +331,68 @@
- return false;
- }
-
-+static bool
-+init_route_ipv6 (struct route_ipv6 *r6,
-+ const struct route_ipv6_option *r6o,
-+ const struct route_ipv6_list *rl6 )
-+{
-+ r6->option = r6o;
-+ r6->defined = false;
-+
-+ if ( !get_ipv6_addr( r6o->prefix, &r6->network, &r6->netbits, NULL, M_WARN ))
-+ goto fail;
-+
-+ /* gateway */
-+ if (is_route_parm_defined (r6o->gateway))
-+ {
-+ if ( inet_pton( AF_INET6, r6o->gateway, &r6->gateway ) != 1 )
-+ {
-+ msg( M_WARN, PACKAGE_NAME "ROUTE6: cannot parse gateway spec '%s'", r6o->gateway );
-+ }
-+ }
-+ else if (rl6->remote_endpoint_defined)
-+ {
-+ r6->gateway = rl6->remote_endpoint_ipv6;
-+ }
-+ else
-+ {
-+ msg (M_WARN, PACKAGE_NAME " ROUTE6: " PACKAGE_NAME " needs a gateway parameter for a --route-ipv6 option and no default was specified by either --route-ipv6-gateway or --ifconfig-ipv6 options");
-+ goto fail;
-+ }
-+
-+ /* metric */
-+
-+ r6->metric_defined = false;
-+ r6->metric = 0;
-+ if (is_route_parm_defined (r6o->metric))
-+ {
-+ r6->metric = atoi (r6o->metric);
-+ if (r6->metric < 0)
-+ {
-+ msg (M_WARN, PACKAGE_NAME " ROUTE: route metric for network %s (%s) must be >= 0",
-+ r6o->prefix,
-+ r6o->metric);
-+ goto fail;
-+ }
-+ r6->metric_defined = true;
-+ }
-+ else if (rl6->default_metric_defined)
-+ {
-+ r6->metric = rl6->default_metric;
-+ r6->metric_defined = true;
-+ }
-+
-+ r6->defined = true;
-+
-+ return true;
-+
-+ fail:
-+ msg (M_WARN, PACKAGE_NAME " ROUTE: failed to parse/resolve route for host/network: %s",
-+ r6o->prefix);
-+ r6->defined = false;
-+ return false;
-+}
-+
- void
- add_route_to_option_list (struct route_option_list *l,
- const char *network,
-@@ -331,6 +413,23 @@
- }
-
- void
-+add_route_ipv6_to_option_list (struct route_ipv6_option_list *l,
-+ const char *prefix,
-+ const char *gateway,
-+ const char *metric)
-+{
-+ struct route_ipv6_option *ro;
-+ if (l->n >= l->capacity)
-+ msg (M_FATAL, PACKAGE_NAME " ROUTE: cannot add more than %d IPv6 routes -- please increase the max-routes option in the client configuration file",
-+ l->capacity);
-+ ro = &l->routes_ipv6[l->n];
-+ ro->prefix = prefix;
-+ ro->gateway = gateway;
-+ ro->metric = metric;
-+ ++l->n;
-+}
-+
-+void
- clear_route_list (struct route_list *rl)
- {
- const int capacity = rl->capacity;
-@@ -340,6 +439,15 @@
- }
-
- void
-+clear_route_ipv6_list (struct route_ipv6_list *rl6)
-+{
-+ const int capacity = rl6->capacity;
-+ const size_t rl6_size = array_mult_safe (sizeof(struct route_ipv6), capacity, sizeof(struct route_ipv6_list));
-+ memset(rl6, 0, rl6_size);
-+ rl6->capacity = capacity;
-+}
-+
-+void
- route_list_add_default_gateway (struct route_list *rl,
- struct env_set *es,
- const in_addr_t addr)
-@@ -469,6 +577,72 @@
- return ret;
- }
-
-+bool
-+init_route_ipv6_list (struct route_ipv6_list *rl6,
-+ const struct route_ipv6_option_list *opt6,
-+ const char *remote_endpoint,
-+ int default_metric,
-+ struct env_set *es)
-+{
-+ struct gc_arena gc = gc_new ();
-+ bool ret = true;
-+
-+ clear_route_ipv6_list (rl6);
-+
-+ rl6->flags = opt6->flags;
-+
-+ if (default_metric)
-+ {
-+ rl6->default_metric = default_metric;
-+ rl6->default_metric_defined = true;
-+ }
-+
-+ /* "default_gateway" is stuff for "redirect-gateway", which we don't
-+ * do for IPv6 yet -> TODO
-+ */
-+ {
-+ dmsg (D_ROUTE, "ROUTE6: default_gateway=UNDEF");
-+ }
-+
-+ if ( is_route_parm_defined( remote_endpoint ))
-+ {
-+ if ( inet_pton( AF_INET6, remote_endpoint,
-+ &rl6->remote_endpoint_ipv6) == 1 )
-+ {
-+ rl6->remote_endpoint_defined = true;
-+ }
-+ else
-+ {
-+ msg (M_WARN, PACKAGE_NAME " ROUTE: failed to parse/resolve default gateway: %s", remote_endpoint);
-+ ret = false;
-+ }
-+ }
-+ else
-+ rl6->remote_endpoint_defined = false;
-+
-+
-+ if (!(opt6->n >= 0 && opt6->n <= rl6->capacity))
-+ msg (M_FATAL, PACKAGE_NAME " ROUTE6: (init) number of route options (%d) is greater than route list capacity (%d)", opt6->n, rl6->capacity);
-+
-+ /* parse the routes from opt to rl6 */
-+ {
-+ int i, j = 0;
-+ for (i = 0; i < opt6->n; ++i)
-+ {
-+ if (!init_route_ipv6 (&rl6->routes_ipv6[j],
-+ &opt6->routes_ipv6[i],
-+ rl6 ))
-+ ret = false;
-+ else
-+ ++j;
-+ }
-+ rl6->n = j;
-+ }
-+
-+ gc_free (&gc);
-+ return ret;
-+}
-+
- static void
- add_route3 (in_addr_t network,
- in_addr_t netmask,
-@@ -714,10 +888,13 @@
- }
-
- void
--add_routes (struct route_list *rl, const struct tuntap *tt, unsigned int flags, const struct env_set *es)
-+add_routes (struct route_list *rl, struct route_ipv6_list *rl6,
-+ const struct tuntap *tt, unsigned int flags, const struct env_set *es)
- {
-- redirect_default_route_to_vpn (rl, tt, flags, es);
-- if (!rl->routes_added)
-+ if (rl)
-+ redirect_default_route_to_vpn (rl, tt, flags, es);
-+
-+ if (rl && !rl->routes_added)
- {
- int i;
-
-@@ -742,12 +919,27 @@
- }
- rl->routes_added = true;
- }
-+
-+ if (rl6 && !rl6->routes_added)
-+ {
-+ int i;
-+
-+ for (i = 0; i < rl6->n; ++i)
-+ {
-+ struct route_ipv6 *r = &rl6->routes_ipv6[i];
-+ if (flags & ROUTE_DELETE_FIRST)
-+ delete_route_ipv6 (r, tt, flags, es);
-+ add_route_ipv6 (r, tt, flags, es);
-+ }
-+ rl6->routes_added = true;
-+ }
- }
-
- void
--delete_routes (struct route_list *rl, const struct tuntap *tt, unsigned int flags, const struct env_set *es)
-+delete_routes (struct route_list *rl, struct route_ipv6_list *rl6,
-+ const struct tuntap *tt, unsigned int flags, const struct env_set *es)
- {
-- if (rl->routes_added)
-+ if (rl && rl->routes_added)
- {
- int i;
- for (i = rl->n - 1; i >= 0; --i)
-@@ -757,9 +949,28 @@
- }
- rl->routes_added = false;
- }
-- undo_redirect_default_route_to_vpn (rl, tt, flags, es);
-
-- clear_route_list (rl);
-+ if ( rl )
-+ {
-+ undo_redirect_default_route_to_vpn (rl, tt, flags, es);
-+ clear_route_list (rl);
-+ }
-+
-+ if ( rl6 && rl6->routes_added )
-+ {
-+ int i;
-+ for (i = rl6->n - 1; i >= 0; --i)
-+ {
-+ const struct route_ipv6 *r6 = &rl6->routes_ipv6[i];
-+ delete_route_ipv6 (r6, tt, flags, es);
-+ }
-+ rl6->routes_added = false;
-+ }
-+
-+ if ( rl6 )
-+ {
-+ clear_route_ipv6_list (rl6);
-+ }
- }
-
- #ifdef ENABLE_DEBUG
-@@ -842,6 +1053,34 @@
- setenv_route (es, &rl->routes[i], i + 1);
- }
-
-+static void
-+setenv_route_ipv6 (struct env_set *es, const struct route_ipv6 *r6, int i)
-+{
-+ struct gc_arena gc = gc_new ();
-+ if (r6->defined)
-+ {
-+ struct buffer name1 = alloc_buf_gc( 256, &gc );
-+ struct buffer val = alloc_buf_gc( 256, &gc );
-+ struct buffer name2 = alloc_buf_gc( 256, &gc );
-+
-+ buf_printf( &name1, "route_ipv6_network_%d", i );
-+ buf_printf( &val, "%s/%d", print_in6_addr( r6->network, 0, &gc ),
-+ r6->netbits );
-+ setenv_str( es, BSTR(&name1), BSTR(&val) );
-+
-+ buf_printf( &name2, "route_ipv6_gateway_%d", i );
-+ setenv_str( es, BSTR(&name2), print_in6_addr( r6->gateway, 0, &gc ));
-+ }
-+ gc_free (&gc);
-+}
-+void
-+setenv_routes_ipv6 (struct env_set *es, const struct route_ipv6_list *rl6)
-+{
-+ int i;
-+ for (i = 0; i < rl6->n; ++i)
-+ setenv_route_ipv6 (es, &rl6->routes_ipv6[i], i + 1);
-+}
-+
- void
- add_route (struct route *r, const struct tuntap *tt, unsigned int flags, const struct env_set *es)
- {
-@@ -1035,6 +1274,176 @@
- gc_free (&gc);
- }
-
-+void
-+add_route_ipv6 (struct route_ipv6 *r6, const struct tuntap *tt, unsigned int flags, const struct env_set *es)
-+{
-+ struct gc_arena gc;
-+ struct argv argv;
-+
-+ const char *network;
-+ const char *gateway;
-+ bool status = false;
-+ const char *device = tt->actual_name;
-+ int byte, bits_to_clear;
-+ struct in6_addr network_copy = r6->network;
-+
-+ if (!r6->defined)
-+ return;
-+
-+ gc_init (&gc);
-+ argv_init (&argv);
-+
-+ /* clear host bit parts of route
-+ * (needed if routes are specified improperly, or if we need to
-+ * explicitely setup the "connected" network routes on some OSes)
-+ */
-+ byte = 15;
-+ bits_to_clear = 128 - r6->netbits;
-+
-+ while( byte >= 0 && bits_to_clear > 0 )
-+ {
-+ if ( bits_to_clear >= 8 )
-+ { network_copy.s6_addr[byte--] = 0; bits_to_clear -= 8; }
-+ else
-+ { network_copy.s6_addr[byte--] &= (~0 << bits_to_clear); bits_to_clear = 0; }
-+ }
-+
-+ network = print_in6_addr( network_copy, 0, &gc);
-+ gateway = print_in6_addr( r6->gateway, 0, &gc);
-+
-+ if ( !tt->ipv6 )
-+ {
-+ msg( M_INFO, "add_route_ipv6(): not adding %s/%d, no IPv6 on if %s",
-+ network, r6->netbits, device );
-+ return;
-+ }
-+
-+ msg( M_INFO, "add_route_ipv6(%s/%d -> %s metric %d) dev %s",
-+ network, r6->netbits, gateway, r6->metric, device );
-+
-+ /*
-+ * Filter out routes which are essentially no-ops
-+ * (not currently done for IPv6)
-+ */
-+
-+#if defined(TARGET_LINUX)
-+#ifdef CONFIG_FEATURE_IPROUTE
-+ argv_printf (&argv, "%s -6 route add %s/%d dev %s",
-+ iproute_path,
-+ network,
-+ r6->netbits,
-+ device);
-+ if (r6->metric_defined)
-+ argv_printf_cat (&argv, " metric %d", r6->metric);
-+
-+#else
-+ argv_printf (&argv, "%s -A inet6 add %s/%d dev %s",
-+ ROUTE_PATH,
-+ network,
-+ r6->netbits,
-+ device);
-+ if (r6->metric_defined)
-+ argv_printf_cat (&argv, " metric %d", r6->metric);
-+#endif /*CONFIG_FEATURE_IPROUTE*/
-+ argv_msg (D_ROUTE, &argv);
-+ status = openvpn_execve_check (&argv, es, 0, "ERROR: Linux route -6/-A inet6 add command failed");
-+
-+#elif defined (WIN32)
-+
-+ /* netsh interface ipv6 add route 2001:db8::/32 MyTunDevice */
-+ argv_printf (&argv, "%s%sc interface ipv6 add route %s/%d %s",
-+ get_win_sys_path(),
-+ NETSH_PATH_SUFFIX,
-+ network,
-+ r6->netbits,
-+ device);
-+
-+ /* next-hop depends on TUN or TAP mode:
-+ * - in TAP mode, we use the "real" next-hop
-+ * - in TUN mode we use a special-case link-local address that the tapdrvr
-+ * knows about and will answer ND (neighbor discovery) packets for
-+ */
-+ if ( tt->type == DEV_TYPE_TUN )
-+ argv_printf_cat( &argv, " %s", "fe80::8" );
-+ else
-+ argv_printf_cat( &argv, " %s", gateway );
-+
-+#if 0
-+ if (r->metric_defined)
-+ argv_printf_cat (&argv, " METRIC %d", r->metric);
-+#endif
-+
-+ argv_msg (D_ROUTE, &argv);
-+
-+ netcmd_semaphore_lock ();
-+ status = openvpn_execve_check (&argv, es, 0, "ERROR: Windows route add ipv6 command failed");
-+ netcmd_semaphore_release ();
-+
-+#elif defined (TARGET_SOLARIS)
-+
-+ /* example: route add -inet6 2001:db8::/32 somegateway 0 */
-+
-+ /* for some weird reason, this does not work for me unless I set
-+ * "metric 0" - otherwise, the routes will be nicely installed, but
-+ * packets will just disappear somewhere. So we use "0" now...
-+ */
-+
-+ argv_printf (&argv, "%s add -inet6 %s/%d %s 0",
-+ ROUTE_PATH,
-+ network,
-+ r6->netbits,
-+ gateway );
-+
-+ argv_msg (D_ROUTE, &argv);
-+ status = openvpn_execve_check (&argv, es, 0, "ERROR: Solaris route add -inet6 command failed");
-+
-+#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
-+
-+ argv_printf (&argv, "%s add -inet6 %s/%d -iface %s",
-+ ROUTE_PATH,
-+ network,
-+ r6->netbits,
-+ device );
-+
-+ argv_msg (D_ROUTE, &argv);
-+ status = openvpn_execve_check (&argv, es, 0, "ERROR: *BSD route add -inet6 command failed");
-+
-+#elif defined(TARGET_DARWIN)
-+
-+ argv_printf (&argv, "%s add -inet6 %s -prefixlen %d -iface %s",
-+ ROUTE_PATH,
-+ network, r6->netbits, device );
-+
-+ argv_msg (D_ROUTE, &argv);
-+ status = openvpn_execve_check (&argv, es, 0, "ERROR: MacOS X route add -inet6 command failed");
-+
-+#elif defined(TARGET_OPENBSD)
-+
-+ argv_printf (&argv, "%s add -inet6 %s -prefixlen %d %s",
-+ ROUTE_PATH,
-+ network, r6->netbits, gateway );
-+
-+ argv_msg (D_ROUTE, &argv);
-+ status = openvpn_execve_check (&argv, es, 0, "ERROR: OpenBSD route add -inet6 command failed");
-+
-+#elif defined(TARGET_NETBSD)
-+
-+ argv_printf (&argv, "%s add -inet6 %s/%d %s",
-+ ROUTE_PATH,
-+ network, r6->netbits, gateway );
-+
-+ argv_msg (D_ROUTE, &argv);
-+ status = openvpn_execve_check (&argv, es, 0, "ERROR: NetBSD route add -inet6 command failed");
-+
-+#else
-+ msg (M_FATAL, "Sorry, but I don't know how to do 'route ipv6' commands on this operating system. Try putting your routes in a --route-up script");
-+#endif
-+
-+ r6->defined = status;
-+ argv_reset (&argv);
-+ gc_free (&gc);
-+}
-+
- static void
- delete_route (const struct route *r, const struct tuntap *tt, unsigned int flags, const struct env_set *es)
- {
-@@ -1171,6 +1580,142 @@
- #endif
-
- argv_reset (&argv);
-+ gc_free (&gc);
-+}
-+
-+static void
-+delete_route_ipv6 (const struct route_ipv6 *r6, const struct tuntap *tt, unsigned int flags, const struct env_set *es)
-+{
-+ struct gc_arena gc;
-+ struct argv argv;
-+ const char *network;
-+ const char *gateway;
-+ const char *device = tt->actual_name;
-+
-+ if (!r6->defined)
-+ return;
-+
-+ gc_init (&gc);
-+ argv_init (&argv);
-+
-+ network = print_in6_addr( r6->network, 0, &gc);
-+ gateway = print_in6_addr( r6->gateway, 0, &gc);
-+
-+ if ( !tt->ipv6 )
-+ {
-+ msg( M_INFO, "delete_route_ipv6(): not deleting %s/%d, no IPv6 on if %s",
-+ network, r6->netbits, device );
-+ return;
-+ }
-+
-+ msg( M_INFO, "delete_route_ipv6(%s/%d)", network, r6->netbits );
-+
-+#if defined(TARGET_LINUX)
-+#ifdef CONFIG_FEATURE_IPROUTE
-+ argv_printf (&argv, "%s -6 route del %s/%d dev %s",
-+ iproute_path,
-+ network,
-+ r6->netbits,
-+ device);
-+#else
-+ argv_printf (&argv, "%s -A inet6 del %s/%d dev %s",
-+ ROUTE_PATH,
-+ network,
-+ r6->netbits,
-+ device);
-+#endif /*CONFIG_FEATURE_IPROUTE*/
-+ argv_msg (D_ROUTE, &argv);
-+ openvpn_execve_check (&argv, es, 0, "ERROR: Linux route -6/-A inet6 del command failed");
-+
-+#elif defined (WIN32)
-+
-+ /* netsh interface ipv6 delete route 2001:db8::/32 MyTunDevice */
-+ argv_printf (&argv, "%s%sc interface ipv6 delete route %s/%d %s",
-+ get_win_sys_path(),
-+ NETSH_PATH_SUFFIX,
-+ network,
-+ r6->netbits,
-+ device);
-+
-+ /* next-hop depends on TUN or TAP mode:
-+ * - in TAP mode, we use the "real" next-hop
-+ * - in TUN mode we use a special-case link-local address that the tapdrvr
-+ * knows about and will answer ND (neighbor discovery) packets for
-+ * (and "route deletion without specifying next-hop" does not work...)
-+ */
-+ if ( tt->type == DEV_TYPE_TUN )
-+ argv_printf_cat( &argv, " %s", "fe80::8" );
-+ else
-+ argv_printf_cat( &argv, " %s", gateway );
-+
-+#if 0
-+ if (r->metric_defined)
-+ argv_printf_cat (&argv, "METRIC %d", r->metric);
-+#endif
-+
-+ argv_msg (D_ROUTE, &argv);
-+
-+ netcmd_semaphore_lock ();
-+ openvpn_execve_check (&argv, es, 0, "ERROR: Windows route add ipv6 command failed");
-+ netcmd_semaphore_release ();
-+
-+#elif defined (TARGET_SOLARIS)
-+
-+ /* example: route delete -inet6 2001:db8::/32 somegateway */
-+ /* GERT-TODO: this is untested, but should work */
-+
-+ argv_printf (&argv, "%s delete -inet6 %s/%d %s",
-+ ROUTE_PATH,
-+ network,
-+ r6->netbits,
-+ gateway );
-+
-+ argv_msg (D_ROUTE, &argv);
-+ openvpn_execve_check (&argv, es, 0, "ERROR: Solaris route delete -inet6 command failed");
-+
-+#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
-+
-+ argv_printf (&argv, "%s delete -inet6 %s/%d -iface %s",
-+ ROUTE_PATH,
-+ network,
-+ r6->netbits,
-+ device );
-+
-+ argv_msg (D_ROUTE, &argv);
-+ openvpn_execve_check (&argv, es, 0, "ERROR: *BSD route delete -inet6 command failed");
-+
-+#elif defined(TARGET_DARWIN)
-+
-+ argv_printf (&argv, "%s delete -inet6 %s -prefixlen %d -iface %s",
-+ ROUTE_PATH,
-+ network, r6->netbits, device );
-+
-+ argv_msg (D_ROUTE, &argv);
-+ openvpn_execve_check (&argv, es, 0, "ERROR: *BSD route delete -inet6 command failed");
-+
-+#elif defined(TARGET_OPENBSD)
-+
-+ argv_printf (&argv, "%s delete -inet6 %s -prefixlen %d %s",
-+ ROUTE_PATH,
-+ network, r6->netbits, gateway );
-+
-+ argv_msg (D_ROUTE, &argv);
-+ openvpn_execve_check (&argv, es, 0, "ERROR: OpenBSD route delete -inet6 command failed");
-+
-+#elif defined(TARGET_NETBSD)
-+
-+ argv_printf (&argv, "%s delete -inet6 %s/%d %s",
-+ ROUTE_PATH,
-+ network, r6->netbits, gateway );
-+
-+ argv_msg (D_ROUTE, &argv);
-+ openvpn_execve_check (&argv, es, 0, "ERROR: NetBSD route delete -inet6 command failed");
-+
-+#else
-+ msg (M_FATAL, "Sorry, but I don't know how to do 'route ipv6' commands on this operating system. Try putting your routes in a --route-down script");
-+#endif
-+
-+ argv_reset (&argv);
- gc_free (&gc);
- }
-
-Index: openvpn-2.2.1/route.h
-===================================================================
---- openvpn-2.2.1.orig/route.h 2011-06-24 08:13:39.000000000 +0200
-+++ openvpn-2.2.1/route.h 2011-12-13 12:24:54.642739141 +0100
-@@ -92,6 +92,19 @@
- struct route_option routes[EMPTY_ARRAY_SIZE];
- };
-
-+struct route_ipv6_option {
-+ const char *prefix; /* e.g. "2001:db8:1::/64" */
-+ const char *gateway; /* e.g. "2001:db8:0::2" */
-+ const char *metric; /* e.g. "5" */
-+};
-+
-+struct route_ipv6_option_list {
-+ unsigned int flags;
-+ int capacity;
-+ int n;
-+ struct route_ipv6_option routes_ipv6[EMPTY_ARRAY_SIZE];
-+};
-+
- struct route {
- bool defined;
- const struct route_option *option;
-@@ -113,6 +126,31 @@
- struct route routes[EMPTY_ARRAY_SIZE];
- };
-
-+struct route_ipv6 {
-+ bool defined;
-+ const struct route_ipv6_option *option;
-+ struct in6_addr network;
-+ unsigned int netbits;
-+ struct in6_addr gateway;
-+ bool metric_defined;
-+ int metric;
-+};
-+
-+struct route_ipv6_list {
-+ bool routes_added;
-+ unsigned int flags;
-+ int default_metric;
-+ bool default_metric_defined;
-+ struct in6_addr remote_endpoint_ipv6;
-+ bool remote_endpoint_defined;
-+ bool did_redirect_default_gateway; /* TODO (?) */
-+ bool did_local; /* TODO (?) */
-+ int capacity;
-+ int n;
-+ struct route_ipv6 routes_ipv6[EMPTY_ARRAY_SIZE];
-+};
-+
-+
- #if P2MP
- /* internal OpenVPN route */
- struct iroute {
-@@ -120,15 +158,24 @@
- int netbits;
- struct iroute *next;
- };
-+
-+struct iroute_ipv6 {
-+ struct in6_addr network;
-+ unsigned int netbits;
-+ struct iroute_ipv6 *next;
-+};
- #endif
-
- struct route_option_list *new_route_option_list (const int max_routes, struct gc_arena *a);
-+struct route_ipv6_option_list *new_route_ipv6_option_list (const int max_routes, struct gc_arena *a);
- struct route_option_list *clone_route_option_list (const struct route_option_list *src, struct gc_arena *a);
- void copy_route_option_list (struct route_option_list *dest, const struct route_option_list *src);
-
- struct route_list *new_route_list (const int max_routes, struct gc_arena *a);
-+struct route_ipv6_list *new_route_ipv6_list (const int max_routes, struct gc_arena *a);
-
- void add_route (struct route *r, const struct tuntap *tt, unsigned int flags, const struct env_set *es);
-+void add_route_ipv6 (struct route_ipv6 *r, const struct tuntap *tt, unsigned int flags, const struct env_set *es);
-
- void add_route_to_option_list (struct route_option_list *l,
- const char *network,
-@@ -136,6 +183,11 @@
- const char *gateway,
- const char *metric);
-
-+void add_route_ipv6_to_option_list (struct route_ipv6_option_list *l,
-+ const char *prefix,
-+ const char *gateway,
-+ const char *metric);
-+
- bool init_route_list (struct route_list *rl,
- const struct route_option_list *opt,
- const char *remote_endpoint,
-@@ -143,21 +195,30 @@
- in_addr_t remote_host,
- struct env_set *es);
-
-+bool init_route_ipv6_list (struct route_ipv6_list *rl6,
-+ const struct route_ipv6_option_list *opt6,
-+ const char *remote_endpoint,
-+ int default_metric,
-+ struct env_set *es);
-+
- void route_list_add_default_gateway (struct route_list *rl,
- struct env_set *es,
- const in_addr_t addr);
-
- void add_routes (struct route_list *rl,
-+ struct route_ipv6_list *rl6,
- const struct tuntap *tt,
- unsigned int flags,
- const struct env_set *es);
-
- void delete_routes (struct route_list *rl,
-+ struct route_ipv6_list *rl6,
- const struct tuntap *tt,
- unsigned int flags,
- const struct env_set *es);
-
- void setenv_routes (struct env_set *es, const struct route_list *rl);
-+void setenv_routes_ipv6 (struct env_set *es, const struct route_ipv6_list *rl6);
-
- bool is_special_addr (const char *addr_str);
-
-Index: openvpn-2.2.1/socket.c
-===================================================================
---- openvpn-2.2.1.orig/socket.c 2011-12-13 12:23:07.000000000 +0100
-+++ openvpn-2.2.1/socket.c 2011-12-13 12:24:54.645739102 +0100
-@@ -543,6 +543,24 @@
- }
- }
-
-+bool
-+ipv6_addr_safe (const char *ipv6_text_addr)
-+{
-+ /* verify non-NULL */
-+ if (!ipv6_text_addr)
-+ return false;
-+
-+ /* verify length is within limits */
-+ if (strlen (ipv6_text_addr) > INET6_ADDRSTRLEN )
-+ return false;
-+
-+ /* verify that string will convert to IPv6 address */
-+ {
-+ struct in6_addr a6;
-+ return inet_pton( AF_INET6, ipv6_text_addr, &a6 ) == 1;
-+ }
-+}
-+
- static bool
- dns_addr_safe (const char *addr)
- {
-@@ -2578,6 +2596,55 @@
- return BSTR (&out);
- }
-
-+/*
-+ * Convert an in6_addr in host byte order
-+ * to an ascii representation of an IPv6 address
-+ */
-+const char *
-+print_in6_addr (struct in6_addr a6, unsigned int flags, struct gc_arena *gc)
-+{
-+ struct buffer out = alloc_buf_gc (64, gc);
-+ char tmp_out_buf[64]; /* inet_ntop wants pointer to buffer */
-+
-+ if ( memcmp(&a6, &in6addr_any, sizeof(a6)) != 0 ||
-+ !(flags & IA_EMPTY_IF_UNDEF))
-+ {
-+ inet_ntop (AF_INET6, &a6, tmp_out_buf, sizeof(tmp_out_buf)-1);
-+ buf_printf (&out, "%s", tmp_out_buf );
-+ }
-+ return BSTR (&out);
-+}
-+
-+/* add some offset to an ipv6 address
-+ * (add in steps of 32 bits, taking overflow into next round)
-+ */
-+#ifndef s6_addr32
-+# ifdef TARGET_SOLARIS
-+# define s6_addr32 _S6_un._S6_u32
-+# else
-+# define s6_addr32 __u6_addr.__u6_addr32
-+# endif
-+#endif
-+#ifndef UINT32_MAX
-+# define UINT32_MAX (4294967295U)
-+#endif
-+struct in6_addr add_in6_addr( struct in6_addr base, uint32_t add )
-+{
-+ int i;
-+ uint32_t h;
-+
-+ for( i=3; i>=0 && add > 0 ; i-- )
-+ {
-+ h = ntohl( base.s6_addr32[i] );
-+ base.s6_addr32[i] = htonl( (h+add) & UINT32_MAX );
-+ /* 32-bit overrun?
-+ * caveat: can't do "h+add > UINT32_MAX" with 32bit math!
-+ */
-+ add = ( h > UINT32_MAX - add )? 1: 0;
-+ }
-+ return base;
-+}
-+
- /* set environmental variables for ip/port in *addr */
- void
- setenv_sockaddr (struct env_set *es, const char *name_prefix, const struct openvpn_sockaddr *addr, const bool flags)
-@@ -3081,6 +3148,58 @@
-
- #ifdef WIN32
-
-+/*
-+ * inet_ntop() and inet_pton() wrap-implementations using
-+ * WSAAddressToString() and WSAStringToAddress() functions
-+ */
-+const char *
-+inet_ntop(int af, const void *src, char *dst, socklen_t size)
-+{
-+ struct sockaddr_storage ss;
-+ unsigned long s = size;
-+
-+ CLEAR(ss);
-+ ss.ss_family = af;
-+
-+ switch(af) {
-+ case AF_INET:
-+ ((struct sockaddr_in *)&ss)->sin_addr = *(struct in_addr *)src;
-+ break;
-+ case AF_INET6:
-+ ((struct sockaddr_in6 *)&ss)->sin6_addr = *(struct in6_addr *)src;
-+ break;
-+ default:
-+ ASSERT (0);
-+ }
-+ // cannot direclty use &size because of strict aliasing rules
-+ return (WSAAddressToString((struct sockaddr *)&ss, sizeof(ss), NULL, dst, &s) == 0)?
-+ dst : NULL;
-+}
-+
-+int
-+inet_pton(int af, const char *src, void *dst)
-+{
-+ struct sockaddr_storage ss;
-+ int size = sizeof(ss);
-+ char src_copy[INET6_ADDRSTRLEN+1];
-+
-+ CLEAR(ss);
-+ // stupid non-const API
-+ strncpynt(src_copy, src, INET6_ADDRSTRLEN+1);
-+
-+ if (WSAStringToAddress(src_copy, af, NULL, (struct sockaddr *)&ss, &size) == 0) {
-+ switch(af) {
-+ case AF_INET:
-+ *(struct in_addr *)dst = ((struct sockaddr_in *)&ss)->sin_addr;
-+ return 1;
-+ case AF_INET6:
-+ *(struct in6_addr *)dst = ((struct sockaddr_in6 *)&ss)->sin6_addr;
-+ return 1;
-+ }
-+ }
-+ return 0;
-+}
-+
- int
- socket_recv_queue (struct link_socket *sock, int maxsize)
- {
-Index: openvpn-2.2.1/socket.h
-===================================================================
---- openvpn-2.2.1.orig/socket.h 2011-12-13 12:23:07.000000000 +0100
-+++ openvpn-2.2.1/socket.h 2011-12-13 12:24:54.646739089 +0100
-@@ -368,6 +368,8 @@
- #define IA_EMPTY_IF_UNDEF (1<<0)
- #define IA_NET_ORDER (1<<1)
- const char *print_in_addr_t (in_addr_t addr, unsigned int flags, struct gc_arena *gc);
-+const char *print_in6_addr (struct in6_addr addr6, unsigned int flags, struct gc_arena *gc);
-+struct in6_addr add_in6_addr( struct in6_addr base, uint32_t add );
-
- #define SA_IP_PORT (1<<0)
- #define SA_SET_IF_NONZERO (1<<1)
-@@ -427,6 +429,7 @@
- bool ip_addr_dotted_quad_safe (const char *dotted_quad);
- bool ip_or_dns_addr_safe (const char *addr, const bool allow_fqdn);
- bool mac_addr_safe (const char *mac_addr);
-+bool ipv6_addr_safe (const char *ipv6_text_addr);
-
- socket_descriptor_t create_socket_tcp (void);
-
-Index: openvpn-2.2.1/tun.c
-===================================================================
---- openvpn-2.2.1.orig/tun.c 2011-12-13 12:23:07.394079932 +0100
-+++ openvpn-2.2.1/tun.c 2011-12-13 12:41:30.078294479 +0100
-@@ -56,13 +56,14 @@
- const in_addr_t ip,
- const in_addr_t netmask,
- const unsigned int flags);
-+static void netsh_command (const struct argv *a, int n);
-
- static const char *netsh_get_id (const char *dev_node, struct gc_arena *gc);
-
- #endif
-
- #ifdef TARGET_SOLARIS
--static void solaris_error_close (struct tuntap *tt, const struct env_set *es, const char *actual);
-+static void solaris_error_close (struct tuntap *tt, const struct env_set *es, const char *actual, bool unplumb_inet6);
- #include <stropts.h>
- #endif
-
-@@ -129,30 +130,6 @@
- return dev;
- }
-
--/*
-- * Called by the open_tun function of OSes to check if we
-- * explicitly support IPv6.
-- *
-- * In this context, explicit means that the OS expects us to
-- * do something special to the tun socket in order to support
-- * IPv6, i.e. it is not transparent.
-- *
-- * ipv6_explicitly_supported should be set to false if we don't
-- * have any explicit IPv6 code in the tun device handler.
-- *
-- * If ipv6_explicitly_supported is true, then we have explicit
-- * OS-specific tun dev code for handling IPv6. If so, tt->ipv6
-- * is set according to the --tun-ipv6 command line option.
-- */
--static void
--ipv6_support (bool ipv6, bool ipv6_explicitly_supported, struct tuntap* tt)
--{
-- tt->ipv6 = false;
-- if (ipv6_explicitly_supported)
-- tt->ipv6 = ipv6;
-- else if (ipv6)
-- msg (M_WARN, "NOTE: explicit support for IPv6 tun devices is not provided for this OS");
--}
-
- /* --ifconfig-nowarn disables some options sanity checking */
- static const char ifconfig_warn_how_to_silence[] = "(silence this warning with --ifconfig-nowarn)";
-@@ -423,6 +400,8 @@
- int topology, /* one of the TOP_x values */
- const char *ifconfig_local_parm, /* --ifconfig parm 1 */
- const char *ifconfig_remote_netmask_parm, /* --ifconfig parm 2 */
-+ const char *ifconfig_ipv6_local_parm, /* --ifconfig parm 1 IPv6 */
-+ const char *ifconfig_ipv6_remote_parm, /* --ifconfig parm 2 IPv6 */
- in_addr_t local_public,
- in_addr_t remote_public,
- const bool strict_warn,
-@@ -537,6 +516,40 @@
-
- tt->did_ifconfig_setup = true;
- }
-+
-+ if (ifconfig_ipv6_local_parm && ifconfig_ipv6_remote_parm)
-+ {
-+ const char *ifconfig_ipv6_local = NULL;
-+ const char *ifconfig_ipv6_remote = NULL;
-+
-+ /*
-+ * Convert arguments to binary IPv6 addresses.
-+ */
-+
-+ if ( inet_pton( AF_INET6, ifconfig_ipv6_local_parm, &tt->local_ipv6 ) != 1 ||
-+ inet_pton( AF_INET6, ifconfig_ipv6_remote_parm, &tt->remote_ipv6 ) != 1 )
-+ {
-+ msg( M_FATAL, "init_tun: problem converting IPv6 ifconfig addresses %s and %s to binary", ifconfig_ipv6_local_parm, ifconfig_ipv6_remote_parm );
-+ }
-+ tt->netbits_ipv6 = 64;
-+
-+ /*
-+ * Set ifconfig parameters
-+ */
-+ ifconfig_ipv6_local = print_in6_addr (tt->local_ipv6, 0, &gc);
-+ ifconfig_ipv6_remote = print_in6_addr (tt->remote_ipv6, 0, &gc);
-+
-+ /*
-+ * Set environmental variables with ifconfig parameters.
-+ */
-+ if (es)
-+ {
-+ setenv_str (es, "ifconfig_ipv6_local", ifconfig_ipv6_local);
-+ setenv_str (es, "ifconfig_ipv6_remote", ifconfig_ipv6_remote);
-+ }
-+ tt->did_ifconfig_ipv6_setup = true;
-+ }
-+
- gc_free (&gc);
- return tt;
- }
-@@ -559,6 +572,28 @@
- #endif
- }
-
-+#if defined(TARGET_WIN32) || \
-+ defined(TARGET_DARWIN) || defined(TARGET_NETBSD) || defined(TARGET_OPENBSD)
-+
-+/* some of the platforms will auto-add a "network route" pointing
-+ * to the interface on "ifconfig tunX 2001:db8::1/64", others need
-+ * an extra call to "route add..."
-+ * -> helper function to simplify code below
-+ */
-+void add_route_connected_v6_net(struct tuntap * tt,
-+ const struct env_set *es)
-+{
-+ struct route_ipv6 r6;
-+
-+ r6.defined = true;
-+ r6.network = tt->local_ipv6;
-+ r6.netbits = tt->netbits_ipv6;
-+ r6.gateway = tt->local_ipv6;
-+ add_route_ipv6 (&r6, tt, 0, es);
-+}
-+#endif
-+
-+
- /* execute the ifconfig command through the shell */
- void
- do_ifconfig (struct tuntap *tt,
-@@ -574,10 +609,16 @@
- const char *ifconfig_local = NULL;
- const char *ifconfig_remote_netmask = NULL;
- const char *ifconfig_broadcast = NULL;
-+ const char *ifconfig_ipv6_local = NULL;
-+ const char *ifconfig_ipv6_remote = NULL;
-+ bool do_ipv6 = false;
- struct argv argv;
-
- argv_init (&argv);
-
-+ msg( M_INFO, "do_ifconfig, tt->ipv6=%d, tt->did_ifconfig_ipv6_setup=%d",
-+ tt->ipv6, tt->did_ifconfig_ipv6_setup );
-+
- /*
- * We only handle TUN/TAP devices here, not --dev null devices.
- */
-@@ -589,6 +630,13 @@
- ifconfig_local = print_in_addr_t (tt->local, 0, &gc);
- ifconfig_remote_netmask = print_in_addr_t (tt->remote_netmask, 0, &gc);
-
-+ if ( tt->ipv6 && tt->did_ifconfig_ipv6_setup )
-+ {
-+ ifconfig_ipv6_local = print_in6_addr (tt->local_ipv6, 0, &gc);
-+ ifconfig_ipv6_remote = print_in6_addr (tt->remote_ipv6, 0, &gc);
-+ do_ipv6 = true;
-+ }
-+
- /*
- * If TAP-style device, generate broadcast address.
- */
-@@ -647,7 +695,19 @@
- argv_msg (M_INFO, &argv);
- openvpn_execve_check (&argv, es, S_FATAL, "Linux ip addr add failed");
- }
-- tt->did_ifconfig = true;
-+ if ( do_ipv6 )
-+ {
-+ argv_printf( &argv,
-+ "%s -6 addr add %s/%d dev %s",
-+ iproute_path,
-+ ifconfig_ipv6_local,
-+ tt->netbits_ipv6,
-+ actual
-+ );
-+ argv_msg (M_INFO, &argv);
-+ openvpn_execve_check (&argv, es, S_FATAL, "Linux ip -6 addr add failed");
-+ }
-+ tt->did_ifconfig = true;
- #else
- if (tun)
- argv_printf (&argv,
-@@ -670,6 +730,18 @@
- );
- argv_msg (M_INFO, &argv);
- openvpn_execve_check (&argv, es, S_FATAL, "Linux ifconfig failed");
-+ if ( do_ipv6 )
-+ {
-+ argv_printf (&argv,
-+ "%s %s inet6 add %s/%d",
-+ IFCONFIG_PATH,
-+ actual,
-+ ifconfig_ipv6_local,
-+ tt->netbits_ipv6
-+ );
-+ argv_msg (M_INFO, &argv);
-+ openvpn_execve_check (&argv, es, S_FATAL, "Linux ifconfig inet6 failed");
-+ }
- tt->did_ifconfig = true;
-
- #endif /*CONFIG_FEATURE_IPROUTE*/
-@@ -693,7 +765,7 @@
-
- argv_msg (M_INFO, &argv);
- if (!openvpn_execve_check (&argv, es, 0, "Solaris ifconfig phase-1 failed"))
-- solaris_error_close (tt, es, actual);
-+ solaris_error_close (tt, es, actual, false);
-
- argv_printf (&argv,
- "%s %s netmask 255.255.255.255",
-@@ -725,7 +797,53 @@
-
- argv_msg (M_INFO, &argv);
- if (!openvpn_execve_check (&argv, es, 0, "Solaris ifconfig phase-2 failed"))
-- solaris_error_close (tt, es, actual);
-+ solaris_error_close (tt, es, actual, false);
-+
-+ if ( do_ipv6 )
-+ {
-+ argv_printf (&argv, "%s %s inet6 unplumb",
-+ IFCONFIG_PATH, actual );
-+ argv_msg (M_INFO, &argv);
-+ openvpn_execve_check (&argv, es, 0, NULL);
-+
-+ if ( tt->type == DEV_TYPE_TUN )
-+ {
-+ argv_printf (&argv,
-+ "%s %s inet6 plumb %s/%d %s up",
-+ IFCONFIG_PATH,
-+ actual,
-+ ifconfig_ipv6_local,
-+ tt->netbits_ipv6,
-+ ifconfig_ipv6_remote
-+ );
-+ }
-+ else /* tap mode */
-+ {
-+ /* base IPv6 tap interface needs to be brought up first
-+ */
-+ argv_printf (&argv, "%s %s inet6 plumb up",
-+ IFCONFIG_PATH, actual );
-+ argv_msg (M_INFO, &argv);
-+ if (!openvpn_execve_check (&argv, es, 0, "Solaris ifconfig IPv6 (prepare) failed"))
-+ solaris_error_close (tt, es, actual, true);
-+
-+ /* we might need to do "ifconfig %s inet6 auto-dhcp drop"
-+ * after the system has noticed the interface and fired up
-+ * the DHCPv6 client - but this takes quite a while, and the
-+ * server will ignore the DHCPv6 packets anyway. So we don't.
-+ */
-+
-+ /* static IPv6 addresses need to go to a subinterface (tap0:1)
-+ */
-+ argv_printf (&argv,
-+ "%s %s inet6 addif %s/%d up",
-+ IFCONFIG_PATH, actual,
-+ ifconfig_ipv6_local, tt->netbits_ipv6 );
-+ }
-+ argv_msg (M_INFO, &argv);
-+ if (!openvpn_execve_check (&argv, es, 0, "Solaris ifconfig IPv6 failed"))
-+ solaris_error_close (tt, es, actual, true);
-+ }
-
- if (!tun && tt->topology == TOP_SUBNET)
- {
-@@ -787,10 +905,42 @@
- );
- argv_msg (M_INFO, &argv);
- openvpn_execve_check (&argv, es, S_FATAL, "OpenBSD ifconfig failed");
-+ if ( do_ipv6 )
-+ {
-+ argv_printf (&argv,
-+ "%s %s inet6 %s/%d",
-+ IFCONFIG_PATH,
-+ actual,
-+ ifconfig_ipv6_local,
-+ tt->netbits_ipv6
-+ );
-+ argv_msg (M_INFO, &argv);
-+ openvpn_execve_check (&argv, es, S_FATAL, "OpenBSD ifconfig inet6 failed");
-+
-+ /* and, hooray, we explicitely need to add a route... */
-+ add_route_connected_v6_net(tt, es);
-+ }
- tt->did_ifconfig = true;
-
- #elif defined(TARGET_NETBSD)
-
-+/* whether or not NetBSD can do IPv6 can be seen by the availability of
-+ * the TUNSIFHEAD ioctl() - see next TARGET_NETBSD block for more details
-+ */
-+#ifdef TUNSIFHEAD
-+# define NETBSD_MULTI_AF
-+#endif
-+
-+ /* as on OpenBSD and Darwin, destroy and re-create tun<x> interface
-+ */
-+ argv_printf (&argv, "%s %s destroy", IFCONFIG_PATH, actual );
-+ argv_msg (M_INFO, &argv);
-+ openvpn_execve_check (&argv, es, 0, "NetBSD ifconfig destroy failed");
-+
-+ argv_printf (&argv, "%s %s create", IFCONFIG_PATH, actual );
-+ argv_msg (M_INFO, &argv);
-+ openvpn_execve_check (&argv, es, S_FATAL, "NetBSD ifconfig create failed");
-+
- if (tun)
- argv_printf (&argv,
- "%s %s %s %s mtu %d netmask 255.255.255.255 up",
-@@ -817,6 +967,27 @@
- );
- argv_msg (M_INFO, &argv);
- openvpn_execve_check (&argv, es, S_FATAL, "NetBSD ifconfig failed");
-+
-+ if ( do_ipv6 )
-+ {
-+#ifdef NETBSD_MULTI_AF
-+ argv_printf (&argv,
-+ "%s %s inet6 %s/%d",
-+ IFCONFIG_PATH,
-+ actual,
-+ ifconfig_ipv6_local,
-+ tt->netbits_ipv6
-+ );
-+ argv_msg (M_INFO, &argv);
-+ openvpn_execve_check (&argv, es, S_FATAL, "NetBSD ifconfig inet6 failed");
-+
-+ /* and, hooray, we explicitely need to add a route... */
-+ add_route_connected_v6_net(tt, es);
-+#else
-+ msg( M_INFO, "no IPv6 support for tun interfaces on NetBSD before 4.0 (if your system is newer, recompile openvpn)" );
-+ tt->ipv6 = false;
-+#endif
-+ }
- tt->did_ifconfig = true;
-
- #elif defined(TARGET_DARWIN)
-@@ -882,6 +1053,22 @@
- add_route (&r, tt, 0, es);
- }
-
-+ if ( do_ipv6 )
-+ {
-+ argv_printf (&argv,
-+ "%s %s inet6 %s/%d",
-+ IFCONFIG_PATH,
-+ actual,
-+ ifconfig_ipv6_local,
-+ tt->netbits_ipv6
-+ );
-+ argv_msg (M_INFO, &argv);
-+ openvpn_execve_check (&argv, es, S_FATAL, "MacOS X ifconfig inet6 failed");
-+
-+ /* and, hooray, we explicitely need to add a route... */
-+ add_route_connected_v6_net(tt, es);
-+ }
-+
- #elif defined(TARGET_FREEBSD)||defined(TARGET_DRAGONFLY)
-
- /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
-@@ -920,6 +1107,19 @@
- add_route (&r, tt, 0, es);
- }
-
-+ if ( do_ipv6 )
-+ {
-+ argv_printf (&argv,
-+ "%s %s inet6 %s/%d",
-+ IFCONFIG_PATH,
-+ actual,
-+ ifconfig_ipv6_local,
-+ tt->netbits_ipv6
-+ );
-+ argv_msg (M_INFO, &argv);
-+ openvpn_execve_check (&argv, es, S_FATAL, "FreeBSD ifconfig inet6 failed");
-+ }
-+
- #elif defined (WIN32)
- {
- /*
-@@ -959,6 +1159,34 @@
- tt->did_ifconfig = true;
- }
-
-+ /* IPv6 always uses "netsh" interface */
-+ if ( do_ipv6 )
-+ {
-+ char * saved_actual;
-+
-+ if (!strcmp (actual, "NULL"))
-+ msg (M_FATAL, "Error: When using --tun-ipv6, if you have more than one TAP-Win32 adapter, you must also specify --dev-node");
-+
-+ /* example: netsh interface ipv6 add address MyTap 2001:608:8003::d */
-+ argv_printf (&argv,
-+ "%s%sc interface ipv6 add address %s %s",
-+ get_win_sys_path(),
-+ NETSH_PATH_SUFFIX,
-+ actual,
-+ ifconfig_ipv6_local );
-+
-+ netsh_command (&argv, 4);
-+
-+ /* explicit route needed */
-+ /* on windows, OpenVPN does ifconfig first, open_tun later, so
-+ * tt->actual_name might not yet be initialized, but routing code
-+ * needs to know interface name - point to "actual", restore later
-+ */
-+ saved_actual = tt->actual_name;
-+ tt->actual_name = (char*) actual;
-+ add_route_connected_v6_net(tt, es);
-+ tt->actual_name = saved_actual;
-+ }
- #else
- msg (M_FATAL, "Sorry, but I don't know how to do 'ifconfig' commands on this operating system. You should ifconfig your TUN/TAP device manually or use an --up script.");
- #endif
-@@ -991,14 +1219,16 @@
- #ifndef WIN32
- static void
- open_tun_generic (const char *dev, const char *dev_type, const char *dev_node,
-- bool ipv6, bool ipv6_explicitly_supported, bool dynamic,
-+ bool ipv6_explicitly_supported, bool dynamic,
- struct tuntap *tt)
- {
- char tunname[256];
- char dynamic_name[256];
- bool dynamic_opened = false;
-
-- ipv6_support (ipv6, ipv6_explicitly_supported, tt);
-+
-+ if ( tt->ipv6 && ! ipv6_explicitly_supported )
-+ msg (M_WARN, "NOTE: explicit support for IPv6 tun devices is not provided for this OS");
-
- if (tt->type == DEV_TYPE_NULL)
- {
-@@ -1094,16 +1324,16 @@
- #if !PEDANTIC
-
- void
--open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt)
-+open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
- {
- struct ifreq ifr;
-
-- /*
-- * Set tt->ipv6 to true if
-- * (a) we have the capability of supporting --tun-ipv6, and
-- * (b) --tun-ipv6 was specified.
-+ /* warn if a very old linux version is used & --tun-ipv6 set
- */
-- ipv6_support (ipv6, LINUX_IPV6, tt);
-+#if LINUX_IPV6 == 0
-+ if ( tt->ipv6 )
-+ msg (M_WARN, "NOTE: explicit support for IPv6 tun devices is not provided for this OS");
-+#endif
-
- /*
- * We handle --dev null specially, we do not open /dev/null for this.
-@@ -1212,7 +1442,7 @@
- #else
-
- void
--open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt)
-+open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
- {
- ASSERT (0);
- }
-@@ -1222,9 +1452,9 @@
- #else
-
- void
--open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt)
-+open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
- {
-- open_tun_generic (dev, dev_type, dev_node, ipv6, false, true, tt);
-+ open_tun_generic (dev, dev_type, dev_node, false, true, tt);
- }
-
- #endif /* HAVE_LINUX_IF_TUN_H */
-@@ -1244,7 +1474,7 @@
- #endif
-
- void
--tuncfg (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, int persist_mode, const char *username, const char *groupname, const struct tuntap_options *options)
-+tuncfg (const char *dev, const char *dev_type, const char *dev_node, int persist_mode, const char *username, const char *groupname, const struct tuntap_options *options)
- {
- struct tuntap *tt;
-
-@@ -1252,7 +1482,7 @@
- clear_tuntap (tt);
- tt->type = dev_type_enum (dev, dev_type);
- tt->options = *options;
-- open_tun (dev, dev_type, dev_node, ipv6, tt);
-+ open_tun (dev, dev_type, dev_node, tt);
- if (ioctl (tt->fd, TUNSETPERSIST, persist_mode) < 0)
- msg (M_ERR, "Cannot ioctl TUNSETPERSIST(%d) %s", persist_mode, dev);
- if (username != NULL)
-@@ -1395,7 +1625,7 @@
- #endif
-
- void
--open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt)
-+open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
- {
- int if_fd, ip_muxid, arp_muxid, arp_fd, ppa = -1;
- struct lifreq ifr;
-@@ -1406,7 +1636,10 @@
- bool is_tun;
- struct strioctl strioc_if, strioc_ppa;
-
-- ipv6_support (ipv6, true, tt);
-+ /* improved generic TUN/TAP driver from
-+ * http://www.whiteboard.ne.jp/~admin2/tuntap/
-+ * has IPv6 support
-+ */
- memset(&ifr, 0x0, sizeof(ifr));
-
- if (tt->type == DEV_TYPE_NULL)
-@@ -1561,6 +1794,18 @@
- {
- if (tt)
- {
-+ /* IPv6 interfaces need to be 'manually' de-configured */
-+ if ( tt->ipv6 && tt->did_ifconfig_ipv6_setup )
-+ {
-+ struct argv argv;
-+ argv_init (&argv);
-+ argv_printf( &argv, "%s %s inet6 unplumb",
-+ IFCONFIG_PATH, tt->actual_name );
-+ argv_msg (M_INFO, &argv);
-+ openvpn_execve_check (&argv, NULL, 0, "Solaris ifconfig inet6 unplumb failed");
-+ argv_reset (&argv);
-+ }
-+
- if (tt->ip_fd >= 0)
- {
- struct lifreq ifr;
-@@ -1613,11 +1858,20 @@
- }
-
- static void
--solaris_error_close (struct tuntap *tt, const struct env_set *es, const char *actual)
-+solaris_error_close (struct tuntap *tt, const struct env_set *es,
-+ const char *actual, bool unplumb_inet6 )
- {
- struct argv argv;
- argv_init (&argv);
-
-+ if (unplumb_inet6)
-+ {
-+ argv_printf( &argv, "%s %s inet6 unplumb",
-+ IFCONFIG_PATH, actual );
-+ argv_msg (M_INFO, &argv);
-+ openvpn_execve_check (&argv, es, 0, "Solaris ifconfig inet6 unplumb failed");
-+ }
-+
- argv_printf (&argv,
- "%s %s unplumb",
- IFCONFIG_PATH,
-@@ -1674,9 +1928,9 @@
- */
-
- void
--open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt)
-+open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
- {
-- open_tun_generic (dev, dev_type, dev_node, ipv6, true, true, tt);
-+ open_tun_generic (dev, dev_type, dev_node, true, true, tt);
-
- /* Enable multicast on the interface */
- if (tt->fd >= 0)
-@@ -1699,12 +1953,31 @@
- }
- }
-
-+/* the current way OpenVPN handles tun devices on OpenBSD leads to
-+ * lingering tunX interfaces after close -> for a full cleanup, they
-+ * need to be explicitely destroyed
-+ */
-+
- void
- close_tun (struct tuntap* tt)
- {
- if (tt)
- {
-+ struct gc_arena gc = gc_new ();
-+ struct argv argv;
-+
-+ /* setup command, close tun dev (clears tt->actual_name!), run command
-+ */
-+
-+ argv_init (&argv);
-+ argv_printf (&argv, "%s %s destroy",
-+ IFCONFIG_PATH, tt->actual_name);
-+
- close_tun_generic (tt);
-+
-+ argv_msg (M_INFO, &argv);
-+ openvpn_execve_check (&argv, NULL, 0, "OpenBSD 'destroy tun interface' failed (non-critical)");
-+
- free (tt);
- }
- }
-@@ -1767,33 +2040,51 @@
- #elif defined(TARGET_NETBSD)
-
- /*
-- * NetBSD does not support IPv6 on tun out of the box,
-- * but there exists a patch. When this patch is applied,
-- * only two things are left to openvpn:
-- * 1. Activate multicasting (this has already been done
-- * before by the kernel, but we make sure that nobody
-- * has deactivated multicasting inbetween.
-- * 2. Deactivate "link layer mode" (otherwise NetBSD
-- * prepends the address family to the packet, and we
-- * would run into the same trouble as with OpenBSD.
-+ * NetBSD before 4.0 does not support IPv6 on tun out of the box,
-+ * but there exists a patch (sys/net/if_tun.c, 1.79->1.80, see PR 32944).
-+ *
-+ * NetBSD 4.0 and up do, but we need to put the tun interface into
-+ * "multi_af" mode, which will prepend the address family to all packets
-+ * (same as OpenBSD and FreeBSD). If this is not enabled, the kernel
-+ * silently drops all IPv6 packets on output and gets confused on input.
-+ *
-+ * On earlier versions, multi_af is not available at all, so we have
-+ * two different NetBSD code variants here :-(
-+ *
- */
-
- void
--open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt)
-+open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
- {
-- open_tun_generic (dev, dev_type, dev_node, ipv6, true, true, tt);
-+#ifdef NETBSD_MULTI_AF
-+ open_tun_generic (dev, dev_type, dev_node, true, true, tt);
-+#else
-+ open_tun_generic (dev, dev_type, dev_node, false, true, tt);
-+#endif
-+
- if (tt->fd >= 0)
- {
- int i = IFF_POINTOPOINT|IFF_MULTICAST;
- ioctl (tt->fd, TUNSIFMODE, &i); /* multicast on */
- i = 0;
- ioctl (tt->fd, TUNSLMODE, &i); /* link layer mode off */
-+
-+#ifdef NETBSD_MULTI_AF
-+ i = 1;
-+ if (ioctl (tt->fd, TUNSIFHEAD, &i) < 0) /* multi-af mode on */
-+ {
-+ msg (M_WARN | M_ERRNO, "ioctl(TUNSIFHEAD): %s", strerror(errno));
-+ }
-+#endif
- }
- }
-
- void
- close_tun (struct tuntap *tt)
- {
-+ /* TODO: we really should cleanup non-persistant tunX with
-+ * "ifconfig tunX destroy" here...
-+ */
- if (tt)
- {
- close_tun_generic (tt);
-@@ -1801,6 +2092,65 @@
- }
- }
-
-+#ifdef NETBSD_MULTI_AF
-+
-+static inline int
-+netbsd_modify_read_write_return (int len)
-+{
-+ if (len > 0)
-+ return len > sizeof (u_int32_t) ? len - sizeof (u_int32_t) : 0;
-+ else
-+ return len;
-+}
-+
-+int
-+write_tun (struct tuntap* tt, uint8_t *buf, int len)
-+{
-+ if (tt->type == DEV_TYPE_TUN)
-+ {
-+ u_int32_t type;
-+ struct iovec iv[2];
-+ struct openvpn_iphdr *iph;
-+
-+ iph = (struct openvpn_iphdr *) buf;
-+
-+ if (tt->ipv6 && OPENVPN_IPH_GET_VER(iph->version_len) == 6)
-+ type = htonl (AF_INET6);
-+ else
-+ type = htonl (AF_INET);
-+
-+ iv[0].iov_base = (char *)&type;
-+ iv[0].iov_len = sizeof (type);
-+ iv[1].iov_base = buf;
-+ iv[1].iov_len = len;
-+
-+ return netbsd_modify_read_write_return (writev (tt->fd, iv, 2));
-+ }
-+ else
-+ return write (tt->fd, buf, len);
-+}
-+
-+int
-+read_tun (struct tuntap* tt, uint8_t *buf, int len)
-+{
-+ if (tt->type == DEV_TYPE_TUN)
-+ {
-+ u_int32_t type;
-+ struct iovec iv[2];
-+
-+ iv[0].iov_base = (char *)&type;
-+ iv[0].iov_len = sizeof (type);
-+ iv[1].iov_base = buf;
-+ iv[1].iov_len = len;
-+
-+ return netbsd_modify_read_write_return (readv (tt->fd, iv, 2));
-+ }
-+ else
-+ return read (tt->fd, buf, len);
-+}
-+
-+#else /* not NETBSD_MULTI_AF -> older code, IPv4 only */
-+
- int
- write_tun (struct tuntap* tt, uint8_t *buf, int len)
- {
-@@ -1812,6 +2162,7 @@
- {
- return read (tt->fd, buf, len);
- }
-+#endif /* NETBSD_MULTI_AF */
-
- #elif defined(TARGET_FREEBSD)
-
-@@ -1825,9 +2176,9 @@
- }
-
- void
--open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt)
-+open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
- {
-- open_tun_generic (dev, dev_type, dev_node, ipv6, true, true, tt);
-+ open_tun_generic (dev, dev_type, dev_node, true, true, tt);
-
- if (tt->fd >= 0 && tt->type == DEV_TYPE_TUN)
- {
-@@ -1913,9 +2264,9 @@
- }
-
- void
--open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt)
-+open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
- {
-- open_tun_generic (dev, dev_type, dev_node, ipv6, true, true, tt);
-+ open_tun_generic (dev, dev_type, dev_node, true, true, tt);
-
- if (tt->fd >= 0)
- {
-@@ -1984,6 +2335,61 @@
- return read (tt->fd, buf, len);
- }
-
-+#elif defined(TARGET_DARWIN)
-+
-+/* Darwin (MacOS X) is mostly "just use the generic stuff", but there
-+ * is always one caveat...:
-+ *
-+ * If IPv6 is configured, and the tun device is closed, the IPv6 address
-+ * configured to the tun interface changes to a lingering /128 route
-+ * pointing to lo0. Need to unconfigure... (observed on 10.5)
-+ */
-+
-+void
-+open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
-+{
-+ open_tun_generic (dev, dev_type, dev_node, false, true, tt);
-+}
-+
-+void
-+close_tun (struct tuntap* tt)
-+{
-+ if (tt)
-+ {
-+ struct gc_arena gc = gc_new ();
-+ struct argv argv;
-+ argv_init (&argv);
-+
-+ if ( tt->ipv6 && tt->did_ifconfig_ipv6_setup )
-+ {
-+ const char * ifconfig_ipv6_local =
-+ print_in6_addr (tt->local_ipv6, 0, &gc);
-+
-+ argv_printf (&argv, "%s delete -inet6 %s",
-+ ROUTE_PATH, ifconfig_ipv6_local );
-+ argv_msg (M_INFO, &argv);
-+ openvpn_execve_check (&argv, NULL, 0, "MacOS X 'remove inet6 route' failed (non-critical)");
-+ }
-+
-+ close_tun_generic (tt);
-+ free (tt);
-+ argv_reset (&argv);
-+ gc_free (&gc);
-+ }
-+}
-+
-+int
-+write_tun (struct tuntap* tt, uint8_t *buf, int len)
-+{
-+ return write (tt->fd, buf, len);
-+}
-+
-+int
-+read_tun (struct tuntap* tt, uint8_t *buf, int len)
-+{
-+ return read (tt->fd, buf, len);
-+}
-+
- #elif defined(WIN32)
-
- int
-@@ -3969,7 +4375,7 @@
- }
-
- void
--open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt)
-+open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
- {
- struct gc_arena gc = gc_new ();
- char device_path[256];
-@@ -3980,7 +4386,7 @@
-
- /*netcmd_semaphore_lock ();*/
-
-- ipv6_support (ipv6, false, tt);
-+ msg( M_INFO, "open_tun, tt->ipv6=%d", tt->ipv6 );
-
- if (tt->type == DEV_TYPE_NULL)
- {
-@@ -4102,6 +4508,16 @@
- msg (M_FATAL, "ERROR: This version of " PACKAGE_NAME " requires a TAP-Win32 driver that is at least version %d.%d -- If you recently upgraded your " PACKAGE_NAME " distribution, a reboot is probably required at this point to get Windows to see the new driver.",
- TAP_WIN32_MIN_MAJOR,
- TAP_WIN32_MIN_MINOR);
-+
-+ /* usage of numeric constants is ugly, but this is really tied to
-+ * *this* version of the driver
-+ */
-+ if ( tt->ipv6 && tt->type == DEV_TYPE_TUN &&
-+ info[0] == 9 && info[1] < 8)
-+ {
-+ msg( M_INFO, "WARNING: Tap-Win32 driver version %d.%d does not support IPv6 in TUN mode. IPv6 will be disabled. Upgrade to Tap-Win32 9.8 (2.2-beta3 release or later) or use TAP mode to get IPv6", (int) info[0], (int) info[1] );
-+ tt->ipv6 = false;
-+ }
- }
-
- /* get driver MTU */
-@@ -4426,6 +4842,12 @@
-
- if (tt)
- {
-+ if ( tt->ipv6 && tt->did_ifconfig_ipv6_setup )
-+ {
-+ /* netsh interface ipv6 delete address \"%s\" %s */
-+ const char * ifconfig_ipv6_local = print_in6_addr (tt->local_ipv6, 0, &gc);
-+ msg( M_WARN, "TODO: remove IPv6 address %s", ifconfig_ipv6_local );
-+ }
- #if 1
- if (tt->ipapi_context_defined)
- {
-@@ -4529,9 +4951,9 @@
- #else /* generic */
-
- void
--open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt)
-+open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
- {
-- open_tun_generic (dev, dev_type, dev_node, ipv6, false, true, tt);
-+ open_tun_generic (dev, dev_type, dev_node, false, true, tt);
- }
-
- void
-Index: openvpn-2.2.1/tun.h
-===================================================================
---- openvpn-2.2.1.orig/tun.h 2011-06-24 08:13:39.000000000 +0200
-+++ openvpn-2.2.1/tun.h 2011-12-13 12:24:54.653739003 +0100
-@@ -130,6 +130,7 @@
- int topology; /* one of the TOP_x values */
-
- bool did_ifconfig_setup;
-+ bool did_ifconfig_ipv6_setup;
- bool did_ifconfig;
-
- bool ipv6;
-@@ -146,6 +147,10 @@
- in_addr_t remote_netmask;
- in_addr_t broadcast;
-
-+ struct in6_addr local_ipv6;
-+ struct in6_addr remote_ipv6;
-+ int netbits_ipv6;
-+
- #ifdef WIN32
- HANDLE hand;
- struct overlapped_io reads;
-@@ -197,7 +202,7 @@
- void clear_tuntap (struct tuntap *tuntap);
-
- void open_tun (const char *dev, const char *dev_type, const char *dev_node,
-- bool ipv6, struct tuntap *tt);
-+ struct tuntap *tt);
-
- void close_tun (struct tuntap *tt);
-
-@@ -206,7 +211,7 @@
- int read_tun (struct tuntap* tt, uint8_t *buf, int len);
-
- void tuncfg (const char *dev, const char *dev_type, const char *dev_node,
-- bool ipv6, int persist_mode, const char *username,
-+ int persist_mode, const char *username,
- const char *groupname, const struct tuntap_options *options);
-
- const char *guess_tuntap_dev (const char *dev,
-@@ -219,6 +224,8 @@
- int topology, /* one of the TOP_x values */
- const char *ifconfig_local_parm, /* --ifconfig parm 1 */
- const char *ifconfig_remote_netmask_parm, /* --ifconfig parm 2 */
-+ const char *ifconfig_ipv6_local_parm, /* --ifconfig parm 1 / IPv6 */
-+ const char *ifconfig_ipv6_remote_parm, /* --ifconfig parm 2 / IPv6 */
- in_addr_t local_public,
- in_addr_t remote_public,
- const bool strict_warn,
-Index: openvpn-2.2.1/win32.c
-===================================================================
---- openvpn-2.2.1.orig/win32.c 2011-06-24 08:13:39.000000000 +0200
-+++ openvpn-2.2.1/win32.c 2011-12-13 12:24:54.654738990 +0100
-@@ -874,16 +874,21 @@
- static char *
- env_block (const struct env_set *es)
- {
-+ char * force_path = "PATH=C:\\Windows\\System32;C:\\WINDOWS;C:\\WINDOWS\\System32\\Wbem";
-+
- if (es)
- {
- struct env_item *e;
- char *ret;
- char *p;
- size_t nchars = 1;
-+ bool path_seen = false;
-
- for (e = es->list; e != NULL; e = e->next)
- nchars += strlen (e->string) + 1;
-
-+ nchars += strlen(force_path)+1;
-+
- ret = (char *) malloc (nchars);
- check_malloc_return (ret);
-
-@@ -895,7 +900,18 @@
- strcpy (p, e->string);
- p += strlen (e->string) + 1;
- }
-+ if ( strncmp(e->string, "PATH=", 5 ) == 0 )
-+ path_seen = true;
-+ }
-+
-+ /* make sure PATH is set */
-+ if ( !path_seen )
-+ {
-+ msg( M_INFO, "env_block: add %s", force_path );
-+ strcpy( p, force_path );
-+ p += strlen(force_path) + 1;
- }
-+
- *p = '\0';
- return ret;
- }
-Index: openvpn-2.2.1/win32.h
-===================================================================
---- openvpn-2.2.1.orig/win32.h 2011-12-13 12:23:07.000000000 +0100
-+++ openvpn-2.2.1/win32.h 2011-12-13 12:24:54.654738990 +0100
-@@ -272,6 +272,8 @@
-
- /* call self in a subprocess */
- void fork_to_self (const char *cmdline);
-+const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
-+int inet_pton(int af, const char *src, void *st);
-
- /* Find temporary directory */
- const char *win_get_tempdir();
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;
diff --git a/debian/patches/manpage_dash_escaping.patch b/debian/patches/manpage_dash_escaping.patch
deleted file mode 100644
index 23fdb03..0000000
--- a/debian/patches/manpage_dash_escaping.patch
+++ /dev/null
@@ -1,20 +0,0 @@
-Index: openvpn-2.2.0/openvpn.8
-===================================================================
---- openvpn-2.2.0.orig/openvpn.8 2011-04-21 21:13:51.000000000 +0200
-+++ openvpn-2.2.0/openvpn.8 2011-05-10 16:19:19.548001393 +0200
-@@ -21,13 +21,13 @@
- .\" 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- .\"
- .\" Manual page for openvpn
--.\
-+.\"
- .\" SH section heading
- .\" SS subsection heading
- .\" LP paragraph
- .\" IP indented paragraph
- .\" TP hanging label
--.\
-+.\"
- .\" .nf -- no formatting
- .\" .fi -- resume formatting
- .\" .ft 3 -- boldface
diff --git a/debian/patches/remote_env.patch b/debian/patches/remote_env.patch
deleted file mode 100644
index ae26415..0000000
--- a/debian/patches/remote_env.patch
+++ /dev/null
@@ -1,15 +0,0 @@
-Index: openvpn-2.1_rc15/options.c
-===================================================================
---- openvpn-2.1_rc15.orig/options.c 2009-04-30 12:58:46.952616319 +0200
-+++ openvpn-2.1_rc15/options.c 2009-04-30 12:58:50.352666598 +0200
-@@ -769,8 +769,8 @@
- setenv_str_i (es, "proto", proto2ascii (e->proto, false), i);
- setenv_str_i (es, "local", e->local, i);
- setenv_int_i (es, "local_port", e->local_port, i);
-- setenv_str_i (es, "remote", e->local, i);
-- setenv_int_i (es, "remote_port", e->local_port, i);
-+ setenv_str_i (es, "remote", e->remote, i);
-+ setenv_int_i (es, "remote_port", e->remote_port, i);
-
- #ifdef ENABLE_HTTP_PROXY
- if (e->http_proxy_options)
diff --git a/debian/patches/update_sample_certs.patch b/debian/patches/update_sample_certs.patch
deleted file mode 100644
index 38e49ef..0000000
--- a/debian/patches/update_sample_certs.patch
+++ /dev/null
@@ -1,532 +0,0 @@
-Index: openvpn/sample/sample-keys/ca.crt
-===================================================================
---- openvpn.orig/sample/sample-keys/ca.crt 2014-12-01 17:35:28.603250441 +0100
-+++ openvpn/sample/sample-keys/ca.crt 2014-12-01 17:35:28.599250441 +0100
-@@ -1,19 +1,35 @@
- -----BEGIN CERTIFICATE-----
--MIIDBjCCAm+gAwIBAgIBADANBgkqhkiG9w0BAQQFADBmMQswCQYDVQQGEwJLRzEL
-+MIIGKDCCBBCgAwIBAgIJAKFO3vqQ8q6BMA0GCSqGSIb3DQEBCwUAMGYxCzAJBgNV
-+BAYTAktHMQswCQYDVQQIEwJOQTEQMA4GA1UEBxMHQklTSEtFSzEVMBMGA1UEChMM
-+T3BlblZQTi1URVNUMSEwHwYJKoZIhvcNAQkBFhJtZUBteWhvc3QubXlkb21haW4w
-+HhcNMTQxMDIyMjE1OTUyWhcNMjQxMDE5MjE1OTUyWjBmMQswCQYDVQQGEwJLRzEL
- MAkGA1UECBMCTkExEDAOBgNVBAcTB0JJU0hLRUsxFTATBgNVBAoTDE9wZW5WUE4t
--VEVTVDEhMB8GCSqGSIb3DQEJARYSbWVAbXlob3N0Lm15ZG9tYWluMB4XDTA0MTEy
--NTE0NDA1NVoXDTE0MTEyMzE0NDA1NVowZjELMAkGA1UEBhMCS0cxCzAJBgNVBAgT
--Ak5BMRAwDgYDVQQHEwdCSVNIS0VLMRUwEwYDVQQKEwxPcGVuVlBOLVRFU1QxITAf
--BgkqhkiG9w0BCQEWEm1lQG15aG9zdC5teWRvbWFpbjCBnzANBgkqhkiG9w0BAQEF
--AAOBjQAwgYkCgYEAqPjWJnesPu6bR/iec4FMz3opVaPdBHxg+ORKNmrnVZPh0t8/
--ZT34KXkYoI9B82scurp8UlZVXG8JdUsz+yai8ti9+g7vcuyKUtcCIjn0HLgmdPu5
--gFX25lB0pXw+XIU031dOfPvtROdG5YZN5yCErgCy7TE7zntLnkEDuRmyU6cCAwEA
--AaOBwzCBwDAdBgNVHQ4EFgQUiaZg47rqPq/8ZH9MvYzSSI3gzEYwgZAGA1UdIwSB
--iDCBhYAUiaZg47rqPq/8ZH9MvYzSSI3gzEahaqRoMGYxCzAJBgNVBAYTAktHMQsw
--CQYDVQQIEwJOQTEQMA4GA1UEBxMHQklTSEtFSzEVMBMGA1UEChMMT3BlblZQTi1U
--RVNUMSEwHwYJKoZIhvcNAQkBFhJtZUBteWhvc3QubXlkb21haW6CAQAwDAYDVR0T
--BAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQBfJoiWYrYdjM0mKPEzUQk0nLYTovBP
--I0es/2rfGrin1zbcFY+4dhVBd1E/StebnG+CP8r7QeEIwu7x8gYDdOLLsZn+2vBL
--e4jNU1ClI6Q0L7jrzhhunQ5mAaZztVyYwFB15odYcdN2iO0tP7jtEsvrRqxICNy3
--8itzViPTf5W4sA==
-+VEVTVDEhMB8GCSqGSIb3DQEJARYSbWVAbXlob3N0Lm15ZG9tYWluMIICIjANBgkq
-+hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsJVPCqt3vtoDW2U0DII1QIh2Qs0dqh88
-+8nivxAIm2LTq93e9fJhsq3P/UVYAYSeCIrekXypR0EQgSgcNTvGBMe20BoHO5yvb
-+GjKPmjfLj6XRotCOGy8EDl/hLgRY9efiA8wsVfuvF2q/FblyJQPR/gPiDtTmUiqF
-+qXa7AJmMrqFsnWppOuGd7Qc6aTsae4TF1e/gUTCTraa7NeHowDaKhdyFmEEnCYR5
-+CeUsx2JlFWAH8PCrxBpHYbmGyvS0kH3+rQkaSM/Pzc2bS4ayHaOYRK5XsGq8XiNG
-+KTTLnSaCdPeHsI+3xMHmEh+u5Og2DFGgvyD22gde6W2ezvEKCUDrzR7bsnYqqyUy
-+n7LxnkPXGyvR52T06G8KzLKQRmDlPIXhzKMO07qkHmIonXTdF7YI1azwHpAtN4dS
-+rUe1bvjiTSoEsQPfOAyvD0RMK/CBfgEZUzAB50e/IlbZ84c0DJfUMOm4xCyft1HF
-+YpYeyCf5dxoIjweCPOoP426+aTXM7kqq0ieIr6YxnKV6OGGLKEY+VNZh1DS7enqV
-+HP5i8eimyuUYPoQhbK9xtDGMgghnc6Hn8BldPMcvz98HdTEH4rBfA3yNuCxLSNow
-+4jJuLjNXh2QeiUtWtkXja7ec+P7VqKTduJoRaX7cs+8E3ImigiRnvmK+npk7Nt1y
-+YE9hBRhSoLsCAwEAAaOB2DCB1TAdBgNVHQ4EFgQUK0DlyX319JY46S/jL9lAZMmO
-+BZswgZgGA1UdIwSBkDCBjYAUK0DlyX319JY46S/jL9lAZMmOBZuhaqRoMGYxCzAJ
-+BgNVBAYTAktHMQswCQYDVQQIEwJOQTEQMA4GA1UEBxMHQklTSEtFSzEVMBMGA1UE
-+ChMMT3BlblZQTi1URVNUMSEwHwYJKoZIhvcNAQkBFhJtZUBteWhvc3QubXlkb21h
-+aW6CCQChTt76kPKugTAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG
-+9w0BAQsFAAOCAgEABc77f4C4P8fIS+V8qCJmVNSDU44UZBc+D+J6ZTgW8JeOHUIj
-+Bh++XDg3gwat7pIWQ8AU5R7h+fpBI9n3dadyIsMHGwSogHY9Gw7di2RVtSFajEth
-+rvrq0JbzpwoYedMh84sJ2qI/DGKW9/Is9+O52fR+3z3dY3gNRDPQ5675BQ5CQW9I
-+AJgLOqzD8Q0qrXYi7HaEqzNx6p7RDTuhFgvTd+vS5d5+28Z5fm2umnq+GKHF8W5P
-+ylp2Js119FTVO7brusAMKPe5emc7tC2ov8OFFemQvfHR41PLryap2VD81IOgmt/J
-+kX/j/y5KGux5HZ3lxXqdJbKcAq4NKYQT0mCkRD4l6szaCEJ+k0SiM9DdTcBDefhR
-+9q+pCOyMh7d8QjQ1075mF7T+PGkZQUW1DUjEfrZhICnKgq+iEoUmM0Ee5WtRqcnu
-+5BTGQ2mSfc6rV+Vr+eYXqcg7Nxb3vFXYSTod1UhefonVqwdmyJ2sC79zp36Tbo2+
-+65NW2WJK7KzPUyOJU0U9bcu0utvDOvGWmG+aHbymJgcoFzvZmlXqMXn97pSFn4jV
-+y3SLRgJXOw1QLXL2Y5abcuoBVr4gCOxxk2vBeVxOMRXNqSWZOFIF1bu/PxuDA+Sa
-+hEi44aHbPXt9opdssz/hdGfd8Wo7vEJrbg7c6zR6C/Akav1Rzy9oohIdgOw=
- -----END CERTIFICATE-----
-Index: openvpn/sample/sample-keys/ca.key
-===================================================================
---- openvpn.orig/sample/sample-keys/ca.key 2014-12-01 17:35:28.603250441 +0100
-+++ openvpn/sample/sample-keys/ca.key 2014-12-01 17:35:28.599250441 +0100
-@@ -1,15 +1,52 @@
-------BEGIN RSA PRIVATE KEY-----
--MIICXQIBAAKBgQCo+NYmd6w+7ptH+J5zgUzPeilVo90EfGD45Eo2audVk+HS3z9l
--PfgpeRigj0Hzaxy6unxSVlVcbwl1SzP7JqLy2L36Du9y7IpS1wIiOfQcuCZ0+7mA
--VfbmUHSlfD5chTTfV058++1E50blhk3nIISuALLtMTvOe0ueQQO5GbJTpwIDAQAB
--AoGAQuVREyWp4bhhbZr2UFBOco2ws6EOLWp4kdD/uI+WSoEjlHKiDJj+GJ1CrL5K
--o+4yD5MpCQf4/4FOQ0ukprfjJpDwDinTG6vzuWSLTHNiTgvksW3vy7IsNMJx97hT
--4D2QOOl9HhA50Qqg70teMPYXOgLRMVsdCIV7p7zDNy4nM+ECQQDX8m5ZcQmPtUDA
--38dPTfpL4U7kMB94FItJYH/Lk5kMW1/J33xymNhL+BHaG064ol9n2ubGW4XEO5t2
--qE1IOsVpAkEAyE/x/OBVSI1s75aYGlEwMd87p3qaDdtXT7WzujjRY7r8Y1ynkMU6
--GtMeneBX/lk4BY/6I+5bhAzce+hqhaXejwJBAL5Wg+c4GApf41xdogqHm7doNyYw
--OHyZ9w9NDDc+uGbI30xLPSCxEe0cEXgiG6foDpm2uzRZFTWaqHPU8pFYpAkCQGNX
--cpWM0/7VVK9Fqk1y8knpgfY/UWOJ4jU/0dCLGR0ywLSuYNPlXDmtdkOp3TnhGW14
--x/9F2NEWZ8pzq1B4wHUCQQC5ztD4m/rpiIpinoewUJODoeBJXYBKqx1+mdrALCq6
--ESvK1WRiusMaY3xmsdv4J2TB5iUPryELbn3jU12WGcQc
-------END RSA PRIVATE KEY-----
-+-----BEGIN PRIVATE KEY-----
-+MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQCwlU8Kq3e+2gNb
-+ZTQMgjVAiHZCzR2qHzzyeK/EAibYtOr3d718mGyrc/9RVgBhJ4Iit6RfKlHQRCBK
-+Bw1O8YEx7bQGgc7nK9saMo+aN8uPpdGi0I4bLwQOX+EuBFj15+IDzCxV+68Xar8V
-+uXIlA9H+A+IO1OZSKoWpdrsAmYyuoWydamk64Z3tBzppOxp7hMXV7+BRMJOtprs1
-+4ejANoqF3IWYQScJhHkJ5SzHYmUVYAfw8KvEGkdhuYbK9LSQff6tCRpIz8/NzZtL
-+hrIdo5hErlewarxeI0YpNMudJoJ094ewj7fEweYSH67k6DYMUaC/IPbaB17pbZ7O
-+8QoJQOvNHtuydiqrJTKfsvGeQ9cbK9HnZPTobwrMspBGYOU8heHMow7TuqQeYiid
-+dN0XtgjVrPAekC03h1KtR7Vu+OJNKgSxA984DK8PREwr8IF+ARlTMAHnR78iVtnz
-+hzQMl9Qw6bjELJ+3UcVilh7IJ/l3GgiPB4I86g/jbr5pNczuSqrSJ4ivpjGcpXo4
-+YYsoRj5U1mHUNLt6epUc/mLx6KbK5Rg+hCFsr3G0MYyCCGdzoefwGV08xy/P3wd1
-+MQfisF8DfI24LEtI2jDiMm4uM1eHZB6JS1a2ReNrt5z4/tWopN24mhFpftyz7wTc
-+iaKCJGe+Yr6emTs23XJgT2EFGFKguwIDAQABAoICAQCEYPqnihI0PqZjnwQdGIQp
-+g+P8gl7pyY9cS0OhUueicEbyDI8+V9qn0kcmx61zKDY0Jq4QNd6tnlUCijTc6Mot
-+DwF2G1xsC4GvKxZiy89MOkhloanXETEeQZzDbbjvaM4UgL0AHLWPfZQRCjxbKXkE
-+0A5phgvAr2YSvBLHCVXhGN0fScXnwXouVsvgVdGtpcTWdIUa+KrNdQBGDbz6VCkW
-+31I76SQFy40d8PPX6ZjUJHDvnM14LycySO6XOkofRIVnXTqaOUiVBb2VKj5fX+Ro
-+ILdWZz4d6J3RiGXYwyTr4SGVKLjgxWfgUGZB7x+NrqgugNzuaLYrkuWKSEN42nWq
-+yoP6x6xtbAsmB6Fvdqwm/d8BmLhUweaVc0L7AYzXNsOBuT3kubJHMmu3Jv4xgyWk
-+l/MAGJQc7i7QQweGgsYZgR8WlbkWkSFpUcgQBDzDibb6nsD2jnYijQrnrrmiEjEI
-+R7MO551V+nFw9utiM8U9WIWwqzY0d98ujWkGjVe7uz9ZBVyg0DEAEj/zRi9T54aG
-+1V6CB2Cjyw+HzzsDw7yWroWzo4U9YfjbPKCoBsXlqQFLFwY8oL6mEZ7UOobaV1Zl
-+WtuHyYw3UNFxuSGPPyxJkFePIQLLvfKvh2R+V0DrT3UJRoKKlt9RejRSN0tOh0Cm
-+2YD6d7T/DXnQHomIQKhKEQKCAQEA3sgsDg0eKDK8pUyVE+9wW5kql12nTzpBtnCM
-+eg5J9OJcXKhCD/NIyUTIMXoMvZQpLwGUAYLgu4gE04zKWHDouf7MRSFltD5LJ7F2
-+7nuYKHZXk0BhgMhdnQot3FKcOMrKCnZcM+RWX9ZJa8wO6whCaYCw7DtS0SSVODQk
-+9EwAgX6/Hq60V7ujPZJCyNd3o0bIdAA/0AQRTZUADP3AHgUzh71aysYJt+UKt1v0
-+Xc7l6hn7Dn7Ewzpf+WdZ2pV7d3JUSBVKiTDxLV904nDBNOxjMhz0rW01ojR6bzpn
-+XhkFPqnmh+yEYGRgfSAAzkvSsSJEAtBFSicupA/6n83Lo2YvswKCAQEAyumuxP4Z
-+a7s8x8DFba7vuQ+KVxpkKgEz1sxnGRNQJm18/ss/Y5JiaLFYT3E72VkQfBQ2ngu+
-+GrJL3OhiNhzy1KLGS6mrwULtKiuud5MMQDL0Pvkncr9NTy4rBnWzhp2XyPeETu8n
-+JpL2i2OK6lY/lgpBckXuap9gAl0fXk+y+BkZ71OoYaGnKpPjs+Xcq/qgPgZ7O3NW
-+1g+Bd2AVPSxQpXjuy5rgtQURCN733vkNBzFedKREx7Z6l8UPlK/Exuc7BMIHfn5V
-+dd0R3Th+82fkMNVJz6MKmHJ6CJI53M7co/YdAvIkxOFRIPGbO3arL2R69nRgAZBE
-+zLawx1JJTRIG2QKCAQATtZXgMFzopYR3A011FAvWrrhL5+czZS4HG/Hxom38kkIl
-+mGUv0BAybjlf1zJlW0RBelxDvfZv4Nq8dIo6RNLyEY601v2OcqxneJXTB3AwtDeP
-+OXTm1dMiX5IrGcvkYlx5jHsfxCW4GNcqCEWRmYt2lgIRBDaRdjEVZdeXHVo2GqaB
-+6mbeFCWe/t+VsSpOcaauTI9YseNt/66fd5uVjFRAwAnWQqr9b/AAxMvbuMAyc9X4
-+NFLoCrQO9ovGgM8JhD3cmrWbaY8MupM2rU8KhZdJCbLD3ROPpCDo0jvu4TvLjXBt
-+ugkEFh1LNJedqKudLDDkJtTaeJjxvtAnbyeC7zltAoIBAC9TIyzUqq8io0FfZ2x2
-+cXiy9CvuftABKcr+L0l85KOhw5ZVZvpdKNCMFDGrEi9WA28886QWzwbA8Mqb9FP0
-+mnoXYLJC50kSx+ee+nju9dt/RtHtIFM15N0DwosmJnHODZmUiOo0AuiPPCs0UzDm
-+Xrwqtirlvn5ln2nNuEQxyGbuy8qys0HaBvf6OBA8GySNNpRgxJsQAn+4bBSgdzOm
-+Q0TkmKUqASCXBusPvbXmVjCIRiRkL5p4p8z/6+tct0NAqNYqPr80zc/IeKMkyw8P
-++vucszNXLmBxyp53JEGoiXNAMnH+ca7tchOB5hePTMun3rneWInk0PcB4OcL/QaZ
-+nrkCggEBAN67+SvcWtM1BoLXSz5/apFAE+DicCv94PrvMBOhfvu1oBrElR1rBjiN
-+2B83SktkF4WhCXr10GP+RUpjaqPBtT7NW4r3fL5B8EPsHeabL+pg9e6wG1rH8GqG
-+toWecmfC9uqK7l1A59h5Oveq5K19bZTRZRjQtv2e4KQknlJR6cwy+TGUU5kAUlMt
-+vcivyjzxc0UQwq7zKktJq+xW/TZiSLgd3B32p0sXX378qFUJ4SO2UZ1OCh8R7PY1
-+Fx25K/89Q1yGdbYiXb/Dx0a2WB9rP+b6alMl/dxPdqDKj2QXXkdh8+yvhVpQTyZw
-+B1RaqQXwzqrCH0F/vw3lRceYhcQvzcQ=
-+-----END PRIVATE KEY-----
-Index: openvpn/sample/sample-keys/client.crt
-===================================================================
---- openvpn.orig/sample/sample-keys/client.crt 2014-12-01 17:35:28.603250441 +0100
-+++ openvpn/sample/sample-keys/client.crt 2014-12-01 17:35:28.599250441 +0100
-@@ -2,64 +2,102 @@
- Data:
- Version: 3 (0x2)
- Serial Number: 2 (0x2)
-- Signature Algorithm: md5WithRSAEncryption
-+ Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=KG, ST=NA, L=BISHKEK, O=OpenVPN-TEST/emailAddress=me@myhost.mydomain
- Validity
-- Not Before: Nov 25 14:46:49 2004 GMT
-- Not After : Nov 23 14:46:49 2014 GMT
-+ Not Before: Oct 22 21:59:53 2014 GMT
-+ Not After : Oct 19 21:59:53 2024 GMT
- Subject: C=KG, ST=NA, O=OpenVPN-TEST, CN=Test-Client/emailAddress=me@myhost.mydomain
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
-- RSA Public Key: (1024 bit)
-- Modulus (1024 bit):
-- 00:d2:12:5c:c6:4d:13:34:ae:cf:fa:ab:fe:cb:de:
-- 8c:f1:4b:4a:95:28:60:87:82:2c:b8:c1:e5:8e:c6:
-- 5d:11:58:61:a4:a5:f1:42:d7:86:74:6c:9d:9c:7a:
-- f0:3a:5c:29:e6:53:3b:5e:6d:d8:f0:45:06:2c:23:
-- ee:09:bc:02:8f:0e:b8:d5:33:1f:c3:4a:11:02:48:
-- 0b:cc:4b:ad:6e:74:e0:a2:53:b1:d6:cc:89:b9:e2:
-- 6f:db:15:b3:19:1e:57:04:79:48:3a:da:76:31:fc:
-- bf:d3:34:21:e7:32:d8:9e:06:4e:be:f3:e3:79:b0:
-- 54:fd:d1:42:32:aa:3e:7a:c1
-+ Public-Key: (2048 bit)
-+ Modulus:
-+ 00:ec:65:8f:e9:12:c2:1a:5b:e6:56:2a:08:a9:82:
-+ 3a:2d:44:78:a3:00:3b:b0:9f:e7:27:10:40:93:ef:
-+ f1:cc:3e:a0:aa:04:a2:80:1b:13:a9:e6:fe:81:d6:
-+ 70:90:a8:d8:d4:de:30:d8:35:00:d2:be:62:f0:48:
-+ da:fc:15:8d:c4:c6:6d:0b:99:f1:2b:83:00:0a:d3:
-+ 2a:23:0b:e5:cd:f9:35:df:43:61:15:72:ad:95:98:
-+ f6:73:21:41:5e:a0:dd:47:27:a0:d5:9a:d4:41:a8:
-+ 1c:1d:57:20:71:17:8f:f7:28:9e:3e:07:ce:ec:d5:
-+ 0e:42:4f:1e:74:47:8e:47:9d:d2:14:28:27:2c:14:
-+ 10:f5:d1:96:b5:93:74:84:ef:f9:04:de:8d:4a:6f:
-+ df:77:ab:ea:d1:58:d3:44:fe:5a:04:01:ff:06:7a:
-+ 97:f7:fd:e3:57:48:e1:f0:df:40:13:9f:66:23:5a:
-+ e3:55:54:3d:54:39:ee:00:f9:12:f1:d2:df:74:2e:
-+ ba:d7:f0:8d:c6:dd:18:58:1c:93:22:0b:75:fa:a8:
-+ d6:e0:b5:2f:2d:b9:d4:fe:b9:4f:86:e2:75:48:16:
-+ 60:fb:3f:c9:b4:30:42:29:fb:3b:b3:2b:b9:59:81:
-+ 6a:46:f3:45:83:bf:fd:d5:1a:ff:37:0c:6f:5b:fd:
-+ 61:f1
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints:
- CA:FALSE
-- Netscape Comment:
-- OpenSSL Generated Certificate
- X509v3 Subject Key Identifier:
-- 17:B7:3F:C7:62:A0:A9:FD:A4:31:0E:58:D7:D9:94:7B:4B:3F:CB:56
-+ D2:B4:36:0F:B1:FC:DD:A5:EA:2A:F7:C7:23:89:FA:E3:FA:7A:44:1D
- X509v3 Authority Key Identifier:
-- keyid:89:A6:60:E3:BA:EA:3E:AF:FC:64:7F:4C:BD:8C:D2:48:8D:E0:CC:46
-+ keyid:2B:40:E5:C9:7D:F5:F4:96:38:E9:2F:E3:2F:D9:40:64:C9:8E:05:9B
- DirName:/C=KG/ST=NA/L=BISHKEK/O=OpenVPN-TEST/emailAddress=me@myhost.mydomain
-- serial:00
-+ serial:A1:4E:DE:FA:90:F2:AE:81
-
-- Signature Algorithm: md5WithRSAEncryption
-- 61:c6:d1:fa:24:0f:c7:be:09:3b:d8:04:17:63:31:17:07:f9:
-- 56:99:af:4c:67:fa:db:cb:94:cf:55:a5:7b:16:20:8b:42:64:
-- 13:23:62:45:28:93:5e:36:f7:db:02:95:a1:e9:fd:e3:0f:8d:
-- 73:a1:7b:0e:55:78:4d:a5:c4:b7:22:12:a0:ee:55:e0:b8:0e:
-- c9:9b:12:e3:b0:ef:9b:68:93:57:6e:6c:ad:16:68:8e:8d:30:
-- 33:fe:2a:1b:c3:03:8f:b6:0a:2d:0c:b1:3c:bb:f9:58:3f:8c:
-- 81:59:6b:14:dd:62:b5:c2:93:ed:5d:c6:19:0f:9b:4b:52:b3:
-- 7c:78
-+ Signature Algorithm: sha256WithRSAEncryption
-+ 7f:e0:fe:84:a7:ec:df:62:a5:cd:3c:c1:e6:42:b1:31:12:f0:
-+ b9:da:a7:9e:3f:bd:96:52:b6:fc:55:74:64:3e:e4:ff:7e:aa:
-+ f7:3e:06:18:5f:73:85:f8:c8:e0:67:1b:4d:97:ca:05:d0:37:
-+ 07:33:64:9b:e6:78:77:14:9a:55:bb:2a:ac:c3:7f:c9:15:08:
-+ 83:5c:c8:c2:61:d3:71:4c:05:0b:2b:cb:a3:87:6d:a0:32:ed:
-+ b0:b3:27:97:4a:55:8d:01:2a:30:56:68:ab:f2:da:5c:10:73:
-+ c9:aa:0a:9c:4b:4c:a0:5b:51:6e:0a:7e:6c:53:80:b0:00:e1:
-+ 1e:9a:4c:0a:37:9e:20:89:bc:c5:e5:79:58:b7:45:ff:d3:c4:
-+ a1:fd:d9:78:3d:45:16:74:df:82:44:1d:1d:81:50:5a:b9:32:
-+ 4c:e2:4f:3f:0e:3a:65:5a:64:83:3b:29:31:c4:99:88:bc:c5:
-+ 84:39:f2:19:12:e1:66:d0:ea:fb:75:b1:d2:27:be:91:59:a3:
-+ 2b:09:d5:5c:bf:46:8e:d6:67:d6:0b:ec:da:ab:f0:80:19:87:
-+ 64:07:a9:77:b1:5e:0c:e2:c5:1d:6a:ac:5d:23:f3:30:75:36:
-+ 4e:ca:c3:4e:b0:4d:8c:2c:ce:52:61:63:de:d5:f5:ef:ef:0a:
-+ 6b:23:25:26:3c:3a:f2:c3:c2:16:19:3f:a9:32:ba:68:f9:c9:
-+ 12:3c:3e:c6:1f:ff:9b:4e:f4:90:b0:63:f5:d1:33:00:30:5a:
-+ e8:24:fa:35:44:9b:6a:80:f3:a6:cc:7b:3c:73:5f:50:c4:30:
-+ 71:d8:74:90:27:0a:01:4e:a5:5e:b1:f8:da:c2:61:81:11:ae:
-+ 29:a3:8f:fa:7e:4c:4e:62:b1:00:de:92:e3:8f:6a:2e:da:d9:
-+ 38:5d:6b:7c:0d:e4:01:aa:c8:c6:6d:8b:cd:c0:c8:6e:e4:57:
-+ 21:8a:f6:46:30:d9:ad:51:a1:87:96:a6:53:c9:1e:c6:bb:c3:
-+ eb:55:fe:8c:d6:5c:d5:c6:f3:ca:b0:60:d2:d4:2a:1f:88:94:
-+ d3:4c:1a:da:0c:94:fe:c1:5d:0d:2a:db:99:29:5d:f6:dd:16:
-+ c4:c8:4d:74:9e:80:d9:d0:aa:ed:7b:e3:30:e4:47:d8:f5:15:
-+ c1:71:b8:c6:fd:ee:fc:9e:b2:5f:b5:b7:92:ed:ff:ca:37:f6:
-+ c7:82:b4:54:13:9b:83:cd:87:8b:7e:64:f6:2e:54:3a:22:b1:
-+ c5:c1:f4:a5:25:53:9a:4d:a8:0f:e7:35:4b:89:df:19:83:66:
-+ 64:d9:db:d1:61:2b:24:1b:1d:44:44:fb:49:30:87:b7:49:23:
-+ 08:02:8a:e0:25:f3:f4:43
- -----BEGIN CERTIFICATE-----
--MIIDNTCCAp6gAwIBAgIBAjANBgkqhkiG9w0BAQQFADBmMQswCQYDVQQGEwJLRzEL
-+MIIFFDCCAvygAwIBAgIBAjANBgkqhkiG9w0BAQsFADBmMQswCQYDVQQGEwJLRzEL
- MAkGA1UECBMCTkExEDAOBgNVBAcTB0JJU0hLRUsxFTATBgNVBAoTDE9wZW5WUE4t
--VEVTVDEhMB8GCSqGSIb3DQEJARYSbWVAbXlob3N0Lm15ZG9tYWluMB4XDTA0MTEy
--NTE0NDY0OVoXDTE0MTEyMzE0NDY0OVowajELMAkGA1UEBhMCS0cxCzAJBgNVBAgT
-+VEVTVDEhMB8GCSqGSIb3DQEJARYSbWVAbXlob3N0Lm15ZG9tYWluMB4XDTE0MTAy
-+MjIxNTk1M1oXDTI0MTAxOTIxNTk1M1owajELMAkGA1UEBhMCS0cxCzAJBgNVBAgT
- Ak5BMRUwEwYDVQQKEwxPcGVuVlBOLVRFU1QxFDASBgNVBAMTC1Rlc3QtQ2xpZW50
--MSEwHwYJKoZIhvcNAQkBFhJtZUBteWhvc3QubXlkb21haW4wgZ8wDQYJKoZIhvcN
--AQEBBQADgY0AMIGJAoGBANISXMZNEzSuz/qr/svejPFLSpUoYIeCLLjB5Y7GXRFY
--YaSl8ULXhnRsnZx68DpcKeZTO15t2PBFBiwj7gm8Ao8OuNUzH8NKEQJIC8xLrW50
--4KJTsdbMibnib9sVsxkeVwR5SDradjH8v9M0Iecy2J4GTr7z43mwVP3RQjKqPnrB
--AgMBAAGjge4wgeswCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBH
--ZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFBe3P8dioKn9pDEOWNfZlHtL
--P8tWMIGQBgNVHSMEgYgwgYWAFImmYOO66j6v/GR/TL2M0kiN4MxGoWqkaDBmMQsw
--CQYDVQQGEwJLRzELMAkGA1UECBMCTkExEDAOBgNVBAcTB0JJU0hLRUsxFTATBgNV
--BAoTDE9wZW5WUE4tVEVTVDEhMB8GCSqGSIb3DQEJARYSbWVAbXlob3N0Lm15ZG9t
--YWluggEAMA0GCSqGSIb3DQEBBAUAA4GBAGHG0fokD8e+CTvYBBdjMRcH+VaZr0xn
--+tvLlM9VpXsWIItCZBMjYkUok14299sClaHp/eMPjXOhew5VeE2lxLciEqDuVeC4
--DsmbEuOw75tok1dubK0WaI6NMDP+KhvDA4+2Ci0MsTy7+Vg/jIFZaxTdYrXCk+1d
--xhkPm0tSs3x4
-+MSEwHwYJKoZIhvcNAQkBFhJtZUBteWhvc3QubXlkb21haW4wggEiMA0GCSqGSIb3
-+DQEBAQUAA4IBDwAwggEKAoIBAQDsZY/pEsIaW+ZWKgipgjotRHijADuwn+cnEECT
-+7/HMPqCqBKKAGxOp5v6B1nCQqNjU3jDYNQDSvmLwSNr8FY3Exm0LmfErgwAK0yoj
-+C+XN+TXfQ2EVcq2VmPZzIUFeoN1HJ6DVmtRBqBwdVyBxF4/3KJ4+B87s1Q5CTx50
-+R45HndIUKCcsFBD10Za1k3SE7/kE3o1Kb993q+rRWNNE/loEAf8Gepf3/eNXSOHw
-+30ATn2YjWuNVVD1UOe4A+RLx0t90LrrX8I3G3RhYHJMiC3X6qNbgtS8tudT+uU+G
-+4nVIFmD7P8m0MEIp+zuzK7lZgWpG80WDv/3VGv83DG9b/WHxAgMBAAGjgcgwgcUw
-+CQYDVR0TBAIwADAdBgNVHQ4EFgQU0rQ2D7H83aXqKvfHI4n64/p6RB0wgZgGA1Ud
-+IwSBkDCBjYAUK0DlyX319JY46S/jL9lAZMmOBZuhaqRoMGYxCzAJBgNVBAYTAktH
-+MQswCQYDVQQIEwJOQTEQMA4GA1UEBxMHQklTSEtFSzEVMBMGA1UEChMMT3BlblZQ
-+Ti1URVNUMSEwHwYJKoZIhvcNAQkBFhJtZUBteWhvc3QubXlkb21haW6CCQChTt76
-+kPKugTANBgkqhkiG9w0BAQsFAAOCAgEAf+D+hKfs32KlzTzB5kKxMRLwudqnnj+9
-+llK2/FV0ZD7k/36q9z4GGF9zhfjI4GcbTZfKBdA3BzNkm+Z4dxSaVbsqrMN/yRUI
-+g1zIwmHTcUwFCyvLo4dtoDLtsLMnl0pVjQEqMFZoq/LaXBBzyaoKnEtMoFtRbgp+
-+bFOAsADhHppMCjeeIIm8xeV5WLdF/9PEof3ZeD1FFnTfgkQdHYFQWrkyTOJPPw46
-+ZVpkgzspMcSZiLzFhDnyGRLhZtDq+3Wx0ie+kVmjKwnVXL9GjtZn1gvs2qvwgBmH
-+ZAepd7FeDOLFHWqsXSPzMHU2TsrDTrBNjCzOUmFj3tX17+8KayMlJjw68sPCFhk/
-+qTK6aPnJEjw+xh//m070kLBj9dEzADBa6CT6NUSbaoDzpsx7PHNfUMQwcdh0kCcK
-+AU6lXrH42sJhgRGuKaOP+n5MTmKxAN6S449qLtrZOF1rfA3kAarIxm2LzcDIbuRX
-+IYr2RjDZrVGhh5amU8kexrvD61X+jNZc1cbzyrBg0tQqH4iU00wa2gyU/sFdDSrb
-+mSld9t0WxMhNdJ6A2dCq7XvjMORH2PUVwXG4xv3u/J6yX7W3ku3/yjf2x4K0VBOb
-+g82Hi35k9i5UOiKxxcH0pSVTmk2oD+c1S4nfGYNmZNnb0WErJBsdRET7STCHt0kj
-+CAKK4CXz9EM=
- -----END CERTIFICATE-----
-Index: openvpn/sample/sample-keys/client.key
-===================================================================
---- openvpn.orig/sample/sample-keys/client.key 2014-12-01 17:35:28.603250441 +0100
-+++ openvpn/sample/sample-keys/client.key 2014-12-01 17:35:28.599250441 +0100
-@@ -1,15 +1,28 @@
-------BEGIN RSA PRIVATE KEY-----
--MIICXAIBAAKBgQDSElzGTRM0rs/6q/7L3ozxS0qVKGCHgiy4weWOxl0RWGGkpfFC
--14Z0bJ2cevA6XCnmUztebdjwRQYsI+4JvAKPDrjVMx/DShECSAvMS61udOCiU7HW
--zIm54m/bFbMZHlcEeUg62nYx/L/TNCHnMtieBk6+8+N5sFT90UIyqj56wQIDAQAB
--AoGBAK8RoIGekCfym99DYYfTg9A/t/tQeAnWYaDj7oSrKbqf1lgZ91OGPEZgkoVr
--KzLnxf9uU+bhUs8CJx+4HdO8/L9rAJA+oD9QNuMp0elN4AKuEGE1Eq3a0e3cmgPI
--+VIoXM6WVAGgK9I03Zu/UerYQ/DdXWGOIsKhFe8qyQoG9pKxAkEA9ld6O9MHQt3d
--JAjJkgCNn4psozxjrfLWy2huXd3H3CRqGMjLITDGzdkVSgXjHokBYroi0+TZTu4M
--ulJSJaWwBQJBANpO2DAexH2zRHw5Z6QyeEVxz7B3/FzU4GgJx9BH+FSBh+F0G5Ln
--ir5Vst8vZ/LGcgpYjHQLNAvZVgUjiQ4Y6I0CQGvwMJL+CHR4GmmroAblTyjU0n1D
--/Lk/anZ+L73Za7U+D28ErFzCrpmLwRRKOBYtGfpUbOZDpCQ9kj4hy/TLALECQCcL
--9ysUNbzt9Y/qjJkX1d9F7gn4TBEmmkTBixW76bTjvjQbGlt6Qpyso2O8DPGlgPxM
--vkJ7RoHgC7y7kGYPGnkCQBVxSNGIjLx4NQBgN4HD0y4+fars1PTUGnckBcS4npb9
--onLNyerBlWdBwbARyBS7WPIbyyf5VCrn3yIqWxaARO0=
-------END RSA PRIVATE KEY-----
-+-----BEGIN PRIVATE KEY-----
-+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDsZY/pEsIaW+ZW
-+KgipgjotRHijADuwn+cnEECT7/HMPqCqBKKAGxOp5v6B1nCQqNjU3jDYNQDSvmLw
-+SNr8FY3Exm0LmfErgwAK0yojC+XN+TXfQ2EVcq2VmPZzIUFeoN1HJ6DVmtRBqBwd
-+VyBxF4/3KJ4+B87s1Q5CTx50R45HndIUKCcsFBD10Za1k3SE7/kE3o1Kb993q+rR
-+WNNE/loEAf8Gepf3/eNXSOHw30ATn2YjWuNVVD1UOe4A+RLx0t90LrrX8I3G3RhY
-+HJMiC3X6qNbgtS8tudT+uU+G4nVIFmD7P8m0MEIp+zuzK7lZgWpG80WDv/3VGv83
-+DG9b/WHxAgMBAAECggEBAIOdaCpUD02trOh8LqZxowJhBOl7z7/ex0uweMPk67LT
-+i5AdVHwOlzwZJ8oSIknoOBEMRBWcLQEojt1JMuL2/R95emzjIKshHHzqZKNulFvB
-+TIUpdnwChTKtH0mqUkLlPU3Ienty4IpNlpmfUKimfbkWHERdBJBHbtDsTABhdo3X
-+9pCF/yRKqJS2Fy/Mkl3gv1y/NB1OL4Jhl7vQbf+kmgfQN2qdOVe2BOKQ8NlPUDmE
-+/1XNIDaE3s6uvUaoFfwowzsCCwN2/8QrRMMKkjvV+lEVtNmQdYxj5Xj5IwS0vkK0
-+6icsngW87cpZxxc1zsRWcSTloy5ohub4FgKhlolmigECgYEA+cBlxzLvaMzMlBQY
-+kCac9KQMvVL+DIFHlZA5i5L/9pRVp4JJwj3GUoehFJoFhsxnKr8HZyLwBKlCmUVm
-+VxnshRWiAU18emUmeAtSGawlAS3QXhikVZDdd/L20YusLT+DXV81wlKR97/r9+17
-+klQOLkSdPm9wcMDOWMNHX8bUg8kCgYEA8k+hQv6+TR/+Beao2IIctFtw/EauaJiJ
-+wW5ql1cpCLPMAOQUvjs0Km3zqctfBF8mUjdkcyJ4uhL9FZtfywY22EtRIXOJ/8VR
-+we65mVo6RLR8YVM54sihanuFOnlyF9LIBWB+9pUfh1/Y7DSebh7W73uxhAxQhi3Y
-+QwfIQIFd8OkCgYBalH4VXhLYhpaYCiXSej6ot6rrK2N6c5Tb2MAWMA1nh+r84tMP
-+gMoh+pDgYPAqMI4mQbxUmqZEeoLuBe6VHpDav7rPECRaW781AJ4ZM4cEQ3Jz/inz
-+4qOAMn10CF081/Ez9ykPPlU0bsYNWHNd4eB2xWnmUBKOwk7UgJatVPaUiQKBgQCI
-+f18CVGpzG9CHFnaK8FCnMNOm6VIaTcNcGY0mD81nv5Dt943P054BQMsAHTY7SjZW
-+HioRyZtkhonXAB2oSqnekh7zzxgv4sG5k3ct8evdBCcE1FNJc2eqikZ0uDETRoOy
-+s7cRxNNr+QxDkyikM+80HOPU1PMPgwfOSrX90GJQ8QKBgEBKohGMV/sNa4t14Iau
-+qO8aagoqh/68K9GFXljsl3/iCSa964HIEREtW09Qz1w3dotEgp2w8bsDa+OwWrLy
-+0SY7T5jRViM3cDWRlUBLrGGiL0FiwsfqiRiji60y19erJgrgyGVIb1kIgIBRkgFM
-+2MMweASzTmZcri4PA/5C0HYb
-+-----END PRIVATE KEY-----
-Index: openvpn/sample/sample-keys/server.crt
-===================================================================
---- openvpn.orig/sample/sample-keys/server.crt 2014-12-01 17:35:28.603250441 +0100
-+++ openvpn/sample/sample-keys/server.crt 2014-12-01 17:35:28.599250441 +0100
-@@ -2,25 +2,34 @@
- Data:
- Version: 3 (0x2)
- Serial Number: 1 (0x1)
-- Signature Algorithm: md5WithRSAEncryption
-+ Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=KG, ST=NA, L=BISHKEK, O=OpenVPN-TEST/emailAddress=me@myhost.mydomain
- Validity
-- Not Before: Nov 25 14:42:22 2004 GMT
-- Not After : Nov 23 14:42:22 2014 GMT
-+ Not Before: Oct 22 21:59:52 2014 GMT
-+ Not After : Oct 19 21:59:52 2024 GMT
- Subject: C=KG, ST=NA, O=OpenVPN-TEST, CN=Test-Server/emailAddress=me@myhost.mydomain
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
-- RSA Public Key: (1024 bit)
-- Modulus (1024 bit):
-- 00:cb:4e:ac:f9:83:57:f6:69:d2:32:29:b4:bc:ad:
-- e6:f7:26:21:89:33:30:43:40:a3:35:d9:de:26:01:
-- d6:b4:f0:bc:0a:19:55:99:3b:f1:4c:91:60:b6:fd:
-- 74:34:8d:5a:c7:62:ec:ce:f2:d6:02:ce:57:32:f4:
-- 35:8c:71:a0:6d:65:2a:e7:80:ae:29:59:cf:36:73:
-- f8:7c:4a:73:90:fc:30:28:d5:46:7d:35:a4:4e:c9:
-- 9f:90:7b:e2:09:21:36:c5:a8:ec:85:82:9a:32:b4:
-- 91:3b:c1:d6:4f:9f:d1:f8:6f:68:f4:1d:d2:06:91:
-- 32:cc:9a:48:fd:cd:98:7f:2f
-+ Public-Key: (2048 bit)
-+ Modulus:
-+ 00:a5:b8:a2:ee:ce:b1:a6:0f:6a:b2:9f:d3:22:17:
-+ 79:de:09:98:71:78:fa:a7:ce:36:51:54:57:c7:31:
-+ 99:56:d1:8a:d6:c5:fd:52:e6:88:0e:7b:f9:ea:27:
-+ 7a:bf:3f:14:ec:aa:d2:ff:8b:56:58:ac:ca:51:77:
-+ c5:3c:b6:e4:83:6f:22:06:2d:5b:eb:e7:59:d4:ab:
-+ 42:c8:d5:a9:87:73:b3:73:36:51:2f:a5:d0:90:a2:
-+ 87:64:54:6c:12:d3:b8:76:47:69:af:ae:8f:00:b3:
-+ 70:b9:e7:67:3f:8c:6a:3d:79:5f:81:27:a3:0e:aa:
-+ a7:3d:81:48:10:b1:18:6c:38:2e:8f:7a:7b:c5:3d:
-+ 21:c8:f9:a0:7f:17:2b:88:4f:ba:f2:ec:6d:24:8e:
-+ 6c:f1:0a:5c:d9:5b:b1:b0:fc:49:cb:4a:d2:58:c6:
-+ 2a:25:b0:97:84:c3:9e:ff:34:8c:10:46:7f:0f:fb:
-+ 3c:59:7a:a6:29:0c:ae:8e:50:3a:f2:53:84:40:2d:
-+ d5:91:7b:0a:37:8e:82:77:ce:66:2f:34:77:5c:a5:
-+ 45:3b:00:19:a7:07:d1:92:e6:66:b9:3b:4e:e9:63:
-+ fc:33:98:1a:ae:7b:08:7d:0a:df:7a:ba:aa:59:6d:
-+ 86:82:0a:64:2b:da:59:a7:4c:4e:ef:3d:bd:04:a2:
-+ 4b:31
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints:
-@@ -30,38 +39,75 @@
- Netscape Comment:
- OpenSSL Generated Server Certificate
- X509v3 Subject Key Identifier:
-- 69:11:FE:E7:9F:89:7B:71:34:69:C0:DC:82:F8:D0:5D:4D:FB:78:DF
-+ B3:9D:81:E6:16:92:64:C4:86:87:F5:29:10:1B:5E:2F:74:F7:ED:B1
- X509v3 Authority Key Identifier:
-- keyid:89:A6:60:E3:BA:EA:3E:AF:FC:64:7F:4C:BD:8C:D2:48:8D:E0:CC:46
-+ keyid:2B:40:E5:C9:7D:F5:F4:96:38:E9:2F:E3:2F:D9:40:64:C9:8E:05:9B
- DirName:/C=KG/ST=NA/L=BISHKEK/O=OpenVPN-TEST/emailAddress=me@myhost.mydomain
-- serial:00
-+ serial:A1:4E:DE:FA:90:F2:AE:81
-
-- Signature Algorithm: md5WithRSAEncryption
-- 35:5c:75:da:57:ef:b5:79:f2:a2:db:36:e4:75:e8:c7:bc:73:
-- 26:cf:30:36:4b:2e:51:46:37:60:2f:4e:2b:f6:71:a2:23:db:
-- 8e:d8:5c:d5:af:2e:22:28:dd:30:a8:89:66:3a:cc:5b:3c:0f:
-- 96:12:20:de:5e:41:52:74:35:ed:4c:26:40:19:ca:73:df:54:
-- b1:30:96:9c:a5:14:d0:38:28:3f:ab:30:07:d7:de:98:d2:7f:
-- 7f:90:b2:52:1d:e5:95:88:ed:ba:8a:6a:14:85:66:76:ec:75:
-- 30:e8:ae:94:f4:e1:76:fa:4b:0e:f1:53:d7:95:be:fb:69:fa:
-- 3d:32
-+ X509v3 Extended Key Usage:
-+ TLS Web Server Authentication
-+ X509v3 Key Usage:
-+ Digital Signature, Key Encipherment
-+ Signature Algorithm: sha256WithRSAEncryption
-+ 4e:25:80:1b:cb:b0:42:ff:bb:3f:e8:0d:58:c1:80:db:cf:d0:
-+ 90:df:ca:c1:e6:41:e1:48:7f:a7:1e:c7:35:9f:9c:6d:7c:3e:
-+ 82:e8:de:7e:ae:82:16:00:33:0f:02:23:f1:9d:fe:2b:06:16:
-+ 05:55:16:89:dc:63:ac:5f:1a:31:13:79:21:a3:6e:60:28:e8:
-+ e7:6b:54:00:22:a1:b7:69:5a:17:31:ce:0f:c2:a6:dd:a3:6f:
-+ de:ea:19:6c:d2:d2:cb:35:9d:dd:87:51:33:68:cd:c3:9b:90:
-+ 55:f1:80:3d:5c:b8:09:b6:e1:3c:13:a4:5d:4a:ce:a5:11:9e:
-+ f9:08:ee:be:e3:54:1d:06:4c:bb:1b:72:13:ee:7d:a0:45:cc:
-+ fe:d1:3b:02:03:c1:d4:ea:45:2d:a8:c9:97:e7:f3:8a:7a:a0:
-+ 2f:dd:48:3a:75:c9:42:28:94:fc:af:44:52:16:68:98:d6:ad:
-+ a8:65:b1:cd:ac:60:41:70:e5:44:e8:5a:f2:e7:fc:3b:fe:45:
-+ 89:17:1d:6d:85:c6:f0:fc:69:87:d1:1d:07:f3:cb:7b:54:8d:
-+ aa:a3:cc:e3:c6:fc:d6:05:76:35:d0:26:63:8e:d1:a8:b7:ff:
-+ 61:42:8a:2c:63:1f:d4:ec:14:47:6b:1e:e3:81:61:12:3b:8c:
-+ 16:b5:cf:87:6a:2d:42:21:83:9c:0e:3a:90:3a:1e:c1:36:61:
-+ 41:f9:fb:4e:5d:ea:f4:df:23:92:33:2b:9b:14:9f:a0:f5:d3:
-+ c4:f8:1f:2f:9c:11:36:af:2a:22:61:95:32:0b:c4:1c:2d:b1:
-+ c1:0a:2a:97:c0:43:4a:6c:3e:db:00:cd:29:15:9e:7e:41:75:
-+ 36:a8:56:86:8c:82:9e:46:20:e5:06:1e:60:d2:03:5f:9f:9e:
-+ 69:bb:bf:c2:b4:43:e2:7d:85:17:83:18:41:b0:cb:a9:04:1b:
-+ 18:52:9f:89:8b:76:9f:94:59:81:4f:60:5b:33:18:fc:c7:52:
-+ d0:d2:69:fc:0b:a2:63:32:75:43:99:e9:d7:f8:6d:c7:55:31:
-+ 0c:f3:ef:1a:71:e1:0a:57:e1:9d:13:b2:1e:fe:1d:ef:e4:f1:
-+ 51:d9:95:b3:fd:28:28:93:91:4a:29:c5:37:0e:ab:d8:85:6a:
-+ fe:a8:83:1f:7b:80:5d:1f:04:79:b7:a9:08:6e:0d:d6:2e:aa:
-+ 7c:f6:63:7d:41:de:70:13:32:ce:dd:58:cc:a6:73:d4:72:7e:
-+ d7:ac:74:a8:35:ba:c3:1b:2a:64:d7:5a:37:97:56:94:34:2b:
-+ 2a:71:60:bc:69:ab:00:85:b9:4f:67:32:17:51:c3:da:57:3a:
-+ 37:89:66:c4:7a:51:da:5f
- -----BEGIN CERTIFICATE-----
--MIIDUTCCArqgAwIBAgIBATANBgkqhkiG9w0BAQQFADBmMQswCQYDVQQGEwJLRzEL
-+MIIFgDCCA2igAwIBAgIBATANBgkqhkiG9w0BAQsFADBmMQswCQYDVQQGEwJLRzEL
- MAkGA1UECBMCTkExEDAOBgNVBAcTB0JJU0hLRUsxFTATBgNVBAoTDE9wZW5WUE4t
--VEVTVDEhMB8GCSqGSIb3DQEJARYSbWVAbXlob3N0Lm15ZG9tYWluMB4XDTA0MTEy
--NTE0NDIyMloXDTE0MTEyMzE0NDIyMlowajELMAkGA1UEBhMCS0cxCzAJBgNVBAgT
-+VEVTVDEhMB8GCSqGSIb3DQEJARYSbWVAbXlob3N0Lm15ZG9tYWluMB4XDTE0MTAy
-+MjIxNTk1MloXDTI0MTAxOTIxNTk1MlowajELMAkGA1UEBhMCS0cxCzAJBgNVBAgT
- Ak5BMRUwEwYDVQQKEwxPcGVuVlBOLVRFU1QxFDASBgNVBAMTC1Rlc3QtU2VydmVy
--MSEwHwYJKoZIhvcNAQkBFhJtZUBteWhvc3QubXlkb21haW4wgZ8wDQYJKoZIhvcN
--AQEBBQADgY0AMIGJAoGBAMtOrPmDV/Zp0jIptLyt5vcmIYkzMENAozXZ3iYB1rTw
--vAoZVZk78UyRYLb9dDSNWsdi7M7y1gLOVzL0NYxxoG1lKueArilZzzZz+HxKc5D8
--MCjVRn01pE7Jn5B74gkhNsWo7IWCmjK0kTvB1k+f0fhvaPQd0gaRMsyaSP3NmH8v
--AgMBAAGjggEJMIIBBTAJBgNVHRMEAjAAMBEGCWCGSAGG+EIBAQQEAwIGQDAzBglg
--hkgBhvhCAQ0EJhYkT3BlblNTTCBHZW5lcmF0ZWQgU2VydmVyIENlcnRpZmljYXRl
--MB0GA1UdDgQWBBRpEf7nn4l7cTRpwNyC+NBdTft43zCBkAYDVR0jBIGIMIGFgBSJ
--pmDjuuo+r/xkf0y9jNJIjeDMRqFqpGgwZjELMAkGA1UEBhMCS0cxCzAJBgNVBAgT
--Ak5BMRAwDgYDVQQHEwdCSVNIS0VLMRUwEwYDVQQKEwxPcGVuVlBOLVRFU1QxITAf
--BgkqhkiG9w0BCQEWEm1lQG15aG9zdC5teWRvbWFpboIBADANBgkqhkiG9w0BAQQF
--AAOBgQA1XHXaV++1efKi2zbkdejHvHMmzzA2Sy5RRjdgL04r9nGiI9uO2FzVry4i
--KN0wqIlmOsxbPA+WEiDeXkFSdDXtTCZAGcpz31SxMJacpRTQOCg/qzAH196Y0n9/
--kLJSHeWViO26imoUhWZ27HUw6K6U9OF2+ksO8VPXlb77afo9Mg==
-+MSEwHwYJKoZIhvcNAQkBFhJtZUBteWhvc3QubXlkb21haW4wggEiMA0GCSqGSIb3
-+DQEBAQUAA4IBDwAwggEKAoIBAQCluKLuzrGmD2qyn9MiF3neCZhxePqnzjZRVFfH
-+MZlW0YrWxf1S5ogOe/nqJ3q/PxTsqtL/i1ZYrMpRd8U8tuSDbyIGLVvr51nUq0LI
-+1amHc7NzNlEvpdCQoodkVGwS07h2R2mvro8As3C552c/jGo9eV+BJ6MOqqc9gUgQ
-+sRhsOC6PenvFPSHI+aB/FyuIT7ry7G0kjmzxClzZW7Gw/EnLStJYxiolsJeEw57/
-+NIwQRn8P+zxZeqYpDK6OUDryU4RALdWRewo3joJ3zmYvNHdcpUU7ABmnB9GS5ma5
-+O07pY/wzmBquewh9Ct96uqpZbYaCCmQr2lmnTE7vPb0EoksxAgMBAAGjggEzMIIB
-+LzAJBgNVHRMEAjAAMBEGCWCGSAGG+EIBAQQEAwIGQDAzBglghkgBhvhCAQ0EJhYk
-+T3BlblNTTCBHZW5lcmF0ZWQgU2VydmVyIENlcnRpZmljYXRlMB0GA1UdDgQWBBSz
-+nYHmFpJkxIaH9SkQG14vdPftsTCBmAYDVR0jBIGQMIGNgBQrQOXJffX0ljjpL+Mv
-+2UBkyY4Fm6FqpGgwZjELMAkGA1UEBhMCS0cxCzAJBgNVBAgTAk5BMRAwDgYDVQQH
-+EwdCSVNIS0VLMRUwEwYDVQQKEwxPcGVuVlBOLVRFU1QxITAfBgkqhkiG9w0BCQEW
-+Em1lQG15aG9zdC5teWRvbWFpboIJAKFO3vqQ8q6BMBMGA1UdJQQMMAoGCCsGAQUF
-+BwMBMAsGA1UdDwQEAwIFoDANBgkqhkiG9w0BAQsFAAOCAgEATiWAG8uwQv+7P+gN
-+WMGA28/QkN/KweZB4Uh/px7HNZ+cbXw+gujefq6CFgAzDwIj8Z3+KwYWBVUWidxj
-+rF8aMRN5IaNuYCjo52tUACKht2laFzHOD8Km3aNv3uoZbNLSyzWd3YdRM2jNw5uQ
-+VfGAPVy4CbbhPBOkXUrOpRGe+QjuvuNUHQZMuxtyE+59oEXM/tE7AgPB1OpFLajJ
-+l+fzinqgL91IOnXJQiiU/K9EUhZomNatqGWxzaxgQXDlROha8uf8O/5FiRcdbYXG
-+8Pxph9EdB/PLe1SNqqPM48b81gV2NdAmY47RqLf/YUKKLGMf1OwUR2se44FhEjuM
-+FrXPh2otQiGDnA46kDoewTZhQfn7Tl3q9N8jkjMrmxSfoPXTxPgfL5wRNq8qImGV
-+MgvEHC2xwQoql8BDSmw+2wDNKRWefkF1NqhWhoyCnkYg5QYeYNIDX5+eabu/wrRD
-+4n2FF4MYQbDLqQQbGFKfiYt2n5RZgU9gWzMY/MdS0NJp/AuiYzJ1Q5np1/htx1Ux
-+DPPvGnHhClfhnROyHv4d7+TxUdmVs/0oKJORSinFNw6r2IVq/qiDH3uAXR8Eebep
-+CG4N1i6qfPZjfUHecBMyzt1YzKZz1HJ+16x0qDW6wxsqZNdaN5dWlDQrKnFgvGmr
-+AIW5T2cyF1HD2lc6N4lmxHpR2l8=
- -----END CERTIFICATE-----
-Index: openvpn/sample/sample-keys/server.key
-===================================================================
---- openvpn.orig/sample/sample-keys/server.key 2014-12-01 17:35:28.603250441 +0100
-+++ openvpn/sample/sample-keys/server.key 2014-12-01 17:35:28.599250441 +0100
-@@ -1,15 +1,28 @@
-------BEGIN RSA PRIVATE KEY-----
--MIICXgIBAAKBgQDLTqz5g1f2adIyKbS8reb3JiGJMzBDQKM12d4mAda08LwKGVWZ
--O/FMkWC2/XQ0jVrHYuzO8tYCzlcy9DWMcaBtZSrngK4pWc82c/h8SnOQ/DAo1UZ9
--NaROyZ+Qe+IJITbFqOyFgpoytJE7wdZPn9H4b2j0HdIGkTLMmkj9zZh/LwIDAQAB
--AoGBAKP1ljA/iY/zNY447kZ/5NWKzd7tBk4mcbl7M9no/7O6tZtbZRoIKoi6cYoC
--C1ZabUyBbkNTud5XdCFmq0zRUjOWvoFMZ9VZfd2kRPvl4TGczBtJAq65b+EYMGui
--q6T9p61xPdtzu0vM+Ecj127pAMk5XcJyxu8XQK7lZWmG5UoJAkEA8CxXNZN+A3qD
--bMBPI3VdwKCNSjNVEQEnygMbNgw7VLdxPpspzZziqJEGdzsM4dsnOBwKxIWFLN2h
--lbGBOquAswJBANi0atGWM8VUxDjvqqHCTS9RUXWgnvYhee4/xraJBQPBSivjC9P0
--vKT7PjBHU6djtKSLKGaHn1vHqmyY7PCMjZUCQQCNVSqExqSzG1dXmdt4PErNXi2G
--6qo2dX2arTVIGu6XLdQgSWLSMm5XT/CEHWW5SyPLKwVTHFeATXQXCPvJML9tAkEA
--k0yXax0g1ZoXwufN4SQUmPw6Va03P/BjU/nP1ZVvbiz9gLVU/d7WN4J7tA9XomkY
--idv5OzAmtxkSE70jGSNAvQJAWhCf9+iHkzOHRyKKOYlh1DHUwDfSEp+hlZYg9H03
--P2sraQzUxgWDY/DIY63KvW78ny863baFz7onz21MYGgJXg==
-------END RSA PRIVATE KEY-----
-+-----BEGIN PRIVATE KEY-----
-+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCluKLuzrGmD2qy
-+n9MiF3neCZhxePqnzjZRVFfHMZlW0YrWxf1S5ogOe/nqJ3q/PxTsqtL/i1ZYrMpR
-+d8U8tuSDbyIGLVvr51nUq0LI1amHc7NzNlEvpdCQoodkVGwS07h2R2mvro8As3C5
-+52c/jGo9eV+BJ6MOqqc9gUgQsRhsOC6PenvFPSHI+aB/FyuIT7ry7G0kjmzxClzZ
-+W7Gw/EnLStJYxiolsJeEw57/NIwQRn8P+zxZeqYpDK6OUDryU4RALdWRewo3joJ3
-+zmYvNHdcpUU7ABmnB9GS5ma5O07pY/wzmBquewh9Ct96uqpZbYaCCmQr2lmnTE7v
-+Pb0EoksxAgMBAAECggEAPMOMin+jR75TYxeTNObiunVOPh0b2zeTVxLT9KfND7ZZ
-+cBK8pg79SEJRCnhbW5BnvbeNEkIm8PC6ZlDCM1bkRwUStq0fDUqQ95esLzOYq5/S
-+5qW98viblszhU/pYfja/Zi8dI1uf96PT63Zbt0NnGQ9N42+DLDeKhtTGdchZqiQA
-+LeSR0bQanY4tUUtCNYvBT8E3pzhoIsUzVwzIK53oovRpcOX3pMXVYZsmNhXdFFRy
-+YkjMXpj7fGyaAJK0QsC+PsgrKuhXDzDttsG2lI/mq9+7RXB3d/pzhmBVWynVH2lw
-+iQ7ONkSz7akDz/4I4WmxJep+FfQJYgK6rnLAlQqauQKBgQDammSAprnvDvNhSEp8
-+W+xt7jQnFqaENbGgP0/D/OZMXc4khgexqlKFmSnBCRDmQ6JvLTWqDXC4+aqAbFQz
-+zAIjiKaT+so8xvFRob+rBMJY5JLYKNa+zUUanfORUNYLFJPvFqnrWGaJ9uufdaM7
-+0a5bu95PN74NXee3DBbpBv8HLwKBgQDCEk+IjNbjMT+Neq0ywUeM5rFrUKi92abe
-+AgsVpjbighRV+6jA2lZFJcize+xYJ9wiOR1/TEI9PZ2OtBkqpwVdvTEHTagRLcvd
-+NfGcptREDnNLoNWA22buQpztiEduutACWQsrd+JQmqbUicUdW4zw86/oCMbYCW3V
-+QmYOLns7nwKBgHHUX20WZE91S4pmqFKlUzHTDdkk1ESX6Qx2q0R01j8BwawHFs6O
-+0DW9EZ7w55nfsh+OPRl1sjK/3ubMgfQO0TZLm+IGf3Sya0qEnVeiPMkpDMX+TgRA
-+wzEe+ou6uho+9uFSvdxMxeglaYA5M2ycvNwLsbEyZ4ZyVYxdgTiKahYFAoGAcIfP
-+iD0qKQiYcj/tB94cz+3AeJqHjbYT1O1YYhBECOkmQ4kuG80+cs/q5W/45lEOiuWV
-+Xgfo7Lu6jVGOujWoneci87oqtvNYH4e09oGh2WiLoBG9Wv9dWtBTUERSLzmxfXsG
-+SAk2uEhEbj8IhfJc8iZLHH9iVUh6YEslBBodqL8CgYEAlAhvcqAvw5SzsfBR5Mcu
-+4Nql6mXEVhHCvS4hdFCGaNF0z9A6eBORKJpdLWnqhpquDQDsghWE+Ga4QKSNFIi1
-+fnAaykmZuY3ToqNOIaVlYM6HpMEz0wHQbTWfDLGcTFcElLZgMAk7VlDyiYVOco+E
-+QX9lXOO1PGpLzXhlDxSe63Y=
-+-----END PRIVATE KEY-----
diff --git a/debian/patches/use-dpkg-buildflags.patch b/debian/patches/use-dpkg-buildflags.patch
deleted file mode 100644
index e1a7e46..0000000
--- a/debian/patches/use-dpkg-buildflags.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-Description: Use build flags from environment for plugins (dpkg-buildflags).
- Necessary for hardening flags.
-Author: Simon Ruderich <simon@ruderich.org>
-Last-Update: 2012-03-16
-
---- openvpn-2.2.1.orig/src/plugins/auth-pam/Makefile
-+++ openvpn-2.2.1/src/plugins/auth-pam/Makefile
-@@ -18,13 +18,13 @@ INCLUDE=-I../..
- CC_FLAGS=-O2 -Wall -DDLOPEN_PAM=$(DLOPEN_PAM)
-
- openvpn-auth-pam.so : auth-pam.o pamdl.o
-- gcc ${CC_FLAGS} -fPIC -shared -Wl,-soname,openvpn-auth-pam.so -o openvpn-auth-pam.so auth-pam.o pamdl.o -lc $(LIBPAM)
-+ gcc ${CFLAGS} ${CC_FLAGS} ${LDFLAGS} -fPIC -shared -Wl,-soname,openvpn-auth-pam.so -o openvpn-auth-pam.so auth-pam.o pamdl.o -lc $(LIBPAM)
-
- auth-pam.o : auth-pam.c pamdl.h
-- gcc ${CC_FLAGS} -fPIC -c ${INCLUDE} auth-pam.c
-+ gcc ${CFLAGS} ${CC_FLAGS} ${CPPFLAGS} -fPIC -c ${INCLUDE} auth-pam.c
-
- pamdl.o : pamdl.c pamdl.h
-- gcc ${CC_FLAGS} -fPIC -c ${INCLUDE} pamdl.c
-+ gcc ${CFLAGS} ${CC_FLAGS} ${CPPFLAGS} -fPIC -c ${INCLUDE} pamdl.c
-
- clean :
- rm -f *.o *.so
---- openvpn-2.2.1.orig/src/plugins/down-root/Makefile
-+++ openvpn-2.2.1/src/plugins/down-root/Makefile
-@@ -8,10 +8,10 @@ INCLUDE=-I../..
- CC_FLAGS=-O2 -Wall
-
- down-root.so : down-root.o
-- gcc ${CC_FLAGS} -fPIC -shared -Wl,-soname,openvpn-down-root.so -o openvpn-down-root.so down-root.o -lc
-+ gcc ${CFLAGS} ${CC_FLAGS} ${LDFLAGS} -fPIC -shared -Wl,-soname,openvpn-down-root.so -o openvpn-down-root.so down-root.o -lc
-
- down-root.o : down-root.c
-- gcc ${CC_FLAGS} -fPIC -c ${INCLUDE} down-root.c
-+ gcc ${CFLAGS} ${CC_FLAGS} ${CPPFLAGS} -fPIC -c ${INCLUDE} down-root.c
-
- clean :
- rm -f *.o *.so