18#ifndef OPENVPN_CLIENT_CLIOPT_H
19#define OPENVPN_CLIENT_CLIOPT_H
23#include <unordered_set>
60#if defined(OPENVPN_PLATFORM_ANDROID)
64#if defined(OPENVPN_EXTERNAL_TRANSPORT_FACTORY)
69#if defined(OPENVPN_EXTERNAL_TUN_FACTORY)
72#elif defined(USE_TUN_BUILDER)
74#elif defined(OPENVPN_PLATFORM_LINUX) && !defined(OPENVPN_FORCE_TUN_NULL)
76#ifdef OPENVPN_COMMAND_AGENT
79#elif defined(OPENVPN_PLATFORM_MAC) && !defined(OPENVPN_FORCE_TUN_NULL)
82#ifdef OPENVPN_COMMAND_AGENT
85#elif defined(OPENVPN_PLATFORM_WIN) && !defined(OPENVPN_FORCE_TUN_NULL)
87#ifdef OPENVPN_COMMAND_AGENT
94#ifdef PRIVATE_TUNNEL_PROXY
95#include <openvpn/pt/ptproxy.hpp>
98#if defined(ENABLE_KOVPN) || defined(ENABLE_OVPNDCO) || defined(ENABLE_OVPNDCOWIN)
102#ifndef OPENVPN_UNUSED_OPTIONS
103#define OPENVPN_UNUSED_OPTIONS "UNKNOWN/UNSUPPORTED OPTIONS"
119 ClientAPI::ConfigCommon::operator=(
config);
121 if (!
config.protoOverride.empty())
124 if (
config.protoVersionOverride == 4)
126 else if (
config.protoVersionOverride == 6)
129 if (!
config.allowUnusedAddrFamilies.empty())
169#ifdef OPENVPN_PLATFORM_ANDROID
170 bool enable_route_emulation =
true;
172#ifdef OPENVPN_GREMLIN
183#if defined(USE_TUN_BUILDER)
187#if defined(OPENVPN_EXTERNAL_TUN_FACTORY)
191#if defined(OPENVPN_EXTERNAL_TRANSPORT_FACTORY)
213#ifdef OPENVPN_EXTERNAL_TRANSPORT_FACTORY
215 extern_transport_factory(
config.extern_transport_factory)
251 CryptoAlgs::allow_default_dc_algs<SSLLib::CryptoAPI>(
cp_main->ssl_factory->libctx(),
252 !
config.clientconf.enableNonPreferredDCAlgorithms,
253 config.clientconf.enableLegacyAlgorithms);
255#if (defined(ENABLE_KOVPN) || defined(ENABLE_OVPNDCO) || defined(ENABLE_OVPNDCOWIN)) && !defined(OPENVPN_FORCE_TUN_NULL) && !defined(OPENVPN_EXTERNAL_TUN_FACTORY)
256 if (
config.clientconf.dco)
257#if defined(USE_TUN_BUILDER)
258 dco = DCOTransport::new_controller(
config.builder);
260 dco = DCOTransport::new_controller(
nullptr);
266#ifdef PRIVATE_TUNNEL_PROXY
276 if (
config.remote_override)
284 throw option_error(ERR_INVALID_CONFIG,
"no remote option specified");
301 if (opt.
exists(
"remote-random"))
322 bool dco_compatible =
false;
324 if (
config.clientconf.dco && !dco_compatible)
326 throw option_error(ERR_INVALID_CONFIG,
"dco_compatibility: config/options are not compatible with dco");
329#ifdef OPENVPN_PLATFORM_UWP
336#ifdef OPENVPN_TLS_LINK
339 tls_ca = opt.
cat(
"tls-ca");
350#if defined(OPENVPN_COMMAND_AGENT) && defined(OPENVPN_PLATFORM_WIN)
363#if defined(OPENVPN_PLATFORM_WIN)
364 if (
config.clientconf.tunPersist)
371#if defined(OPENVPN_EXTERNAL_TUN_FACTORY)
388 throw option_error(ERR_INVALID_CONFIG,
"OPENVPN_EXTERNAL_TUN_FACTORY: no tun factory");
390#elif defined(USE_TUN_BUILDER)
393 tunconf->builder =
config.builder;
394 tunconf->tun_prop.session_name = session_name;
395 tunconf->tun_prop.google_dns_fallback =
config.clientconf.googleDnsFallback;
396 tunconf->tun_prop.dhcp_search_domains_as_split_domains =
config.clientconf.dhcpSearchDomainsAsSplitDomains;
397 tunconf->tun_prop.allow_local_lan_access =
config.clientconf.allowLocalLanAccess;
399 tunconf->tun_prop.mtu = tun_mtu;
400 tunconf->tun_prop.mtu_max = tun_mtu_max;
401 tunconf->frame =
frame;
405#if defined(OPENVPN_PLATFORM_IPHONE)
406 tunconf->retain_sd =
true;
407 tunconf->tun_prefix =
true;
408 if (
config.clientconf.tunPersist)
409 tunconf->tun_prop.remote_bypass =
true;
411#if defined(OPENVPN_PLATFORM_ANDROID)
414 if (
config.enable_route_emulation)
420 tunconf->eer_factory.
reset(
nullptr);
423#if defined(OPENVPN_PLATFORM_MAC)
424 tunconf->tun_prefix =
true;
426 if (
config.clientconf.tunPersist)
430#elif defined(OPENVPN_PLATFORM_LINUX) && !defined(OPENVPN_FORCE_TUN_NULL)
433 tunconf->tun_prop.layer =
layer;
434 tunconf->tun_prop.session_name = session_name;
436 tunconf->tun_prop.mtu = tun_mtu;
437 tunconf->tun_prop.mtu_max = tun_mtu_max;
438 tunconf->tun_prop.google_dns_fallback =
config.clientconf.googleDnsFallback;
439 tunconf->tun_prop.dhcp_search_domains_as_split_domains =
config.clientconf.dhcpSearchDomainsAsSplitDomains;
440 tunconf->generate_tun_builder_capture_event =
config.clientconf.generateTunBuilderCaptureEvent;
442 tunconf->frame =
frame;
444 if (
config.clientconf.tunPersist)
449#elif defined(OPENVPN_PLATFORM_MAC) && !defined(OPENVPN_FORCE_TUN_NULL)
452 tunconf->tun_prop.layer =
layer;
453 tunconf->tun_prop.session_name = session_name;
454 tunconf->tun_prop.google_dns_fallback =
config.clientconf.googleDnsFallback;
455 tunconf->tun_prop.dhcp_search_domains_as_split_domains =
config.clientconf.dhcpSearchDomainsAsSplitDomains;
457 tunconf->tun_prop.mtu = tun_mtu;
458 tunconf->tun_prop.mtu_max = tun_mtu_max;
459 tunconf->frame =
frame;
461 tunconf->stop =
config.stop;
462 if (
config.clientconf.tunPersist)
465#ifndef OPENVPN_COMMAND_AGENT
467 tunconf->tun_prop.remote_bypass =
true;
472#ifdef OPENVPN_COMMAND_AGENT
477#elif defined(OPENVPN_PLATFORM_WIN) && !defined(OPENVPN_FORCE_TUN_NULL)
480 tunconf->tun_prop.layer =
layer;
481 tunconf->tun_prop.session_name = session_name;
482 tunconf->tun_prop.google_dns_fallback =
config.clientconf.googleDnsFallback;
483 tunconf->tun_prop.dhcp_search_domains_as_split_domains =
config.clientconf.dhcpSearchDomainsAsSplitDomains;
485 tunconf->tun_prop.mtu = tun_mtu;
486 tunconf->tun_prop.mtu_max = tun_mtu_max;
487 tunconf->frame =
frame;
489 tunconf->stop =
config.stop;
491 tunconf->allow_local_dns_resolvers =
config.clientconf.allowLocalDnsResolvers;
492 if (
config.clientconf.tunPersist)
495#ifndef OPENVPN_COMMAND_AGENT
497 tunconf->tun_prop.remote_bypass =
true;
501#ifdef OPENVPN_COMMAND_AGENT
509 tunconf->frame =
frame;
601#if defined(ENABLE_KOVPN)
603 return std::make_tuple(
true,
"");
606 std::vector<std::string> reasons;
612 reasons.push_back(
"option " +
optname +
" is not compatible with dco");
616 if (
config.enableLegacyAlgorithms)
618 reasons.emplace_back(
"legacy algorithms are not compatible with dco");
621 if (
config.enableNonPreferredDCAlgorithms)
623 reasons.emplace_back(
"non-preferred data channel algorithms are not compatible with dco");
626 if (!
config.proxyHost.empty())
628 reasons.emplace_back(
"proxyHost config setting is not compatible with dco");
633 return std::make_tuple(
true,
"");
637 return std::make_tuple(
false,
string::join(reasons,
"\n"));
646 throw option_error(ERR_INVALID_OPTION_CRYPTO,
"sorry, static key encryption mode (non-SSL/TLS) is not supported");
649 if (opt.
exists(
"fragment"))
650 throw option_error(ERR_INVALID_OPTION_VAL,
"sorry, 'fragment' directive is not supported, nor is connecting to a server that uses 'fragment' directive");
652 if (!opt.
exists(
"client"))
653 throw option_error(ERR_INVALID_CONFIG,
"Neither 'client' nor both 'tls-client' and 'pull' options declared. OpenVPN3 client only supports --client mode.");
658 const auto &mode = opt.
get(
"mode");
659 if (mode.size() != 2 || mode.get(1, 128) !=
"p2p")
661 throw option_error(ERR_INVALID_CONFIG,
"Only 'mode p2p' supported");
666 if (opt.
exists(
"key-method"))
668 auto keymethod = opt.
get(
"key-method");
669 if (keymethod.size() != 2 || keymethod.get(1, 128) !=
"2")
671 throw option_error(ERR_INVALID_OPTION_VAL,
"Only 'key-method 2' is supported: " + keymethod.get(1, 128));
678 "allow-recursive-routing",
685 "data-ciphers-fallback",
689 "explicit-exit-notify",
695 "machine-readable-output",
715 "suppress-timestamps",
725 "auth-gen-token-secret",
726 "auth-user-pass-optional",
727 "auth-user-pass-verify",
739 "ifconfig-ipv6-pool",
741 "ifconfig-pool-persist",
743 "ifconfig-push-constraint",
747 "max-routes-per-client",
754 "stale-routes-check",
755 "tls-crypt-v2-verify",
756 "username-as-common-name",
757 "verify-client-cert",
792 "x509-username-field",
861 "mtu-dynamic",
"no-replay",
"no-name-remapping",
"compat-names",
"ncp-disable",
"no-iv"};
867 "mute-replay-warnings",
895 std::ostringstream
os;
899 if (!options.empty())
903 os << category <<
": ";
904 std::vector<std::string> opts;
905 for (
size_t i = 0; i < options.size(); ++i)
907 auto &o = options[i];
909 opts.push_back(o.get(0, 64));
940 std::unordered_set<std::string> ignoreMetaOptions = {
941 "CLI_PREF_ALLOW_WEB_IMPORT",
942 "CLI_PREF_BASIC_CLIENT",
943 "CLI_PREF_ENABLE_CONNECT",
944 "CLI_PREF_ENABLE_XD_PROXY",
951 std::unordered_set<std::string> ignore_unknown_option_list;
953 if (opt.
exists(
"ignore-unknown-option"))
955 auto igOptlist = opt.
get_index(
"ignore-unknown-option");
956 for (
auto igUnOptIdx : igOptlist)
958 const Option &o = opt[igUnOptIdx];
959 for (
size_t i = 1; i < o.
size(); i++)
961 const auto &optionToIgnore = o.
get(i, 0);
963 ignore_unknown_option_list.insert(optionToIgnore);
969 for (
const auto &o : opt)
975 if (o.meta() && ignoreMetaOptions.contains(o.get(0, 0)))
986 OPENVPN_LOG_NTNL(
"NOTE: This configuration contains options that were not used:" << std::endl);
998 showUnusedOptionsByList(opt, ignore_unknown_option_list,
"Ignored by option 'ignore-unknown-option'",
false, errors);
1001 auto ignoredBySetenvOpt = [](
const Option &option)
1002 {
return !option.touched() && option.warnonlyunknown(); };
1003 showOptionsByFunction(opt, ignoredBySetenvOpt,
"Ignored options prefixed with 'setenv opt'",
false, errors);
1005 auto unusedMetaOpt = [](
const Option &option)
1006 {
return !option.touched() && option.meta(); };
1009 auto managmentOpt = [](
const Option &option)
1010 {
return !option.touched() && option.get(0, 0).rfind(
"management", 0) == 0; };
1011 showOptionsByFunction(opt, managmentOpt,
"OpenVPN management interface is not supported by this client",
true, errors);
1014 auto onlyLightlyTouchedOptions = [](
const Option &option)
1015 {
return option.touched_lightly(); };
1016 showOptionsByFunction(opt, onlyLightlyTouchedOptions,
"Unused options, probably specified multiple times in the configuration file",
false, errors);
1018 auto nonTouchedOptions = [](
const Option &option)
1019 {
return !option.touched() && !option.touched_lightly(); };
1022 errors.print_option_errors();
1027 auto func = [&option_set](
const Option &opt)
1028 {
return !opt.touched() && option_set.contains(opt.get(0, 0)); };
1034 template <
typename T>
1037 for (
size_t i = 0; i < opt.size(); ++i)
1055 pi->emplace_back(
"IV_AUTO_SESS",
"1");
1062 if (!
config.clientconf.hwAddrOverride.empty())
1064 pi->emplace_back(
"IV_HWADDR",
config.clientconf.hwAddrOverride);
1069 if (!
config.clientconf.platformVersion.empty())
1070 pi->emplace_back(
"IV_PLAT_VER",
config.clientconf.platformVersion);
1073 std::unordered_map<std::string, std::string> extra_values;
1079 extra_values[kv.key] = kv.value;
1084 if (
config.extra_peer_info.get())
1086 for (
auto const &kv : *
config.extra_peer_info.get())
1088 extra_values[kv.key] = kv.value;
1092 for (
auto kv : extra_values)
1094 pi->emplace_back(kv.first, kv.second);
1099 if (!
config.clientconf.guiVersion.empty())
1100 pi->emplace_back(
"IV_GUI_VER",
config.clientconf.guiVersion);
1103 if (!
config.clientconf.ssoMethods.empty())
1104 pi->emplace_back(
"IV_SSO",
config.clientconf.ssoMethods);
1106 if (!
config.clientconf.appCustomProtocols.empty())
1107 pi->emplace_back(
"IV_ACC",
"2048,6:A," +
config.clientconf.appCustomProtocols);
1114 bool omit_next =
false;
1162 cli_config->creds =
creds;
1172 cli_config->proto_context_config->set_xmit_creds(
true);
1285 const bool relay_mode)
1288 if (relay_mode && !opt.
exists(
"relay-mode"))
1297 SSLLib::SSLAPI::Config::Ptr cc(
new SSLLib::SSLAPI::Config());
1298 cc->set_external_pki_callback(
config.external_pki,
config.clientconf.external_pki_alias);
1299 cc->set_frame(
frame);
1301 cc->set_debug_level(
config.clientconf.sslDebugLevel);
1305 cc->enable_legacy_algorithms(
config.clientconf.enableLegacyAlgorithms);
1306 cc->set_private_key_password(
config.clientconf.privateKeyPassword);
1307 cc->load(opt, lflags);
1308 cc->set_tls_version_min_override(
config.clientconf.tlsVersionMinOverride);
1309 cc->set_tls_cert_profile_override(
config.clientconf.tlsCertProfileOverride);
1310 cc->set_tls_cipher_list(
config.clientconf.tlsCipherList);
1311 cc->set_tls_ciphersuite_list(
config.clientconf.tlsCiphersuitesList);
1315 cp->ssl_factory = cc->new_factory();
1316 cp->relay_mode = relay_mode;
1318 cp->dc_deferred =
true;
1326 cp->extra_peer_info_push_peerinfo = pcc.
pushPeerInfo();
1345#ifdef OPENVPN_EXTERNAL_TRANSPORT_FACTORY
1353 transconf.
protocol = transport_protocol;
1355#ifdef OPENVPN_GREMLIN
1356 udpconf->gremlin_config = gremlin_config;
1363 transconf.
protocol = transport_protocol;
1374 throw option_error(ERR_INVALID_CONFIG,
"internal error: no TCP server entries for " +
alt_proxy->
name() +
" transport");
1386 if (!transport_protocol.
is_tcp())
1387 throw option_error(ERR_INVALID_CONFIG,
"internal error: no TCP server entries for HTTP proxy transport");
1392 httpconf->frame =
frame;
1397 httpconf->rng =
rng;
1398#ifdef PRIVATE_TUNNEL_PROXY
1399 httpconf->skip_html =
true;
1405 if (transport_protocol.
is_udp())
1410 udpconf->frame =
frame;
1414#ifdef OPENVPN_GREMLIN
1415 udpconf->gremlin_config = gremlin_config;
1419 else if (transport_protocol.
is_tcp()
1420#ifdef OPENVPN_TLS_LINK
1421 || transport_protocol.
is_tls()
1428 tcpconf->frame =
frame;
1431#ifdef OPENVPN_TLS_LINK
1432 if (transport_protocol.
is_tls())
1433 tcpconf->use_tls =
true;
1434 tcpconf->tls_ca = tls_ca;
1436#ifdef OPENVPN_GREMLIN
1437 tcpconf->gremlin_config = gremlin_config;
1442 throw option_error(ERR_INVALID_OPTION_VAL,
"internal error: unknown transport protocol");
1470#ifdef OPENVPN_GREMLIN
1484#ifdef OPENVPN_EXTERNAL_TRANSPORT_FACTORY
1487#ifdef OPENVPN_TLS_LINK
bool username_defined() const
void set_username(const std::string &username_arg)
std::string get_http_proxy_username() const
bool http_proxy_password_defined() const
std::string get_http_proxy_password() const
bool session_id_defined() const
void set_password(const std::string &password_arg)
bool http_proxy_username_defined() const
void save_username_for_session_id()
std::map< std::string, std::vector< Option > > options_per_category
void print_option_errors()
void add_failed_opt(const Option &o, const std::string &message, bool fatal_arg)
void check_for_incompatible_options(const OptionList &opt)
std::unordered_set< std::string > settings_standalone_options
void showOptionsByFunction(const OptionList &opt, T func, const std::string &message, bool fatal, OptionErrors &errors)
ReconnectNotify * reconnect_notify
const SessionStats::Ptr & stats_ptr() const
ProtoContext::ProtoConfig & proto_config_cached(const bool relay_mode)
void showUnusedOptionsByList(const OptionList &optlist, std::unordered_set< std::string > option_set, const std::string &message, bool fatal, OptionErrors &errors)
std::unordered_set< std::string > settings_ignoreSilently
std::unordered_set< std::string > settings_feature_not_implemented_warn
void handle_unused_options(const OptionList &opt)
ProtoContext::ProtoConfig::Ptr cp_main
ClientProto::Session Client
PushOptionsBase::Ptr push_base
static std::tuple< bool, std::string > check_dco_compatibility(const ClientAPI::ConfigCommon &config, const OptionList &opt)
std::unordered_set< std::string > settings_ignoreWithWarning
TransportClientFactory::Ptr transport_factory
ClientEvent::Queue::Ptr cli_events
HTTPProxyTransport::Options::Ptr http_proxy_options
std::unordered_set< std::string > settings_removedOptions
unsigned int server_poll_timeout_
ClientLifeCycle::Ptr client_lifecycle
TunClientFactory::Ptr tun_factory
void finalize(const bool disconnected)
unsigned int tcp_queue_limit
std::unordered_set< std::string > settings_script_plugin_feature
static PeerInfo::Set::Ptr build_peer_info(const Config &config, const ParseClientConfig &pcc, const bool autologin_sessions)
std::unordered_set< std::string > settings_serverOnlyOptions
RCPtr< ClientOptions > Ptr
SocketProtect * socket_protect
ProtoContext::ProtoConfig::Ptr cp_relay
SessionStats::Ptr cli_stats
bool server_poll_timeout_enabled() const
RemoteList::Ptr remote_list
bool asio_work_always_on() const
ClientConfigParsed clientconf
bool pause_on_connection_timeout()
void next(RemoteList::Advance type)
static std::unordered_set< std::string > dco_incompatible_opts
ClientEvent::Queue & events()
OptionList::FilterBase::Ptr pushed_options_filter
ClientLifeCycle * lifecycle()
std::unordered_set< std::string > settings_pushonlyoptions
Time::Duration server_poll_timeout() const
bool synchronous_dns_lookup
bool retry_on_auth_failed() const
ClientOptions(const OptionList &opt, const Config &config)
std::string userlocked_username
void submit_creds(const ClientCreds::Ptr &creds_arg)
std::string load_transport_config()
ProtoContext::ProtoConfig::Ptr proto_config(const OptionList &opt, const Config &config, const ParseClientConfig &pcc, const bool relay_mode)
std::unordered_set< std::string > settings_feature_not_implemented_fatal
ProtoContextCompressionOptions::Ptr proto_context_options
RemoteList::Ptr remote_list_precache() const
Client::Config::Ptr client_config(const bool relay_mode)
void remote_reset_cache_item()
bool asio_work_always_on_
static Ptr parse(const OptionList &opt)
std::string cat(const std::string &name) const
void extend(const OptionList &other, FilterBase *filt=nullptr)
const IndexList & get_index(const std::string &name) const
T get_num(const std::string &name, const size_t idx, const T default_value) const
void touch(const std::string &name) const
const Option & get(const std::string &name) const
size_t n_unused(bool ignore_meta=false) const
const Option * get_ptr(const std::string &name) const
bool exists(const std::string &name) const
void touch(bool lightly=false) const
const std::string & get(const size_t index, const size_t max_len) const
bool hasEmbeddedPassword() const
const std::string & embeddedPassword() const
const PeerInfo::Set * peerInfoUV() const
bool pushPeerInfo() const
const std::string & userlockedUsername() const
bool clientCertEnabled() const
static Protocol parse(const std::string &str, const AllowSuffix allow_suffix, const char *title=nullptr)
void reset() noexcept
Points this RCPtr<T> to nullptr safely.
T * get() const noexcept
Returns the raw pointer to the object T, or nullptr.
Reference count base class for objects tracked by RCPtr. Disallows copying and assignment.
virtual bool pause_on_connection_timeout()=0
void set_server_override(const std::string &server_override)
void next(Advance type=Advance::Addr)
void handle_proto_override(const Protocol &proto_override, const bool tcp_proxy_enabled)
void set_enable_cache(const bool enable_cache_arg)
void set_random(const RandomAPI::Ptr &rng_arg)
void set_proto_version_override(const IP::Addr::Version v)
void set_port_override(const std::string &port_override)
const Protocol & current_transport_protocol() const
std::string current_server_host() const
static TriStateSetting parse(const std::string &str)
TunBuilder methods, loosely based on the Android VpnService.Builder abstraction.
static TunBuilderSetup::Factory::Ptr new_agent(const OptionList &opt)
static TunWin::SetupFactory::Ptr new_agent(const OptionList &opt)
#define OPENVPN_UNUSED_OPTIONS
#define OPENVPN_LOG_NTNL(args)
#define OPENVPN_LOG(args)
auto join(const T &strings, const typename T::value_type &delim, const bool tail=false)
unsigned int parse_tun_mtu_max(const OptionList &opt, unsigned int default_value)
Frame::Ptr frame_init(const bool align_adjust_3_1, const size_t tun_mtu_max, const size_t control_channel_payload, const bool verbose)
unsigned int parse_tun_mtu(const OptionList &opt, unsigned int default_value)
const std::string get_ssl_library_version()
SocketProtect * socket_protect
DigestFactory::Ptr digest_factory
RemoteList::Ptr remote_list
virtual TransportClientFactory::Ptr new_transport_client_factory(const Config &)=0
virtual std::string name() const =0
virtual void precache(RemoteList::Ptr &r)=0
virtual bool requires_tcp() const =0
virtual void set_enable_cache(const bool enable_cache)=0
TriStateSetting allowUnusedAddrFamilies
std::string external_pki_alias
IP::Addr::Version proto_version_override
void import_client_settings(const ClientAPI::Config &config)
ReconnectNotify * reconnect_notify
ClientEvent::Queue::Ptr cli_events
ClientConfigParsed clientconf
PeerInfo::Set::Ptr extra_peer_info
RemoteList::RemoteOverride * remote_override
int default_key_direction
ExternalPKIBase * external_pki
SessionStats::Ptr cli_stats
ProtoContextCompressionOptions::Ptr proto_context_options
bool synchronous_dns_lookup
HTTPProxyTransport::Options::Ptr http_proxy_options
SocketProtect * socket_protect
RemoteList::Ptr remote_list
SocketProtect * socket_protect
bool allow_local_dns_resolvers
virtual TunClientFactory::Ptr new_tun_factory(const TunConfig &conf, const OptionList &opt)=0
virtual TransportClientFactory::Ptr new_transport_factory(const TransportConfig &conf)=0
RemoteList::Ptr remote_list
SocketProtect * socket_protect
bool synchronous_dns_lookup
virtual void finalize(const bool disconnected)
RemoteList::Ptr remote_list
bool dhcp_search_domains_as_split_domains
static const char config[]
const std::string optname