diff options
Diffstat (limited to 'debian')
-rw-r--r-- | debian/patches/0001-Drop-too-short-control-channel-packets-instead-of-as.patch | 42 | ||||
-rw-r--r-- | debian/patches/attemping_typo | 13 | ||||
-rw-r--r-- | debian/patches/client_hang_when_server_dont_push.patch | 53 | ||||
-rw-r--r-- | debian/patches/counter_type_for_bytes.patch | 15 | ||||
-rw-r--r-- | debian/patches/debian_openssl_vulnkeys.patch | 102 | ||||
-rw-r--r-- | debian/patches/eurephia.patch | 81 | ||||
-rw-r--r-- | debian/patches/ipv6-payload.patch | 4049 | ||||
-rw-r--r-- | debian/patches/jjo-ipv6-support.patch | 4011 | ||||
-rw-r--r-- | debian/patches/manpage_dash_escaping.patch | 20 | ||||
-rw-r--r-- | debian/patches/remote_env.patch | 15 | ||||
-rw-r--r-- | debian/patches/update_sample_certs.patch | 532 | ||||
-rw-r--r-- | debian/patches/use-dpkg-buildflags.patch | 39 |
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 |