47 const auto min_prio = std::numeric_limits<std::int8_t>::min();
48 const auto max_prio = std::numeric_limits<std::int8_t>::max();
51 if (!parse_number_validate<int>(prio_str, 4, min_prio, max_prio, &priority))
52 OPENVPN_THROW_ARG1(option_error, ERR_INVALID_OPTION_DNS,
"dns server priority '" << prio_str <<
"' invalid");
62 if (indices ==
nullptr)
67 for (
const auto i : *indices)
71 const auto &o = opt[i];
72 if (o.size() >= 3 && o.ref(1) ==
"search-domains")
74 for (std::size_t j = 2; j < o.size(); j++)
79 else if (o.size() >= 5 && o.ref(1) ==
"server")
84 const auto &server_suboption = o.ref(3);
85 if (server_suboption ==
"address" && o.size() <= 12)
87 for (std::size_t j = 4; j < o.size(); j++)
90 unsigned int port = 0;
91 std::string addr_str = o.ref(j);
93 const bool v4_port_found = addr_str.find(
':') != std::string::npos
94 && addr_str.find(
':') == addr_str.rfind(
':');
96 if (addr_str[0] ==
'[' || v4_port_found)
98 const auto &addr_port_str = o.ref(j);
102 OPENVPN_THROW_ARG1(option_error, ERR_INVALID_OPTION_DNS,
"dns server " << priority <<
" invalid address: " << addr_port_str);
110 catch (
const IP::ip_exception &)
112 OPENVPN_THROW_ARG1(option_error, ERR_INVALID_OPTION_DNS,
"dns server " << priority <<
" invalid address: " << addr_str);
118 else if (server_suboption ==
"resolve-domains")
120 for (std::size_t j = 4; j < o.size(); j++)
122 server.domains.push_back({o.ref(j)});
125 else if (server_suboption ==
"dnssec" && o.size() == 5)
127 const auto &dnssec_value = o.ref(4);
128 if (dnssec_value ==
"yes")
132 else if (dnssec_value ==
"no")
136 else if (dnssec_value ==
"optional")
142 OPENVPN_THROW_ARG1(option_error, ERR_INVALID_OPTION_DNS,
"dns server " << priority <<
" dnssec setting '" << dnssec_value <<
"' invalid");
145 else if (server_suboption ==
"transport" && o.size() == 5)
147 const auto &transport_value = o.ref(4);
148 if (transport_value ==
"plain")
152 else if (transport_value ==
"DoH")
156 else if (transport_value ==
"DoT")
162 OPENVPN_THROW_ARG1(option_error, ERR_INVALID_OPTION_DNS,
"dns server " << priority <<
" transport '" << transport_value <<
"' invalid");
165 else if (server_suboption ==
"sni" && o.size() == 5)
167 server.sni = o.ref(4);
171 OPENVPN_THROW_ARG1(option_error, ERR_INVALID_OPTION_DNS,
"dns server " << priority <<
" option '" << server_suboption <<
"' unknown or too many parameters");
179 catch (
const std::exception &e)
187 std::vector<int> remove_servers;
188 for (
const auto &[priority, server] :
servers)
190 if (server.addresses.empty())
193 parse_errors +=
"dns server " + std::to_string(priority) +
" does not have an address assigned";
194 remove_servers.push_back(priority);
197 for (
const auto &prio : remove_servers)
211 auto dhcp_map = opt.
map().find(
"dhcp-option");
212 if (dhcp_map == opt.
map().end())
224 std::string adapter_domain_suffix;
225 for (
const auto &i : dhcp_map->second)
231 const std::string &type = o.
get(1, 64);
232 if (type ==
"DNS" || type ==
"DNS6")
241 server.addresses.push_back({addr.
to_string(), 0});
245 catch (
const IP::ip_exception &)
250 else if (type ==
"DOMAIN" || type ==
"DOMAIN-SEARCH")
253 for (
size_t i = 2; i < o.
size(); ++i)
255 using StrVec = std::vector<std::string>;
256 StrVec domains = Split::by_space<StrVec, StandardLex, SpaceMatch, Split::NullLimit>(o.
get(i, 256));
261 for (
const auto &domain : domains)
264 if (use_search_as_split_domains)
267 server.domains.push_back({domain});
276 else if (type ==
"ADAPTER_DOMAIN_SUFFIX")
281 adapter_domain_suffix = o.
ref(2);
286 catch (
const std::exception &e)
293 if (!adapter_domain_suffix.empty())
298 if (!ignore_values &&
servers.size() &&
servers[0].addresses.empty())
301 parse_errors +=
"dns server does not have an address assigned";