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:
parent
afc1a40d00
commit
2b42b96312
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
89
openvpn/tun/ipv6_setting.hpp
Normal file
89
openvpn/tun/ipv6_setting.hpp
Normal 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
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user