mirror of
https://github.com/oxen-io/lokinet
synced 2023-12-14 06:53:00 +01:00
ReconfigureDNS fixes, fixes macos exit mode
- ReconfigureDNS wasn't returning the old servers; made it void instead (the Apple code can just store a copy of the original upstream servers instead). - Reconfiguring DNS reset the unbound context but didn't replace it, so a Down()/Up() would crash. - Simplify Resolver() destructor to just call Down(), and make it final just so that no one tries to inherit from us (so that calling a virtual function from the destructor is safe). - Rename CancelPendingQueries() to Down(); the former cancelled but also shut down the object, so the name seemed a bit misleading. - Rename SetInternalState in Resolver_Base to ResetResolver, so that we aren't conflicting with ResetInternalState from Endpoint (which was a problem because TunEndpoint inherited from both; it could be resolved through the different argument type if we removed the default, but that seems gross). - Make Resolver use a bare unbound context pointer rather than a shared_ptr; since Resolver (now) entirely manages it already we don't need an extra management layer, and it saves a bunch of `.get()`s.
This commit is contained in:
parent
2ccc518849
commit
ec91a6db05
|
@ -31,10 +31,10 @@ namespace llarp::apple
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enable)
|
if (enable)
|
||||||
saved_upstream_dns =
|
tun->ReconfigureDNS({SockAddr{127, 0, 0, 1, {dns_trampoline_port}}});
|
||||||
tun->ReconfigureDNS({SockAddr{127, 0, 0, 1, huint16_t{dns_trampoline_port}}});
|
|
||||||
else
|
else
|
||||||
tun->ReconfigureDNS(std::move(saved_upstream_dns));
|
tun->ReconfigureDNS(router->GetConfig()->dns.m_upstreamDNS);
|
||||||
|
|
||||||
trampoline_active = enable;
|
trampoline_active = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,6 @@ namespace llarp::apple
|
||||||
private:
|
private:
|
||||||
llarp::Context& context;
|
llarp::Context& context;
|
||||||
bool trampoline_active = false;
|
bool trampoline_active = false;
|
||||||
std::vector<llarp::SockAddr> saved_upstream_dns;
|
|
||||||
void
|
void
|
||||||
check_trampoline(bool enable);
|
check_trampoline(bool enable);
|
||||||
|
|
||||||
|
|
|
@ -113,9 +113,9 @@ namespace llarp::dns
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Resolver_Base that uses libunbound
|
/// Resolver_Base that uses libunbound
|
||||||
class Resolver : public Resolver_Base, public std::enable_shared_from_this<Resolver>
|
class Resolver final : public Resolver_Base, public std::enable_shared_from_this<Resolver>
|
||||||
{
|
{
|
||||||
std::shared_ptr<ub_ctx> m_ctx;
|
ub_ctx* m_ctx = nullptr;
|
||||||
std::weak_ptr<EventLoop> m_Loop;
|
std::weak_ptr<EventLoop> m_Loop;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
// windows is dumb so we do ub mainloop in a thread
|
// windows is dumb so we do ub mainloop in a thread
|
||||||
|
@ -179,7 +179,7 @@ namespace llarp::dns
|
||||||
if (const auto port = dns.getPort(); port != 53)
|
if (const auto port = dns.getPort(); port != 53)
|
||||||
fmt::format_to(std::back_inserter(str), "@{}", port);
|
fmt::format_to(std::back_inserter(str), "@{}", port);
|
||||||
|
|
||||||
if (auto err = ub_ctx_set_fwd(m_ctx.get(), str.c_str()))
|
if (auto err = ub_ctx_set_fwd(m_ctx, str.c_str()))
|
||||||
{
|
{
|
||||||
throw std::runtime_error{
|
throw std::runtime_error{
|
||||||
fmt::format("cannot use {} as upstream dns: {}", str, ub_strerror(err))};
|
fmt::format("cannot use {} as upstream dns: {}", str, ub_strerror(err))};
|
||||||
|
@ -300,7 +300,7 @@ namespace llarp::dns
|
||||||
void
|
void
|
||||||
SetOpt(const std::string& key, const std::string& val)
|
SetOpt(const std::string& key, const std::string& val)
|
||||||
{
|
{
|
||||||
ub_ctx_set_option(m_ctx.get(), key.c_str(), val.c_str());
|
ub_ctx_set_option(m_ctx, key.c_str(), val.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wrapper around the above that takes 3+ arguments: the 2nd arg gets formatted with the
|
// Wrapper around the above that takes 3+ arguments: the 2nd arg gets formatted with the
|
||||||
|
@ -312,24 +312,21 @@ namespace llarp::dns
|
||||||
SetOpt(key, fmt::format(format, std::forward<FmtArgs>(args)...));
|
SetOpt(key, fmt::format(format, std::forward<FmtArgs>(args)...));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Copy of the DNS config (a copy because on some platforms, like Apple, we change the applied
|
||||||
|
// upstream DNS settings when turning on/off exit mode).
|
||||||
llarp::DnsConfig m_conf;
|
llarp::DnsConfig m_conf;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Resolver(const EventLoop_ptr& loop, llarp::DnsConfig conf)
|
explicit Resolver(const EventLoop_ptr& loop, llarp::DnsConfig conf)
|
||||||
: m_ctx{::ub_ctx_create(), ::ub_ctx_delete}, m_Loop{loop}, m_conf{std::move(conf)}
|
: m_Loop{loop}, m_conf{std::move(conf)}
|
||||||
{
|
{
|
||||||
Up(m_conf);
|
Up(m_conf);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
~Resolver() override
|
||||||
virtual ~Resolver()
|
|
||||||
{
|
{
|
||||||
running = false;
|
Down();
|
||||||
runner.join();
|
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
virtual ~Resolver() = default;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
std::string_view
|
std::string_view
|
||||||
ResolverName() const override
|
ResolverName() const override
|
||||||
|
@ -346,6 +343,10 @@ namespace llarp::dns
|
||||||
void
|
void
|
||||||
Up(const llarp::DnsConfig& conf)
|
Up(const llarp::DnsConfig& conf)
|
||||||
{
|
{
|
||||||
|
if (m_ctx)
|
||||||
|
throw std::logic_error{"Internal error: attempt to Up() dns server multiple times"};
|
||||||
|
|
||||||
|
m_ctx = ::ub_ctx_create();
|
||||||
// set libunbound settings
|
// set libunbound settings
|
||||||
|
|
||||||
SetOpt("do-tcp:", "no");
|
SetOpt("do-tcp:", "no");
|
||||||
|
@ -357,7 +358,7 @@ namespace llarp::dns
|
||||||
for (const auto& file : conf.m_hostfiles)
|
for (const auto& file : conf.m_hostfiles)
|
||||||
{
|
{
|
||||||
const auto str = file.u8string();
|
const auto str = file.u8string();
|
||||||
if (auto ret = ub_ctx_hosts(m_ctx.get(), str.c_str()))
|
if (auto ret = ub_ctx_hosts(m_ctx, str.c_str()))
|
||||||
{
|
{
|
||||||
throw std::runtime_error{
|
throw std::runtime_error{
|
||||||
fmt::format("Failed to add host file {}: {}", file, ub_strerror(ret))};
|
fmt::format("Failed to add host file {}: {}", file, ub_strerror(ret))};
|
||||||
|
@ -367,15 +368,14 @@ namespace llarp::dns
|
||||||
ConfigureUpstream(conf);
|
ConfigureUpstream(conf);
|
||||||
|
|
||||||
// set async
|
// set async
|
||||||
ub_ctx_async(m_ctx.get(), 1);
|
ub_ctx_async(m_ctx, 1);
|
||||||
// setup mainloop
|
// setup mainloop
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
running = true;
|
running = true;
|
||||||
runner = std::thread{[this, ctx = std::weak_ptr{m_ctx}]() {
|
runner = std::thread{[this]() {
|
||||||
while (running)
|
while (running)
|
||||||
{
|
{
|
||||||
if (auto c = ctx.lock())
|
ub_wait(ctx);
|
||||||
ub_wait(c.get());
|
|
||||||
std::this_thread::sleep_for(10ms);
|
std::this_thread::sleep_for(10ms);
|
||||||
}
|
}
|
||||||
if (auto c = ctx.lock())
|
if (auto c = ctx.lock())
|
||||||
|
@ -386,10 +386,9 @@ namespace llarp::dns
|
||||||
{
|
{
|
||||||
if (auto loop_ptr = loop->MaybeGetUVWLoop())
|
if (auto loop_ptr = loop->MaybeGetUVWLoop())
|
||||||
{
|
{
|
||||||
m_Poller = loop_ptr->resource<uvw::PollHandle>(ub_fd(m_ctx.get()));
|
m_Poller = loop_ptr->resource<uvw::PollHandle>(ub_fd(m_ctx));
|
||||||
m_Poller->on<uvw::PollEvent>([ptr = std::weak_ptr{m_ctx}](auto&, auto&) {
|
m_Poller->on<uvw::PollEvent>([this](auto&, auto&) {
|
||||||
if (auto ctx = ptr.lock())
|
ub_process(m_ctx);
|
||||||
ub_process(ctx.get());
|
|
||||||
});
|
});
|
||||||
m_Poller->start(uvw::PollHandle::Event::READABLE);
|
m_Poller->start(uvw::PollHandle::Event::READABLE);
|
||||||
return;
|
return;
|
||||||
|
@ -400,15 +399,19 @@ namespace llarp::dns
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Down()
|
Down() override
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
running = false;
|
if (running.exchange(false))
|
||||||
runner.join();
|
runner.join();
|
||||||
#else
|
#else
|
||||||
m_Poller->close();
|
if (m_Poller)
|
||||||
|
m_Poller->close();
|
||||||
#endif
|
#endif
|
||||||
m_ctx.reset();
|
if (m_ctx) {
|
||||||
|
::ub_ctx_delete(m_ctx);
|
||||||
|
m_ctx = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -418,20 +421,14 @@ namespace llarp::dns
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ResetInternalState(std::optional<std::vector<SockAddr>> replace_upstream) override
|
ResetResolver(std::optional<std::vector<SockAddr>> replace_upstream) override
|
||||||
{
|
{
|
||||||
Down();
|
Down();
|
||||||
if (replace_upstream)
|
if (replace_upstream)
|
||||||
m_conf.m_upstreamDNS = *replace_upstream;
|
m_conf.m_upstreamDNS = std::move(*replace_upstream);
|
||||||
Up(m_conf);
|
Up(m_conf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
CancelPendingQueries() override
|
|
||||||
{
|
|
||||||
Down();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
WouldLoop(const SockAddr& to, const SockAddr& from) const override
|
WouldLoop(const SockAddr& to, const SockAddr& from) const override
|
||||||
{
|
{
|
||||||
|
@ -485,7 +482,7 @@ namespace llarp::dns
|
||||||
}
|
}
|
||||||
const auto& q = query.questions[0];
|
const auto& q = query.questions[0];
|
||||||
if (auto err = ub_resolve_async(
|
if (auto err = ub_resolve_async(
|
||||||
m_ctx.get(),
|
m_ctx,
|
||||||
q.Name().c_str(),
|
q.Name().c_str(),
|
||||||
q.qtype,
|
q.qtype,
|
||||||
q.qclass,
|
q.qclass,
|
||||||
|
@ -642,7 +639,7 @@ namespace llarp::dns
|
||||||
for (const auto& resolver : m_Resolvers)
|
for (const auto& resolver : m_Resolvers)
|
||||||
{
|
{
|
||||||
if (auto ptr = resolver.lock())
|
if (auto ptr = resolver.lock())
|
||||||
ptr->CancelPendingQueries();
|
ptr->Down();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -652,7 +649,7 @@ namespace llarp::dns
|
||||||
for (const auto& resolver : m_Resolvers)
|
for (const auto& resolver : m_Resolvers)
|
||||||
{
|
{
|
||||||
if (auto ptr = resolver.lock())
|
if (auto ptr = resolver.lock())
|
||||||
ptr->ResetInternalState();
|
ptr->ResetResolver();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -174,16 +174,17 @@ namespace llarp::dns
|
||||||
virtual std::string_view
|
virtual std::string_view
|
||||||
ResolverName() const = 0;
|
ResolverName() const = 0;
|
||||||
|
|
||||||
/// reset state, replace upstream info with new info if desired
|
/// reset the resolver state, optionally replace upstream info with new info. The default base
|
||||||
|
/// implementation does nothing.
|
||||||
virtual void
|
virtual void
|
||||||
ResetInternalState(std::optional<std::vector<SockAddr>> replace_upstream = std::nullopt)
|
ResetResolver([[maybe_unused]] std::optional<std::vector<SockAddr>> replace_upstream = std::nullopt)
|
||||||
{
|
{
|
||||||
(void)replace_upstream;
|
}
|
||||||
};
|
|
||||||
|
|
||||||
/// cancel all pending requests and ceace further operation
|
/// cancel all pending requests and cease further operation. Default operation is a no-op.
|
||||||
virtual void
|
virtual void
|
||||||
CancelPendingQueries(){};
|
Down(){}
|
||||||
|
|
||||||
/// attempt to handle a dns message
|
/// attempt to handle a dns message
|
||||||
/// returns true if we consumed this query and it should not be processed again
|
/// returns true if we consumed this query and it should not be processed again
|
||||||
virtual bool
|
virtual bool
|
||||||
|
@ -201,7 +202,7 @@ namespace llarp::dns
|
||||||
(void)to;
|
(void)to;
|
||||||
(void)from;
|
(void)from;
|
||||||
return false;
|
return false;
|
||||||
};
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Base class for DNS proxy
|
// Base class for DNS proxy
|
||||||
|
|
|
@ -24,9 +24,6 @@ namespace llarp
|
||||||
return "snode";
|
return "snode";
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
CancelPendingQueries() override{};
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
MaybeHookDNS(
|
MaybeHookDNS(
|
||||||
std::shared_ptr<dns::PacketSource_Base> source,
|
std::shared_ptr<dns::PacketSource_Base> source,
|
||||||
|
|
|
@ -260,7 +260,7 @@ namespace llarp
|
||||||
m_DNS->Reset();
|
m_DNS->Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<SockAddr>
|
void
|
||||||
TunEndpoint::ReconfigureDNS(std::vector<SockAddr> servers)
|
TunEndpoint::ReconfigureDNS(std::vector<SockAddr> servers)
|
||||||
{
|
{
|
||||||
if (m_DNS)
|
if (m_DNS)
|
||||||
|
@ -268,10 +268,9 @@ namespace llarp
|
||||||
for (auto weak : m_DNS->GetAllResolvers())
|
for (auto weak : m_DNS->GetAllResolvers())
|
||||||
{
|
{
|
||||||
if (auto ptr = weak.lock())
|
if (auto ptr = weak.lock())
|
||||||
ptr->ResetInternalState(servers);
|
ptr->ResetResolver(servers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return servers;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -903,7 +902,7 @@ namespace llarp
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TunEndpoint::ResetInternalState(std::optional<std::vector<SockAddr>>)
|
void TunEndpoint::ResetInternalState()
|
||||||
{
|
{
|
||||||
service::Endpoint::ResetInternalState();
|
service::Endpoint::ResetInternalState();
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,9 +67,8 @@ namespace llarp
|
||||||
void
|
void
|
||||||
Thaw() override;
|
Thaw() override;
|
||||||
|
|
||||||
// Reconfigures DNS servers and restarts libunbound with the new servers. Returns the old set
|
// Reconfigures DNS servers and restarts libunbound with the new servers.
|
||||||
// of configured dns servers.
|
void
|
||||||
std::vector<SockAddr>
|
|
||||||
ReconfigureDNS(std::vector<SockAddr> servers);
|
ReconfigureDNS(std::vector<SockAddr> servers);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -202,8 +201,7 @@ namespace llarp
|
||||||
ObtainIPForAddr(std::variant<service::Address, RouterID> addr) override;
|
ObtainIPForAddr(std::variant<service::Address, RouterID> addr) override;
|
||||||
|
|
||||||
void
|
void
|
||||||
ResetInternalState(
|
ResetInternalState() override;
|
||||||
std::optional<std::vector<SockAddr>> replace_upstream = std::nullopt) override;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
struct WritePacket
|
struct WritePacket
|
||||||
|
|
Loading…
Reference in a new issue