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
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#ifdef OPENVPN_PLATFORM_WIN
364 if (
config.clientconf.tunPersist)
371#ifdef 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;
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,
"");
636 return std::make_tuple(
false,
string::join(reasons,
"\n"));
645 throw option_error(ERR_INVALID_OPTION_CRYPTO,
"sorry, static key encryption mode (non-SSL/TLS) is not supported");
648 if (opt.
exists(
"fragment"))
649 throw option_error(ERR_INVALID_OPTION_VAL,
"sorry, 'fragment' directive is not supported, nor is connecting to a server that uses 'fragment' directive");
651 if (!opt.
exists(
"client"))
652 throw option_error(ERR_INVALID_CONFIG,
"Neither 'client' nor both 'tls-client' and 'pull' options declared. OpenVPN3 client only supports --client mode.");
657 const auto &mode = opt.
get(
"mode");
658 if (mode.size() != 2 || mode.get(1, 128) !=
"p2p")
660 throw option_error(ERR_INVALID_CONFIG,
"Only 'mode p2p' supported");
665 if (opt.
exists(
"key-method"))
667 auto keymethod = opt.
get(
"key-method");
668 if (keymethod.size() != 2 || keymethod.get(1, 128) !=
"2")
670 throw option_error(ERR_INVALID_OPTION_VAL,
"Only 'key-method 2' is supported: " + keymethod.get(1, 128));
677 "allow-recursive-routing",
684 "data-ciphers-fallback",
688 "explicit-exit-notify",
694 "machine-readable-output",
714 "suppress-timestamps",
724 "auth-gen-token-secret",
725 "auth-user-pass-optional",
726 "auth-user-pass-verify",
738 "ifconfig-ipv6-pool",
740 "ifconfig-pool-persist",
742 "ifconfig-push-constraint",
746 "max-routes-per-client",
753 "stale-routes-check",
754 "tls-crypt-v2-verify",
755 "username-as-common-name",
756 "verify-client-cert",
791 "x509-username-field",
860 "mtu-dynamic",
"no-replay",
"no-name-remapping",
"compat-names",
"ncp-disable",
"no-iv"};
866 "mute-replay-warnings",
894 std::ostringstream
os;
898 if (!options.empty())
902 os << category <<
": ";
903 std::vector<std::string> opts;
904 for (
size_t i = 0; i < options.size(); ++i)
906 auto &o = options[i];
908 opts.push_back(o.get(0, 64));
939 std::unordered_set<std::string> ignoreMetaOptions = {
940 "CLI_PREF_ALLOW_WEB_IMPORT",
941 "CLI_PREF_BASIC_CLIENT",
942 "CLI_PREF_ENABLE_CONNECT",
943 "CLI_PREF_ENABLE_XD_PROXY",
950 std::unordered_set<std::string> ignore_unknown_option_list;
952 if (opt.
exists(
"ignore-unknown-option"))
954 auto igOptlist = opt.
get_index(
"ignore-unknown-option");
955 for (
auto igUnOptIdx : igOptlist)
957 const Option &o = opt[igUnOptIdx];
958 for (
size_t i = 1; i < o.
size(); i++)
960 const auto &optionToIgnore = o.
get(i, 0);
962 ignore_unknown_option_list.insert(optionToIgnore);
968 for (
const auto &o : opt)
974 if (o.meta() && ignoreMetaOptions.contains(o.get(0, 0)))
985 OPENVPN_LOG_NTNL(
"NOTE: This configuration contains options that were not used:\n");
997 showUnusedOptionsByList(opt, ignore_unknown_option_list,
"Ignored by option 'ignore-unknown-option'",
false, errors);
1000 auto ignoredBySetenvOpt = [](
const Option &option)
1001 {
return !option.touched() && option.warnonlyunknown(); };
1002 showOptionsByFunction(opt, ignoredBySetenvOpt,
"Ignored options prefixed with 'setenv opt'",
false, errors);
1004 auto unusedMetaOpt = [](
const Option &option)
1005 {
return !option.touched() && option.meta(); };
1008 auto managmentOpt = [](
const Option &option)
1009 {
return !option.touched() && option.get(0, 0).rfind(
"management", 0) == 0; };
1010 showOptionsByFunction(opt, managmentOpt,
"OpenVPN management interface is not supported by this client",
true, errors);
1013 auto onlyLightlyTouchedOptions = [](
const Option &option)
1014 {
return option.touched_lightly(); };
1015 showOptionsByFunction(opt, onlyLightlyTouchedOptions,
"Unused options, probably specified multiple times in the configuration file",
false, errors);
1017 auto nonTouchedOptions = [](
const Option &option)
1018 {
return !option.touched() && !option.touched_lightly(); };
1021 errors.print_option_errors();
1026 auto func = [&option_set](
const Option &opt)
1027 {
return !opt.touched() && option_set.contains(opt.get(0, 0)); };
1033 template <
typename T>
1036 for (
size_t i = 0; i < opt.size(); ++i)
1054 pi->emplace_back(
"IV_AUTO_SESS",
"1");
1061 if (!
config.clientconf.hwAddrOverride.empty())
1063 pi->emplace_back(
"IV_HWADDR",
config.clientconf.hwAddrOverride);
1068 if (!
config.clientconf.platformVersion.empty())
1069 pi->emplace_back(
"IV_PLAT_VER",
config.clientconf.platformVersion);
1072 std::unordered_map<std::string, std::string> extra_values;
1078 extra_values[kv.key] = kv.value;
1083 if (
config.extra_peer_info.get())
1085 for (
const auto &kv : *
config.extra_peer_info.get())
1087 extra_values[kv.key] = kv.value;
1091 for (
auto kv : extra_values)
1093 pi->emplace_back(kv.first, kv.second);
1098 if (!
config.clientconf.guiVersion.empty())
1099 pi->emplace_back(
"IV_GUI_VER",
config.clientconf.guiVersion);
1102 if (!
config.clientconf.ssoMethods.empty())
1103 pi->emplace_back(
"IV_SSO",
config.clientconf.ssoMethods);
1105 if (!
config.clientconf.appCustomProtocols.empty())
1106 pi->emplace_back(
"IV_ACC",
"2048,6:A," +
config.clientconf.appCustomProtocols);
1113 bool omit_next =
false;
1160 cli_config->creds =
creds;
1170 cli_config->proto_context_config->set_xmit_creds(
true);
1282 const bool relay_mode)
1285 if (relay_mode && !opt.
exists(
"relay-mode"))
1294 SSLLib::SSLAPI::Config::Ptr cc(
new SSLLib::SSLAPI::Config());
1295 cc->set_external_pki_callback(
config.external_pki,
config.clientconf.external_pki_alias);
1296 cc->set_frame(
frame);
1298 cc->set_debug_level(
config.clientconf.sslDebugLevel);
1302 cc->enable_legacy_algorithms(
config.clientconf.enableLegacyAlgorithms);
1303 cc->set_private_key_password(
config.clientconf.privateKeyPassword);
1304 cc->load(opt, lflags);
1305 cc->set_tls_version_min_override(
config.clientconf.tlsVersionMinOverride);
1306 cc->set_tls_cert_profile_override(
config.clientconf.tlsCertProfileOverride);
1307 cc->set_tls_cipher_list(
config.clientconf.tlsCipherList);
1308 cc->set_tls_ciphersuite_list(
config.clientconf.tlsCiphersuitesList);
1312 cp->ssl_factory = cc->new_factory();
1313 cp->relay_mode = relay_mode;
1315 cp->dc_deferred =
true;
1323 cp->extra_peer_info_push_peerinfo = pcc.
pushPeerInfo();
1342#ifdef OPENVPN_EXTERNAL_TRANSPORT_FACTORY
1350 transconf.
protocol = transport_protocol;
1352#ifdef OPENVPN_GREMLIN
1353 udpconf->gremlin_config = gremlin_config;
1360 transconf.
protocol = transport_protocol;
1371 throw option_error(ERR_INVALID_CONFIG,
"internal error: no TCP server entries for " +
alt_proxy->
name() +
" transport");
1383 if (!transport_protocol.
is_tcp())
1384 throw option_error(ERR_INVALID_CONFIG,
"internal error: no TCP server entries for HTTP proxy transport");
1389 httpconf->frame =
frame;
1394 httpconf->rng =
rng;
1395#ifdef PRIVATE_TUNNEL_PROXY
1396 httpconf->skip_html =
true;
1402 if (transport_protocol.
is_udp())
1407 udpconf->frame =
frame;
1411#ifdef OPENVPN_GREMLIN
1412 udpconf->gremlin_config = gremlin_config;
1416 else if (transport_protocol.
is_tcp()
1417#ifdef OPENVPN_TLS_LINK
1418 || transport_protocol.
is_tls()
1425 tcpconf->frame =
frame;
1428#ifdef OPENVPN_TLS_LINK
1429 if (transport_protocol.
is_tls())
1430 tcpconf->use_tls =
true;
1431 tcpconf->tls_ca = tls_ca;
1433#ifdef OPENVPN_GREMLIN
1434 tcpconf->gremlin_config = gremlin_config;
1439 throw option_error(ERR_INVALID_OPTION_VAL,
"internal error: unknown transport protocol");
1467#ifdef OPENVPN_GREMLIN
1481#ifdef OPENVPN_EXTERNAL_TRANSPORT_FACTORY
1484#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