58 std::string addr_str = address_input;
61 bool ipv6_bracket_encaps = address_input.length() > 2
62 && address_input[0] ==
'['
63 && address_input.rfind(
']') != std::string::npos;
65 auto first_colon_pos = address_input.find(
':');
66 auto last_colon_pos = address_input.rfind(
':');
67 const bool v6_port_found = ipv6_bracket_encaps
68 && last_colon_pos > address_input.rfind(
']');
70 const bool v4_port_found = first_colon_pos != std::string::npos
71 && first_colon_pos == addr_str.rfind(
':');
73 if (v6_port_found || v4_port_found)
83 ipv6_bracket_encaps =
false;
88 if (ipv6_bracket_encaps)
90 addr_str = addr_str.substr(1, addr_str.length() - 2);
92 addr =
IP::Addr(addr_str,
"dns-ip-address");
94 catch (
const IP::ip_exception &)
113 std::ostringstream
os;
135 Json::Value root(Json::objectValue);
136 root[
"address"] = Json::Value(
address);
139 root[
"port"] = Json::Value(
port);
144 void from_json(
const Json::Value &root,
const std::string &title)
149 std::string addr_str;
193 return Json::Value(
domain);
196 void from_json(
const Json::Value &value,
const std::string &title)
198 if (!value.isString())
200 throw json::json_parse(
"string " + title +
" is of incorrect type");
202 domain = value.asString();
270 if (dnssec_value ==
"yes")
274 else if (dnssec_value ==
"no")
278 else if (dnssec_value ==
"optional")
339 if (transport_value ==
"plain")
343 else if (transport_value ==
"DoH")
347 else if (transport_value ==
"DoT")
368 explicit DnsServer(
const Json::Value &root,
const std::string &title =
"")
382 std::ostringstream
os;
383 os << prefix <<
"Addresses:\n";
386 os << prefix <<
" " <<
address.to_string() <<
'\n';
390 os << prefix <<
"Domains:\n";
391 for (
const auto &domain :
domains)
393 os << prefix <<
" " << domain.to_string() <<
'\n';
406 os << prefix <<
"SNI: " <<
sni <<
'\n';
425 Json::Value server(Json::objectValue);
441 server[
"sni"] = Json::Value(
sni);
454 void from_json(
const Json::Value &root,
const std::string &title)
464 std::string dnssec_str;
466 if (dnssec_str ==
"Optional")
470 else if (dnssec_str ==
"Yes")
474 else if (dnssec_str ==
"No")
480 throw json::json_parse(
"dnssec value " + dnssec_str +
"is unknown");
485 std::string transport_str;
487 if (transport_str ==
"Plain")
491 else if (transport_str ==
"HTTPS")
495 else if (transport_str ==
"TLS")
501 throw json::json_parse(
"transport value " + transport_str +
"is unknown");
543 explicit DnsOptions(
const Json::Value &root,
const std::string &title =
"")
557 std::ostringstream
os;
560 os <<
"DNS Servers:\n";
561 for (
const auto &[priority, server] :
servers)
563 os <<
" Priority: " << priority <<
'\n';
564 os << server.to_string(
" ");
569 os <<
"DNS Search Domains:\n";
572 os <<
" " << domain.to_string() <<
'\n';
593 Json::Value root(Json::objectValue);
594 Json::Value servers_json(Json::objectValue);
595 for (
const auto &[prio, server] :
servers)
597 servers_json[std::to_string(prio)] = server.to_json();
599 root[
"servers"] = std::move(servers_json);
613 void from_json(
const Json::Value &root,
const std::string &title)
617 for (
const auto &prio : root[
"servers"].getMemberNames())
619 DnsServer server(root[
"servers"][prio], title);
620 servers[std::stoi(prio)] = std::move(server);
static Addr from_string(const std::string &ipstr, const TITLE &title, const Version required_version)
std::string to_string() const
static std::string validate(const std::string &ipstr, const TITLE &title, const Version required_version)
#define OPENVPN_THROW_EXCEPTION(stuff)
void validate_host(const std::string &host, const std::string &title)
bool split_host_port(const std::string &str, std::string &host, std::string &port, const std::string &default_port, const bool allow_unix, unsigned int *port_save=nullptr)
void assert_dict(const Json::Value &obj, const TITLE &title)
void to_string_optional(const Json::Value &root, std::string &dest, const NAME &name, const std::string &default_value, const TITLE &title)
void to_string(const Json::Value &root, std::string &dest, const NAME &name, const TITLE &title)
void to_vector(const Json::Value &root, T &vec, const NAME &name, const TITLE &title)
bool exists(const Json::Value &root, const NAME &name)
void to_bool(const Json::Value &root, bool &dest, const NAME &name, const TITLE &title)
void from_vector(Json::Value &root, const T &vec, const NAME &name)
void to_uint_optional(const Json::Value &root, unsigned int &dest, const NAME &name, const unsigned int default_value, const TITLE &title)
A name server address and optional port.
bool operator==(const DnsAddress &) const =default
Json::Value to_json() const
virtual ~DnsAddress() noexcept=default
void from_json(const Json::Value &root, const std::string &title)
void validate(const std::string &title) const
std::string to_string() const
Return string representation of the IP address and port stored in the DnsAddress object.
bool operator==(const DnsDomain &) const =default
void validate(const std::string &title) const
std::string to_string() const
Return string representation of the DnsDomain object.
Json::Value to_json() const
virtual ~DnsDomain() noexcept=default
void from_json(const Json::Value &value, const std::string &title)
All DNS options set with the –dns or –dhcp-option directive.
std::map< int, DnsServer > servers
List of DNS servers to use, according to the list of priority.
DnsServer & get_server(const int priority)
void from_json(const Json::Value &root, const std::string &title)
std::vector< DnsDomain > search_domains
List of global DNS search domains to use.
~DnsOptions() noexcept=default
bool from_dhcp_options
Set to true if the DNS options comes from –dhcp-option options.
DnsOptions(const Json::Value &root, const std::string &title="")
bool operator==(const DnsOptions &at) const =default
std::string to_string() const
Json::Value to_json() const
DNS settings for a name server.
std::vector< DnsAddress > addresses
Parsed from –dns server n address ADDRESS[:PORT] [...] or –dhcp-option DNS/DNS6.
DnsServer(const Json::Value &root, const std::string &title="")
std::vector< DnsDomain > domains
Parsed from –dns server n resolve-domains DOMAIN [...] or –dhcp-option DOMAIN/DOMAIN-SEARCH if use_se...
void parse_transport_value(const std::string &transport_value)
std::string transport_string() const
Return string representation of a given DnsServer::Transport value.
static std::string transport_string(const Transport transport)
Return string representation of a given DnsServer::Transport value.
static std::string dnssec_string(const Security dnssec)
Return string representation of a given DnsServer::Security value.
std::string to_string(const char *prefix="") const
bool operator==(const DnsServer &at) const =default
std::string sni
Parsed from –dns server n sni.
virtual ~DnsServer() noexcept=default
Security dnssec
Parsed from –dns server n dnssec {yes,optional,no}.
@ Yes
Enforce using DNSSEC.
@ Unset
Undefined setting; default value when not set.
@ Optional
Try to use DNSSEC opportunistically. If it fails, the DNS resolver may ignore DNSSEC.
Json::Value to_json() const
std::string dnssec_string() const
Return string representation of the dnssec value in this DnsServer object.
@ TLS
Use DNS-over-TLS (DoT)
@ HTTPS
Use DNS-over-HTTPS (DoH)
@ Plain
Use the classic unencrypted DNS protocol.
@ Unset
Undefined setting; default value when not set.
void from_json(const Json::Value &root, const std::string &title)
Transport transport
Parsed from –dns server n transport {plain,DoT,DoH}.
void parse_dnssec_value(const std::string &dnssec_value)
TunBuilderCapture::RemoteAddress from_json