Restore Apple hax

pull/1969/head
Jason Rhinelander 2 years ago
parent de4bce1d96
commit ab2177bee9
No known key found for this signature in database
GPG Key ID: C4992CE7A88D4262

@ -1,5 +1,8 @@
#include "server.hpp"
#include <llarp/constants/platform.hpp>
#include <llarp/constants/apple.hpp>
#include "dns.hpp"
#include <iterator>
#include <llarp/crypto/crypto.hpp>
#include <array>
#include <stdexcept>
@ -228,19 +231,46 @@ namespace llarp::dns
// set up forward dns
for (const auto& dns : conf.m_upstreamDNS)
{
std::stringstream ss;
auto hoststr = dns.hostString();
ss << hoststr;
std::string str = dns.hostString();
if (const auto port = dns.getPort(); port != 53)
ss << "@" << port;
fmt::format_to(std::back_inserter(str), "@{}", port);
const auto str = ss.str();
if (auto err = ub_ctx_set_fwd(m_ctx.get(), str.c_str()))
auto* ctx = m_ctx.get();
if (auto err = ub_ctx_set_fwd(ctx, str.c_str()))
{
throw std::runtime_error{
fmt::format("cannot use {} as upstream dns: {}", str, ub_strerror(err))};
}
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 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.
if (dns.hostString() == "127.0.0.1" && dns.getPort() == apple::dns_trampoline_port)
{
// 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.
ub_ctx_set_option(ctx, "outgoing-interface:", "127.0.0.1");
// The trampoline expects just a single source port (and sends everything back to it)
ub_ctx_set_option(ctx, "outgoing-range:", "1");
ub_ctx_set_option(ctx, "outgoing-port-avoid:", "0-65535");
ub_ctx_set_option(
ctx,
"outgoing-port-permit:",
std::to_string(apple::dns_trampoline_source_port).c_str());
}
}
}
if (auto maybe_addr = conf.m_QueryBind)

Loading…
Cancel
Save