diff --git a/llarp/config/config.cpp b/llarp/config/config.cpp index f3f1a0833..46a1c5942 100644 --- a/llarp/config/config.cpp +++ b/llarp/config/config.cpp @@ -355,23 +355,32 @@ namespace llarp DnsConfig::defineConfigOptions(ConfigDefinition& conf, const ConfigGenParameters& params) { (void)params; - auto parseDNSAddr = [](auto arg) { - IpAddress addr{arg}; - if (not addr.getPort()) - addr.setPort(53); - return addr; - }; - constexpr auto DefaultUpstreamDNS = "1.1.1.1:53"; + // Default, but if we get any upstream (including upstream=, i.e. empty string) we clear it + constexpr auto DefaultUpstreamDNS = "1.1.1.1"; + m_upstreamDNS.emplace_back(DefaultUpstreamDNS); conf.defineOption( - "dns", "upstream", false, true, DefaultUpstreamDNS, [=](std::string arg) { + "dns", "upstream", false, true, DefaultUpstreamDNS, [=, first=true](std::string arg) mutable { + if (first) + { + m_upstreamDNS.clear(); + first = false; + } if (!arg.empty()) - m_upstreamDNS.push_back(parseDNSAddr(std::move(arg))); + { + auto& addr = m_upstreamDNS.emplace_back(std::move(arg)); + if (auto p = addr.getPort(); p && *p != 53) + // unbound doesn't support specifying a port, so bail if the user gave a non-default port + throw std::invalid_argument(stringify("Invalid [dns] upstream setting: non-default DNS ports are not supported")); + addr.setPort(std::nullopt); + } }); conf.defineOption("dns", "bind", false, "127.3.2.1:53", [=](std::string arg) { - m_bind = parseDNSAddr(std::move(arg)); + m_bind = IpAddress{std::move(arg)}; + if (!m_bind.getPort()) + m_bind.setPort(53); }); // Ignored option (used by the systemd service file to disable resolvconf configuration).