18#ifndef OPENVPN_CLIENT_CLIOPT_H
19#define OPENVPN_CLIENT_CLIOPT_H
23#include <unordered_set>
60#ifdef OPENVPN_PLATFORM_ANDROID
64#ifdef OPENVPN_EXTERNAL_TRANSPORT_FACTORY
69#ifdef 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#ifdef USE_TUN_BUILDER
187#ifdef OPENVPN_EXTERNAL_TUN_FACTORY
191#ifdef OPENVPN_EXTERNAL_TRANSPORT_FACTORY
208#ifdef OPENVPN_GREMLIN
209 gremlin_config(
config.gremlin_config),
216#ifdef OPENVPN_EXTERNAL_TRANSPORT_FACTORY
218 extern_transport_factory(
config.extern_transport_factory)
254 CryptoAlgs::allow_default_dc_algs<SSLLib::CryptoAPI>(
cp_main->ssl_factory->libctx(),
255 !
config.clientconf.enableNonPreferredDCAlgorithms,
256 config.clientconf.enableLegacyAlgorithms);
258#if (defined(ENABLE_KOVPN) || defined(ENABLE_OVPNDCO) || defined(ENABLE_OVPNDCOWIN)) && !defined(OPENVPN_FORCE_TUN_NULL) && !defined(OPENVPN_EXTERNAL_TUN_FACTORY)
259 if (
config.clientconf.dco)
260#if defined(USE_TUN_BUILDER)
261 dco = DCOTransport::new_controller(
config.builder);
263 dco = DCOTransport::new_controller(
nullptr);
269#ifdef PRIVATE_TUNNEL_PROXY
279 if (
config.remote_override)
287 throw option_error(ERR_INVALID_CONFIG,
"no remote option specified");
304 if (opt.
exists(
"remote-random"))
325 bool dco_compatible =
false;
327 if (
config.clientconf.dco && !dco_compatible)
329 throw option_error(ERR_INVALID_CONFIG,
"dco_compatibility: config/options are not compatible with dco");
332#ifdef OPENVPN_PLATFORM_UWP
339#ifdef OPENVPN_TLS_LINK
342 tls_ca = opt.
cat(
"tls-ca");
353#if defined(OPENVPN_COMMAND_AGENT) && defined(OPENVPN_PLATFORM_WIN)
366#ifdef OPENVPN_PLATFORM_WIN
367 if (
config.clientconf.tunPersist)
374#ifdef OPENVPN_EXTERNAL_TUN_FACTORY
391 throw option_error(ERR_INVALID_CONFIG,
"OPENVPN_EXTERNAL_TUN_FACTORY: no tun factory");
393#elif defined(USE_TUN_BUILDER)
396 tunconf->builder =
config.builder;
397 tunconf->tun_prop.session_name = session_name;
398 tunconf->tun_prop.google_dns_fallback =
config.clientconf.googleDnsFallback;
399 tunconf->tun_prop.dhcp_search_domains_as_split_domains =
config.clientconf.dhcpSearchDomainsAsSplitDomains;
400 tunconf->tun_prop.allow_local_lan_access =
config.clientconf.allowLocalLanAccess;
402 tunconf->tun_prop.mtu = tun_mtu;
403 tunconf->tun_prop.mtu_max = tun_mtu_max;
404 tunconf->frame =
frame;
408#if defined(OPENVPN_PLATFORM_IPHONE)
409 tunconf->retain_sd =
true;
410 tunconf->tun_prefix =
true;
411 if (
config.clientconf.tunPersist)
412 tunconf->tun_prop.remote_bypass =
true;
414#if defined(OPENVPN_PLATFORM_ANDROID)
417 if (
config.enable_route_emulation)
423 tunconf->eer_factory.
reset(
nullptr);
426#if defined(OPENVPN_PLATFORM_MAC)
427 tunconf->tun_prefix =
true;
429 if (
config.clientconf.tunPersist)
433#elif defined(OPENVPN_PLATFORM_LINUX) && !defined(OPENVPN_FORCE_TUN_NULL)
436 tunconf->tun_prop.layer =
layer;
437 tunconf->tun_prop.session_name = session_name;
439 tunconf->tun_prop.mtu = tun_mtu;
440 tunconf->tun_prop.mtu_max = tun_mtu_max;
441 tunconf->tun_prop.google_dns_fallback =
config.clientconf.googleDnsFallback;
442 tunconf->tun_prop.dhcp_search_domains_as_split_domains =
config.clientconf.dhcpSearchDomainsAsSplitDomains;
443 tunconf->generate_tun_builder_capture_event =
config.clientconf.generateTunBuilderCaptureEvent;
445 tunconf->frame =
frame;
447 if (
config.clientconf.tunPersist)
452#elif defined(OPENVPN_PLATFORM_MAC) && !defined(OPENVPN_FORCE_TUN_NULL)
455 tunconf->tun_prop.layer =
layer;
456 tunconf->tun_prop.session_name = session_name;
457 tunconf->tun_prop.google_dns_fallback =
config.clientconf.googleDnsFallback;
458 tunconf->tun_prop.dhcp_search_domains_as_split_domains =
config.clientconf.dhcpSearchDomainsAsSplitDomains;
460 tunconf->tun_prop.mtu = tun_mtu;
461 tunconf->tun_prop.mtu_max = tun_mtu_max;
462 tunconf->frame =
frame;
464 tunconf->stop =
config.stop;
465 if (
config.clientconf.tunPersist)
468#ifndef OPENVPN_COMMAND_AGENT
470 tunconf->tun_prop.remote_bypass =
true;
475#ifdef OPENVPN_COMMAND_AGENT
480#elif defined(OPENVPN_PLATFORM_WIN) && !defined(OPENVPN_FORCE_TUN_NULL)
483 tunconf->tun_prop.layer =
layer;
484 tunconf->tun_prop.session_name = session_name;
485 tunconf->tun_prop.google_dns_fallback =
config.clientconf.googleDnsFallback;
486 tunconf->tun_prop.dhcp_search_domains_as_split_domains =
config.clientconf.dhcpSearchDomainsAsSplitDomains;
488 tunconf->tun_prop.mtu = tun_mtu;
489 tunconf->tun_prop.mtu_max = tun_mtu_max;
490 tunconf->frame =
frame;
492 tunconf->stop =
config.stop;
494 tunconf->allow_local_dns_resolvers =
config.clientconf.allowLocalDnsResolvers;
495 if (
config.clientconf.tunPersist)
498#ifndef OPENVPN_COMMAND_AGENT
500 tunconf->tun_prop.remote_bypass =
true;
504#ifdef OPENVPN_COMMAND_AGENT
512 tunconf->frame =
frame;
606 return std::make_tuple(
true,
"");
609 std::vector<std::string> reasons;
615 reasons.push_back(
"option " +
optname +
" is not compatible with dco");
619 if (
config.enableLegacyAlgorithms)
621 reasons.emplace_back(
"legacy algorithms are not compatible with dco");
624 if (
config.enableNonPreferredDCAlgorithms)
626 reasons.emplace_back(
"non-preferred data channel algorithms are not compatible with dco");
629 if (!
config.proxyHost.empty())
631 reasons.emplace_back(
"proxyHost config setting is not compatible with dco");
636 return std::make_tuple(
true,
"");
639 return std::make_tuple(
false,
string::join(reasons,
"\n"));
648 throw option_error(ERR_INVALID_OPTION_CRYPTO,
"sorry, static key encryption mode (non-SSL/TLS) is not supported");
651 if (opt.
exists(
"fragment"))
652 throw option_error(ERR_INVALID_OPTION_VAL,
"sorry, 'fragment' directive is not supported, nor is connecting to a server that uses 'fragment' directive");
654 if (!opt.
exists(
"client"))
655 throw option_error(ERR_INVALID_CONFIG,
"Neither 'client' nor both 'tls-client' and 'pull' options declared. OpenVPN3 client only supports --client mode.");
660 const auto &mode = opt.
get(
"mode");
661 if (mode.size() != 2 || mode.get(1, 128) !=
"p2p")
663 throw option_error(ERR_INVALID_CONFIG,
"Only 'mode p2p' supported");
668 if (opt.
exists(
"key-method"))
670 auto keymethod = opt.
get(
"key-method");
671 if (keymethod.size() != 2 || keymethod.get(1, 128) !=
"2")
673 throw option_error(ERR_INVALID_OPTION_VAL,
"Only 'key-method 2' is supported: " + keymethod.get(1, 128));
680 "allow-recursive-routing",
687 "data-ciphers-fallback",
691 "explicit-exit-notify",
697 "machine-readable-output",
717 "suppress-timestamps",
727 "auth-gen-token-secret",
728 "auth-user-pass-optional",
729 "auth-user-pass-verify",
741 "ifconfig-ipv6-pool",
743 "ifconfig-pool-persist",
745 "ifconfig-push-constraint",
749 "max-routes-per-client",
756 "stale-routes-check",
757 "tls-crypt-v2-verify",
758 "username-as-common-name",
759 "verify-client-cert",
794 "x509-username-field",
863 "mtu-dynamic",
"no-replay",
"no-name-remapping",
"compat-names",
"ncp-disable",
"no-iv"};
869 "mute-replay-warnings",
897 std::ostringstream os;
901 if (!options.empty())
905 os << category <<
": ";
906 std::vector<std::string> opts;
907 for (
size_t i = 0; i < options.size(); ++i)
909 auto &o = options[i];
911 opts.push_back(o.get(0, 64));
942 std::unordered_set<std::string> ignoreMetaOptions = {
943 "CLI_PREF_ALLOW_WEB_IMPORT",
944 "CLI_PREF_BASIC_CLIENT",
945 "CLI_PREF_ENABLE_CONNECT",
946 "CLI_PREF_ENABLE_XD_PROXY",
953 std::unordered_set<std::string> ignore_unknown_option_list;
955 if (opt.
exists(
"ignore-unknown-option"))
957 auto igOptlist = opt.
get_index(
"ignore-unknown-option");
958 for (
auto igUnOptIdx : igOptlist)
960 const Option &o = opt[igUnOptIdx];
961 for (
size_t i = 1; i < o.
size(); i++)
963 const auto &optionToIgnore = o.
get(i, 0);
965 ignore_unknown_option_list.insert(optionToIgnore);
971 for (
const auto &o : opt)
977 if (o.meta() && ignoreMetaOptions.contains(o.get(0, 0)))
988 OPENVPN_LOG_NTNL(
"NOTE: This configuration contains options that were not used:\n");
1000 showUnusedOptionsByList(opt, ignore_unknown_option_list,
"Ignored by option 'ignore-unknown-option'",
false, errors);
1003 auto ignoredBySetenvOpt = [](
const Option &option)
1004 {
return !option.touched() && option.warnonlyunknown(); };
1005 showOptionsByFunction(opt, ignoredBySetenvOpt,
"Ignored options prefixed with 'setenv opt'",
false, errors);
1007 auto unusedMetaOpt = [](
const Option &option)
1008 {
return !option.touched() && option.meta(); };
1011 auto managmentOpt = [](
const Option &option)
1012 {
return !option.touched() && option.get(0, 0).rfind(
"management", 0) == 0; };
1013 showOptionsByFunction(opt, managmentOpt,
"OpenVPN management interface is not supported by this client",
true, errors);
1016 auto onlyLightlyTouchedOptions = [](
const Option &option)
1017 {
return option.touched_lightly(); };
1018 showOptionsByFunction(opt, onlyLightlyTouchedOptions,
"Unused options, probably specified multiple times in the configuration file",
false, errors);
1020 auto nonTouchedOptions = [](
const Option &option)
1021 {
return !option.touched() && !option.touched_lightly(); };
1024 errors.print_option_errors();
1029 auto func = [&option_set](
const Option &opt)
1030 {
return !opt.touched() && option_set.contains(opt.get(0, 0)); };
1036 template <
typename T>
1039 for (
size_t i = 0; i < opt.size(); ++i)
1057 pi->emplace_back(
"IV_AUTO_SESS",
"1");
1064 if (!
config.clientconf.hwAddrOverride.empty())
1066 pi->emplace_back(
"IV_HWADDR",
config.clientconf.hwAddrOverride);
1071 if (!
config.clientconf.platformVersion.empty())
1072 pi->emplace_back(
"IV_PLAT_VER",
config.clientconf.platformVersion);
1075 std::unordered_map<std::string, std::string> extra_values;
1081 extra_values[kv.key] = kv.value;
1086 if (
config.extra_peer_info.get())
1088 for (
const auto &kv : *
config.extra_peer_info.get())
1090 extra_values[kv.key] = kv.value;
1094 for (
auto kv : extra_values)
1096 pi->emplace_back(kv.first, kv.second);
1101 if (!
config.clientconf.guiVersion.empty())
1102 pi->emplace_back(
"IV_GUI_VER",
config.clientconf.guiVersion);
1105 if (!
config.clientconf.ssoMethods.empty())
1106 pi->emplace_back(
"IV_SSO",
config.clientconf.ssoMethods);
1108 if (!
config.clientconf.appCustomProtocols.empty())
1109 pi->emplace_back(
"IV_ACC",
"2048,6:A," +
config.clientconf.appCustomProtocols);
1116 bool omit_next =
false;
1163 cli_config->creds =
creds;
1173 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
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
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