mirror of https://github.com/oxen-io/lokinet
Merge pull request #1656 from majestrate/issue-1655-2021-05-30
DNS fixes and features
This commit is contained in:
commit
5da3bb6c0a
|
@ -729,12 +729,9 @@ namespace llarp
|
|||
}
|
||||
if (!arg.empty())
|
||||
{
|
||||
auto& addr = m_upstreamDNS.emplace_back(std::move(arg));
|
||||
if (auto p = addr.getPort(); p && *p != 53)
|
||||
// unbound doesn't support non-default ports so bail if the user gave one
|
||||
throw std::invalid_argument(
|
||||
"Invalid [dns] upstream setting: non-default DNS ports are not supported");
|
||||
addr.setPort(std::nullopt);
|
||||
auto& entry = m_upstreamDNS.emplace_back(std::move(arg));
|
||||
if (!entry.getPort())
|
||||
entry.setPort(53);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -746,11 +743,25 @@ namespace llarp
|
|||
"Address to bind to for handling DNS requests.",
|
||||
},
|
||||
[=](std::string arg) {
|
||||
m_bind = IpAddress{std::move(arg)};
|
||||
m_bind = SockAddr{std::move(arg)};
|
||||
if (!m_bind.getPort())
|
||||
m_bind.setPort(53);
|
||||
});
|
||||
|
||||
conf.defineOption<fs::path>(
|
||||
"dns",
|
||||
"add-hosts",
|
||||
ClientOnly,
|
||||
Comment{"Add a hosts file to the dns resolver", "For use with client side dns filtering"},
|
||||
[=](fs::path path) {
|
||||
if (path.empty())
|
||||
return;
|
||||
if (not fs::exists(path))
|
||||
throw std::invalid_argument{
|
||||
stringify("cannot add hosts file ", path, " as it does not seem to exist")};
|
||||
m_hostfiles.emplace_back(std::move(path));
|
||||
});
|
||||
|
||||
// Ignored option (used by the systemd service file to disable resolvconf configuration).
|
||||
conf.defineOption<bool>(
|
||||
"dns",
|
||||
|
|
|
@ -135,8 +135,9 @@ namespace llarp
|
|||
|
||||
struct DnsConfig
|
||||
{
|
||||
IpAddress m_bind;
|
||||
std::vector<IpAddress> m_upstreamDNS;
|
||||
SockAddr m_bind;
|
||||
std::vector<SockAddr> m_upstreamDNS;
|
||||
std::vector<fs::path> m_hostfiles;
|
||||
|
||||
void
|
||||
defineConfigOptions(ConfigDefinition& conf, const ConfigGenParameters& params);
|
||||
|
|
|
@ -26,9 +26,9 @@ namespace llarp::dns
|
|||
}
|
||||
|
||||
bool
|
||||
Proxy::Start(SockAddr addr, std::vector<IpAddress> resolvers)
|
||||
Proxy::Start(SockAddr addr, std::vector<SockAddr> resolvers, std::vector<fs::path> hostfiles)
|
||||
{
|
||||
if (not PacketHandler::Start(addr, std::move(resolvers)))
|
||||
if (not PacketHandler::Start(addr, std::move(resolvers), std::move(hostfiles)))
|
||||
return false;
|
||||
return m_Server->listen(addr);
|
||||
}
|
||||
|
@ -44,14 +44,19 @@ namespace llarp::dns
|
|||
}
|
||||
|
||||
bool
|
||||
PacketHandler::Start(SockAddr, std::vector<IpAddress> resolvers)
|
||||
PacketHandler::Start(SockAddr, std::vector<SockAddr> resolvers, std::vector<fs::path> hostfiles)
|
||||
{
|
||||
return SetupUnboundResolver(std::move(resolvers));
|
||||
return SetupUnboundResolver(std::move(resolvers), std::move(hostfiles));
|
||||
}
|
||||
|
||||
bool
|
||||
PacketHandler::SetupUnboundResolver(std::vector<IpAddress> resolvers)
|
||||
PacketHandler::SetupUnboundResolver(
|
||||
std::vector<SockAddr> resolvers, std::vector<fs::path> hostfiles)
|
||||
{
|
||||
// if we have no resolvers don't set up unbound
|
||||
if (resolvers.empty())
|
||||
return true;
|
||||
|
||||
auto failFunc = [self = weak_from_this()](
|
||||
const SockAddr& from, const SockAddr& to, Message msg) {
|
||||
if (auto this_ptr = self.lock())
|
||||
|
@ -73,14 +78,18 @@ namespace llarp::dns
|
|||
}
|
||||
for (const auto& resolver : resolvers)
|
||||
{
|
||||
if (not m_UnboundResolver->AddUpstreamResolver(resolver.toHost()))
|
||||
if (not m_UnboundResolver->AddUpstreamResolver(resolver))
|
||||
{
|
||||
llarp::LogError("Failed to add upstream DNS server: ", resolver.toHost());
|
||||
llarp::LogError("Failed to add upstream DNS server: ", resolver);
|
||||
m_UnboundResolver = nullptr;
|
||||
return false;
|
||||
}
|
||||
m_Resolvers.emplace(resolver);
|
||||
}
|
||||
for (const auto& path : hostfiles)
|
||||
{
|
||||
m_UnboundResolver->AddHostsFile(path);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -35,7 +35,10 @@ namespace llarp
|
|||
virtual ~PacketHandler() = default;
|
||||
|
||||
virtual bool
|
||||
Start(SockAddr localaddr, std::vector<IpAddress> upstreamResolvers);
|
||||
Start(
|
||||
SockAddr localaddr,
|
||||
std::vector<SockAddr> upstreamResolvers,
|
||||
std::vector<fs::path> hostfiles);
|
||||
|
||||
void
|
||||
Stop();
|
||||
|
@ -58,10 +61,10 @@ namespace llarp
|
|||
HandleUpstreamFailure(const SockAddr& from, const SockAddr& to, Message msg);
|
||||
|
||||
bool
|
||||
SetupUnboundResolver(std::vector<IpAddress> resolvers);
|
||||
SetupUnboundResolver(std::vector<SockAddr> resolvers, std::vector<fs::path> hostfiles);
|
||||
|
||||
IQueryHandler* const m_QueryHandler;
|
||||
std::set<IpAddress> m_Resolvers;
|
||||
std::set<SockAddr> m_Resolvers;
|
||||
std::shared_ptr<UnboundResolver> m_UnboundResolver;
|
||||
EventLoop_ptr m_Loop;
|
||||
};
|
||||
|
@ -73,7 +76,10 @@ namespace llarp
|
|||
explicit Proxy(EventLoop_ptr loop, IQueryHandler* handler);
|
||||
|
||||
bool
|
||||
Start(SockAddr localaddr, std::vector<IpAddress> resolvers) override;
|
||||
Start(
|
||||
SockAddr localaddr,
|
||||
std::vector<SockAddr> upstreamResolvers,
|
||||
std::vector<fs::path> hostfiles) override;
|
||||
|
||||
protected:
|
||||
void
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
#include "server.hpp"
|
||||
#include <llarp/util/buffer.hpp>
|
||||
#include <sstream>
|
||||
#include <llarp/util/str.hpp>
|
||||
|
||||
namespace llarp::dns
|
||||
{
|
||||
|
@ -105,9 +107,16 @@ namespace llarp::dns
|
|||
}
|
||||
|
||||
bool
|
||||
UnboundResolver::AddUpstreamResolver(const std::string& upstreamResolverIP)
|
||||
UnboundResolver::AddUpstreamResolver(const SockAddr& upstreamResolver)
|
||||
{
|
||||
if (ub_ctx_set_fwd(unboundContext, upstreamResolverIP.c_str()) != 0)
|
||||
std::stringstream ss;
|
||||
ss << upstreamResolver.hostString();
|
||||
|
||||
if (const auto port = upstreamResolver.getPort(); port != 53)
|
||||
ss << "@" << port;
|
||||
|
||||
const auto str = ss.str();
|
||||
if (ub_ctx_set_fwd(unboundContext, str.c_str()) != 0)
|
||||
{
|
||||
Reset();
|
||||
return false;
|
||||
|
@ -115,6 +124,21 @@ namespace llarp::dns
|
|||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
UnboundResolver::AddHostsFile(const fs::path& file)
|
||||
{
|
||||
LogDebug("adding hosts file ", file);
|
||||
const auto str = file.u8string();
|
||||
if (auto ret = ub_ctx_hosts(unboundContext, str.c_str()))
|
||||
{
|
||||
throw std::runtime_error{stringify("Failed to add host file ", file, ": ", ub_strerror(ret))};
|
||||
}
|
||||
else
|
||||
{
|
||||
LogInfo("added hosts file ", file);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
UnboundResolver::Lookup(SockAddr to, SockAddr from, Message msg)
|
||||
{
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <queue>
|
||||
|
||||
#include <llarp/ev/ev.hpp>
|
||||
#include <llarp/util/fs.hpp>
|
||||
|
||||
#include "message.hpp"
|
||||
|
||||
|
@ -50,7 +51,10 @@ namespace llarp::dns
|
|||
Init();
|
||||
|
||||
bool
|
||||
AddUpstreamResolver(const std::string& upstreamResolverIP);
|
||||
AddUpstreamResolver(const SockAddr& upstreamResolverIP);
|
||||
|
||||
void
|
||||
AddHostsFile(const fs::path& file);
|
||||
|
||||
void
|
||||
Lookup(SockAddr to, SockAddr from, Message msg);
|
||||
|
|
|
@ -302,7 +302,7 @@ namespace llarp::uv
|
|||
handle->on<uvw::UDPDataEvent>([this](auto& event, auto& /*handle*/) {
|
||||
on_recv(
|
||||
*this,
|
||||
SockAddr{event.sender.ip, static_cast<uint16_t>(event.sender.port)},
|
||||
SockAddr{event.sender.ip, huint16_t{static_cast<uint16_t>(event.sender.port)}},
|
||||
OwnedBuffer{std::move(event.data), event.length});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace llarp
|
|||
: m_Router(r)
|
||||
, m_Resolver(std::make_shared<dns::Proxy>(r->loop(), this))
|
||||
, m_Name(std::move(name))
|
||||
, m_LocalResolverAddr("127.0.0.1", 53)
|
||||
, m_LocalResolverAddr{"127.0.0.1:53"}
|
||||
, m_QUIC{std::make_shared<quic::TunnelManager>(*this)}
|
||||
, m_InetToNetwork(name + "_exit_rx", r->loop(), r->loop())
|
||||
|
||||
|
@ -476,8 +476,8 @@ namespace llarp
|
|||
|
||||
GetRouter()->loop()->add_ticker([this] { Flush(); });
|
||||
|
||||
llarp::LogInfo("Trying to start resolver ", m_LocalResolverAddr.toString());
|
||||
return m_Resolver->Start(m_LocalResolverAddr.createSockAddr(), m_UpstreamResolvers);
|
||||
llarp::LogInfo("Trying to start resolver ", m_LocalResolverAddr);
|
||||
return m_Resolver->Start(m_LocalResolverAddr, m_UpstreamResolvers, {});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -211,8 +211,8 @@ namespace llarp
|
|||
|
||||
std::shared_ptr<vpn::NetworkInterface> m_NetIf;
|
||||
|
||||
IpAddress m_LocalResolverAddr;
|
||||
std::vector<IpAddress> m_UpstreamResolvers;
|
||||
SockAddr m_LocalResolverAddr;
|
||||
std::vector<SockAddr> m_UpstreamResolvers;
|
||||
|
||||
std::shared_ptr<quic::TunnelManager> m_QUIC;
|
||||
|
||||
|
|
|
@ -169,6 +169,7 @@ namespace llarp
|
|||
|
||||
m_LocalResolverAddr = dnsConf.m_bind;
|
||||
m_UpstreamResolvers = dnsConf.m_upstreamDNS;
|
||||
m_hostfiles = dnsConf.m_hostfiles;
|
||||
|
||||
m_BaseV6Address = conf.m_baseV6Address;
|
||||
|
||||
|
@ -945,7 +946,8 @@ namespace llarp
|
|||
llarp::LogError(Name(), " failed to set up network interface");
|
||||
return false;
|
||||
}
|
||||
if (!m_Resolver->Start(m_LocalResolverAddr.createSockAddr(), m_UpstreamResolvers))
|
||||
if (!m_Resolver->Start(
|
||||
m_LocalResolverAddr.createSockAddr(), m_UpstreamResolvers, m_hostfiles))
|
||||
{
|
||||
llarp::LogError(Name(), " failed to start DNS server");
|
||||
return false;
|
||||
|
|
|
@ -265,7 +265,9 @@ namespace llarp
|
|||
/// our ip range we are using
|
||||
llarp::IPRange m_OurRange;
|
||||
/// upstream dns resolver list
|
||||
std::vector<IpAddress> m_UpstreamResolvers;
|
||||
std::vector<SockAddr> m_UpstreamResolvers;
|
||||
/// dns host files list
|
||||
std::vector<fs::path> m_hostfiles;
|
||||
/// local dns
|
||||
IpAddress m_LocalResolverAddr;
|
||||
/// list of strict connect addresses for hooks
|
||||
|
|
|
@ -75,10 +75,10 @@ namespace llarp
|
|||
init();
|
||||
fromString(addr);
|
||||
}
|
||||
SockAddr::SockAddr(std::string_view addr, uint16_t port)
|
||||
SockAddr::SockAddr(std::string_view addr, huint16_t port)
|
||||
{
|
||||
init();
|
||||
setPort(huint16_t{port});
|
||||
setPort(port);
|
||||
fromString(addr, false);
|
||||
}
|
||||
|
||||
|
@ -289,7 +289,15 @@ namespace llarp
|
|||
// TODO: review
|
||||
if (isEmpty())
|
||||
return "";
|
||||
std::string str = hostString();
|
||||
str.append(1, ':');
|
||||
str.append(std::to_string(getPort()));
|
||||
return str;
|
||||
}
|
||||
|
||||
std::string
|
||||
SockAddr::hostString() const
|
||||
{
|
||||
std::string str;
|
||||
|
||||
if (isIPv4())
|
||||
|
@ -313,9 +321,6 @@ namespace llarp
|
|||
str.append(buf);
|
||||
str.append("]");
|
||||
}
|
||||
|
||||
str.append(1, ':');
|
||||
str.append(std::to_string(getPort()));
|
||||
return str;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace llarp
|
|||
|
||||
// String ctors
|
||||
SockAddr(std::string_view addr);
|
||||
SockAddr(std::string_view addr, uint16_t port); // port is in native (host) order
|
||||
SockAddr(std::string_view addr, huint16_t port); // port is in native (host) order
|
||||
|
||||
SockAddr(const AddressInfo&);
|
||||
|
||||
|
@ -83,6 +83,9 @@ namespace llarp
|
|||
std::string
|
||||
toString() const;
|
||||
|
||||
std::string
|
||||
hostString() const;
|
||||
|
||||
/// Returns true if this is an empty SockAddr, defined by having no IP address set. An empty IP
|
||||
/// address with a valid port is still considered empty.
|
||||
///
|
||||
|
|
|
@ -485,7 +485,7 @@ namespace llarp::quic
|
|||
}
|
||||
|
||||
auto bound = tcp_tunnel->sock();
|
||||
saddr = SockAddr{bound.ip, static_cast<uint16_t>(bound.port)};
|
||||
saddr = SockAddr{bound.ip, huint16_t{static_cast<uint16_t>(bound.port)}};
|
||||
|
||||
// Find the first unused psuedo-port value starting from next_pseudo_port_.
|
||||
if (auto p = find_unused_key(client_tunnels_, next_pseudo_port_))
|
||||
|
|
|
@ -163,7 +163,7 @@ namespace llarp
|
|||
|
||||
systemd_resolved_set_dns(
|
||||
m_Router->hiddenServiceContext().GetDefault()->GetIfName(),
|
||||
m_Router->GetConfig()->dns.m_bind.createSockAddr(),
|
||||
m_Router->GetConfig()->dns.m_bind,
|
||||
true /* route all DNS */);
|
||||
}
|
||||
|
||||
|
@ -178,7 +178,7 @@ namespace llarp
|
|||
|
||||
systemd_resolved_set_dns(
|
||||
m_Router->hiddenServiceContext().GetDefault()->GetIfName(),
|
||||
m_Router->GetConfig()->dns.m_bind.createSockAddr(),
|
||||
m_Router->GetConfig()->dns.m_bind,
|
||||
false /* route DNS only for .loki/.snode */);
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ TEST_CASE("SockAddr fromString", "[SockAddr]")
|
|||
CHECK(llarp::SockAddr("255.255.255.255").toString() == "255.255.255.255:0");
|
||||
CHECK(llarp::SockAddr("255.255.255.255:255").toString() == "255.255.255.255:255");
|
||||
CHECK(llarp::SockAddr("255.255.255.255:65535").toString() == "255.255.255.255:65535");
|
||||
CHECK(llarp::SockAddr("5.6.7.8", 5678).toString() == "5.6.7.8:5678");
|
||||
CHECK(llarp::SockAddr("5.6.7.8", llarp::huint16_t{5678}).toString() == "5.6.7.8:5678");
|
||||
|
||||
CHECK_THROWS_WITH(llarp::SockAddr("abcd"), "abcd is not a valid IPv4 address");
|
||||
|
||||
|
@ -66,7 +66,7 @@ TEST_CASE("SockAddr fromString", "[SockAddr]")
|
|||
|
||||
CHECK_THROWS_WITH(llarp::SockAddr("1.2.3.4:1a"), "1a is not a valid port");
|
||||
|
||||
CHECK_THROWS_WITH(llarp::SockAddr("5.6.7.8:1234", 5678), "invalid ip address (port not allowed here): 5.6.7.8:1234");
|
||||
CHECK_THROWS_WITH(llarp::SockAddr("5.6.7.8:1234", llarp::huint16_t{5678}), "invalid ip address (port not allowed here): 5.6.7.8:1234");
|
||||
}
|
||||
|
||||
TEST_CASE("SockAddr from sockaddr_in", "[SockAddr]")
|
||||
|
|
Loading…
Reference in New Issue