mirror of
https://github.com/oxen-io/lokinet
synced 2023-12-14 06:53:00 +01:00
Fix apple dns, part 817
This commit is contained in:
parent
bd09f7716d
commit
2ccc518849
2 changed files with 48 additions and 32 deletions
|
@ -828,9 +828,7 @@ namespace llarp
|
|||
conf.defineOption<std::string>(
|
||||
"dns",
|
||||
"query-bind",
|
||||
#ifdef __APPLE__
|
||||
Default{"127.0.0.1:1253"},
|
||||
#elif defined(_WIN32)
|
||||
#if defined(_WIN32)
|
||||
Default{"0.0.0.0:0"},
|
||||
#else
|
||||
Hidden,
|
||||
|
|
|
@ -186,43 +186,61 @@ namespace llarp::dns
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
ConfigureUpstream(const llarp::DnsConfig& conf)
|
||||
bool
|
||||
ConfigureAppleTrampoline(const SockAddr& dns)
|
||||
{
|
||||
// On Apple, when we turn on exit mode, we tear down and then reestablish the unbound
|
||||
// resolver: in exit mode, we set use upstream to a localhost trampoline that redirects
|
||||
// packets through the tunnel. In non-exit mode, we directly use the upstream, so we look
|
||||
// here for a reconfiguration to use the trampoline port to check which state we're in.
|
||||
//
|
||||
// We have to do all this crap because we can't directly connect to upstream from here:
|
||||
// within the network extension, macOS ignores the tunnel we are managing and so, if we
|
||||
// didn't do this, all our DNS queries would leak out around the tunnel. Instead we have to
|
||||
// bounce things through the objective C trampoline code (which is what actually handles the
|
||||
// upstream querying) so that it can call into Apple's special snowflake API to set up a
|
||||
// socket that has the magic Apple snowflake sauce added on top so that it actually routes
|
||||
// through the tunnel instead of around it.
|
||||
//
|
||||
// But the trampoline *always* tries to send the packet through the tunnel, and that will
|
||||
// only work in exit mode.
|
||||
//
|
||||
// All of this macos behaviour is all carefully and explicitly documented by Apple with
|
||||
// plenty of examples and other exposition, of course, just like all of their wonderful new
|
||||
// APIs to reinvent standard unix interfaces with half-baked replacements.
|
||||
|
||||
if constexpr (platform::is_apple)
|
||||
{
|
||||
// On Apple, when we turn on exit mode, we can't directly connect to upstream from here
|
||||
// because, from within the network extension, macOS ignores setting the tunnel as the
|
||||
// default route and would leak all DNS; instead we have to bounce things through the
|
||||
// objective C trampoline code (which is what actually handles the upstream querying) so
|
||||
// that it can call into Apple's special snowflake API to set up a socket that has the
|
||||
// magic Apple snowflake sauce added on top so that it actually routes through the tunnel
|
||||
// instead of around it.
|
||||
//
|
||||
// This behaviour is all carefully and explicitly documented by Apple with plenty of
|
||||
// examples and other exposition, of course, just like all of their wonderful new APIs to
|
||||
// reinvent standard unix interfaces.
|
||||
|
||||
// Not at all clear why this is needed but without it we get "send failed: Can't
|
||||
// assign requested address" when unbound tries to connect to the localhost address
|
||||
// using a source address of 0.0.0.0. Yay apple.
|
||||
if (dns.hostString() == "127.0.0.1" and dns.getPort() == apple::dns_trampoline_port)
|
||||
{
|
||||
// macOS is stupid: the default (0.0.0.0) fails with "send failed: Can't assign requested
|
||||
// address" when unbound tries to connect to the localhost address using a source address
|
||||
// of 0.0.0.0. Yay apple.
|
||||
SetOpt("outgoing-interface:", "127.0.0.1");
|
||||
|
||||
// The trampoline expects just a single source port (and sends everything back to it)
|
||||
// The trampoline expects just a single source port (and sends everything back to it).
|
||||
SetOpt("outgoing-range:", "1");
|
||||
SetOpt("outgoing-port-avoid:", "0-65535");
|
||||
SetOpt("outgoing-port-permit:", "{}", apple::dns_trampoline_source_port);
|
||||
|
||||
AddUpstreamResolver(SockAddr{127, 0, 0, 1, {apple::dns_trampoline_port}});
|
||||
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
ConfigureUpstream(const llarp::DnsConfig& conf)
|
||||
{
|
||||
bool is_apple_tramp = false;
|
||||
|
||||
// set up forward dns
|
||||
for (const auto& dns : conf.m_upstreamDNS)
|
||||
{
|
||||
AddUpstreamResolver(dns);
|
||||
is_apple_tramp = is_apple_tramp or ConfigureAppleTrampoline(dns);
|
||||
}
|
||||
|
||||
if (auto maybe_addr = conf.m_QueryBind)
|
||||
if (auto maybe_addr = conf.m_QueryBind; maybe_addr and not is_apple_tramp)
|
||||
{
|
||||
SockAddr addr{*maybe_addr};
|
||||
std::string host{addr.hostString()};
|
||||
|
|
Loading…
Reference in a new issue