0
0
mirror of https://github.com/OpenVPN/openvpn3.git synced 2024-09-20 04:02:15 +02:00

Added IPv6 setting to ovpn3 client API via

ClientAPI::Config::ipv6 string:

  IPv6 preference
    no      -- disable IPv6, so tunnel will be IPv4-only
    yes     -- request combined IPv4/IPv6 tunnel
    default (or empty string) -- leave decision to server
This commit is contained in:
James Yonan 2016-02-05 12:16:20 -07:00
parent afc1a40d00
commit 2b42b96312
5 changed files with 134 additions and 3 deletions

View File

@ -314,6 +314,7 @@ namespace openvpn {
// extra settings submitted by API client
std::string server_override;
Protocol proto_override;
IPv6Setting ipv6;
int conn_timeout = 0;
bool tun_persist = false;
bool google_dns_fallback = false;
@ -396,6 +397,10 @@ namespace openvpn {
if (!config.protoOverride.empty())
Protocol::parse(config.protoOverride, false);
// validate IPv6 setting
if (!config.ipv6.empty())
IPv6Setting::parse(config.ipv6);
// parse config
OptionList::KeyValueList kvl;
kvl.reserve(config.contentList.size());
@ -448,6 +453,8 @@ namespace openvpn {
state->private_key_password = config.privateKeyPassword;
if (!config.protoOverride.empty())
state->proto_override = Protocol::parse(config.protoOverride, false);
if (!config.ipv6.empty())
state->ipv6 = IPv6Setting::parse(config.ipv6);
if (!config.compressionMode.empty())
state->proto_context_options->parse_compression_mode(config.compressionMode);
if (eval.externalPki)
@ -641,6 +648,7 @@ namespace openvpn {
cc.cli_events = state->events;
cc.server_override = state->server_override;
cc.proto_override = state->proto_override;
cc.ipv6 = state->ipv6;
cc.conn_timeout = state->conn_timeout;
cc.tun_persist = state->tun_persist;
cc.google_dns_fallback = state->google_dns_fallback;

View File

@ -168,6 +168,12 @@ namespace openvpn {
// Should be tcp, udp, or adaptive.
std::string protoOverride;
// IPv6 preference
// no -- disable IPv6, so tunnel will be IPv4-only
// yes -- request combined IPv4/IPv6 tunnel
// default (or empty string) -- leave decision to server
std::string ipv6;
// Connection timeout in seconds, or 0 to retry indefinitely
int connTimeout = 0;

View File

@ -41,6 +41,7 @@
#include <openvpn/crypto/cryptodcsel.hpp>
#include <openvpn/ssl/mssparms.hpp>
#include <openvpn/tun/tunmtu.hpp>
#include <openvpn/tun/ipv6_setting.hpp>
#include <openvpn/transport/socket_protect.hpp>
#include <openvpn/transport/reconnect_notify.hpp>
@ -114,6 +115,7 @@ namespace openvpn {
std::string gui_version;
std::string server_override;
Protocol proto_override;
IPv6Setting ipv6;
int conn_timeout = 0;
SessionStats::Ptr cli_stats;
ClientEvent::Queue::Ptr cli_events;
@ -229,7 +231,7 @@ namespace openvpn {
cp->set_xmit_creds(!autologin || pcc.hasEmbeddedPassword() || config.autologin_sessions);
cp->gui_version = config.gui_version;
cp->force_aes_cbc_ciphersuites = config.force_aes_cbc_ciphersuites; // also used to disable proto V2
cp->extra_peer_info = config.extra_peer_info;
cp->extra_peer_info = build_peer_info(config);
cp->frame = frame;
cp->now = &now_;
cp->rng = rng;
@ -453,7 +455,13 @@ namespace openvpn {
// base options where only a single instance of each option makes sense
push_base->singleton.extend(opt, "redirect-dns");
push_base->singleton.extend(opt, "inactive");
push_base->singleton.extend(opt, "block-ipv6");
// IPv6
{
const unsigned int n = push_base->singleton.extend(opt, "block-ipv6");
if (!n && config.ipv6() == IPv6Setting::NO)
push_base->singleton.emplace_back("block-ipv6");
}
}
// show unused options
@ -461,6 +469,19 @@ namespace openvpn {
OPENVPN_LOG("UNUSED OPTIONS" << std::endl << opt.render(Option::RENDER_TRUNC_64|Option::RENDER_NUMBER|Option::RENDER_BRACKET|Option::RENDER_UNUSED));
}
static PeerInfo::Set::Ptr build_peer_info(const Config& config)
{
PeerInfo::Set::Ptr pi = config.extra_peer_info->copy();
// IPv6
if (config.ipv6() == IPv6Setting::NO)
pi->emplace_back("IV_IPv6", "0");
else if (config.ipv6() == IPv6Setting::YES)
pi->emplace_back("IV_IPv6", "1");
return pi;
}
void next()
{
bool omit_next = false;

View File

@ -0,0 +1,89 @@
// OpenVPN -- An application to securely tunnel IP networks
// over a single port, with support for SSL/TLS-based
// session authentication and key exchange,
// packet encryption, packet authentication, and
// packet compression.
//
// Copyright (C) 2012-2015 OpenVPN Technologies, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License Version 3
// as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program in the COPYING file.
// If not, see <http://www.gnu.org/licenses/>.
#ifndef OPENVPN_TUN_IPv6_SETTING_H
#define OPENVPN_TUN_IPv6_SETTING_H
#include <openvpn/common/exception.hpp>
namespace openvpn {
class IPv6Setting
{
public:
enum Type {
NO,
YES,
DEFAULT,
};
IPv6Setting()
{
}
explicit IPv6Setting(const Type t)
: type_(t)
{
}
Type operator()() const { return type_; }
std::string to_string() const
{
switch (type_)
{
case NO:
return "no";
case YES:
return "yes";
case DEFAULT:
default:
return "default";
}
}
static IPv6Setting parse(const std::string& str)
{
if (str == "no")
return IPv6Setting(NO);
else if (str == "yes")
return IPv6Setting(YES);
else if (str == "default")
return IPv6Setting(DEFAULT);
else
throw Exception("IPv6Setting: unrecognized setting");
}
bool operator==(const IPv6Setting& other) const
{
return type_ == other.type_;
}
bool operator!=(const IPv6Setting& other) const
{
return type_ != other.type_;
}
private:
Type type_ = DEFAULT;
};
}
#endif

View File

@ -241,6 +241,7 @@ int openvpn_client(int argc, char *argv[], const std::string* profile_content)
{ "response", required_argument, nullptr, 'r' },
{ "dc", required_argument, nullptr, 'D' },
{ "proto", required_argument, nullptr, 'P' },
{ "ipv6", required_argument, nullptr, '6' },
{ "server", required_argument, nullptr, 's' },
{ "timeout", required_argument, nullptr, 't' },
{ "compress", required_argument, nullptr, 'c' },
@ -283,6 +284,7 @@ int openvpn_client(int argc, char *argv[], const std::string* profile_content)
std::string response;
std::string dynamicChallengeCookie;
std::string proto;
std::string ipv6;
std::string server;
int timeout = 0;
std::string compress;
@ -311,7 +313,7 @@ int openvpn_client(int argc, char *argv[], const std::string* profile_content)
int ch;
optind = 1;
while ((ch = getopt_long(argc, argv, "BAdeTCxfgjmvau:p:r:D:P:s:t:c:z:M:h:q:U:W:I:G:k:", longopts, nullptr)) != -1)
while ((ch = getopt_long(argc, argv, "BAdeTCxfgjmvau:p:r:D:P:6:s:t:c:z:M:h:q:U:W:I:G:k:", longopts, nullptr)) != -1)
{
switch (ch)
{
@ -339,6 +341,9 @@ int openvpn_client(int argc, char *argv[], const std::string* profile_content)
case 'P':
proto = optarg;
break;
case '6':
ipv6 = optarg;
break;
case 's':
server = optarg;
break;
@ -459,6 +464,7 @@ int openvpn_client(int argc, char *argv[], const std::string* profile_content)
config.protoOverride = proto;
config.connTimeout = timeout;
config.compressionMode = compress;
config.ipv6 = ipv6;
config.privateKeyPassword = privateKeyPassword;
config.tlsVersionMinOverride = tlsVersionMinOverride;
config.disableClientCert = disableClientCert;
@ -621,6 +627,7 @@ int openvpn_client(int argc, char *argv[], const std::string* profile_content)
std::cout << "--dc, -D : dynamic challenge/response cookie" << std::endl;
std::cout << "--proto, -P : protocol override (udp|tcp)" << std::endl;
std::cout << "--server, -s : server override" << std::endl;
std::cout << "--ipv6, -6 : IPv6 (yes|no|default)" << std::endl;
std::cout << "--timeout, -t : timeout" << std::endl;
std::cout << "--compress, -c : compression mode (yes|no|asym)" << std::endl;
std::cout << "--pk-password, -z : private key password" << std::endl;