Merge pull request #2076 from tewinget/more-verbose-logging

Fix Windows DNS issues
pull/2080/head
majestrate 1 year ago committed by GitHub
commit 2c6e2e9472
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -146,6 +146,7 @@ namespace llarp::dns
static void
Callback(void* data, int err, ub_result* _result)
{
log::debug(logcat, "got dns response from libunbound");
// take ownership of ub_result
std::unique_ptr<ub_result, ub_result_deleter> result{_result};
// borrow query
@ -158,6 +159,8 @@ namespace llarp::dns
return;
}
log::trace(logcat, "queueing dns response from libunbound to userland");
// rewrite response
OwnedBuffer pkt{(const byte_t*)result->answer_packet, (size_t)result->answer_len};
llarp_buffer_t buf{pkt};
@ -452,20 +455,6 @@ namespace llarp::dns
Up(m_conf);
}
bool
WouldLoop(const SockAddr& to, const SockAddr& from) const override
{
#if defined(ANDROID)
(void)to;
(void)from;
return false;
#else
const auto& vec = m_conf.m_upstreamDNS;
return std::find(vec.begin(), vec.end(), to) != std::end(vec)
or std::find(vec.begin(), vec.end(), from) != std::end(vec);
#endif
}
template <typename Callable>
void
call(Callable&& f)
@ -483,13 +472,15 @@ namespace llarp::dns
const SockAddr& to,
const SockAddr& from) override
{
if (WouldLoop(to, from))
return false;
auto tmp = std::make_shared<Query>(weak_from_this(), query, source, to, from);
// no questions, send fail
if (query.questions.empty())
{
log::info(
logcat,
"dns from {} to {} has empty query questions, sending failure reply",
from,
to);
tmp->Cancel();
return true;
}
@ -499,6 +490,12 @@ namespace llarp::dns
// dont process .loki or .snode
if (q.HasTLD(".loki") or q.HasTLD(".snode"))
{
log::warning(
logcat,
"dns from {} to {} is for .loki or .snode but got to the unbound resolver, sending "
"failure reply",
from,
to);
tmp->Cancel();
return true;
}
@ -506,6 +503,12 @@ namespace llarp::dns
if (not m_ctx)
{
// we are down
log::debug(
logcat,
"dns from {} to {} got to the unbound resolver, but the resolver isn't set up, "
"sending failure reply",
from,
to);
tmp->Cancel();
return true;
}
@ -514,6 +517,12 @@ namespace llarp::dns
if (not running)
{
// we are stopping the win32 thread
log::debug(
logcat,
"dns from {} to {} got to the unbound resolver, but the resolver isn't running, "
"sending failure reply",
from,
to);
tmp->Cancel();
return true;
}
@ -533,7 +542,10 @@ namespace llarp::dns
tmp->Cancel();
}
else
{
log::trace(logcat, "dns from {} to {} processing via libunbound", from, to);
m_Pending.insert(std::move(tmp));
}
return true;
}
@ -549,6 +561,12 @@ namespace llarp::dns
{
parent_ptr->call(
[self = shared_from_this(), parent_ptr = std::move(parent_ptr), buf = replyBuf.copy()] {
log::trace(
logcat,
"forwarding dns response from libunbound to userland (resolverAddr: {}, "
"askerAddr: {})",
self->resolverAddr,
self->askerAddr);
self->src->SendTo(self->askerAddr, self->resolverAddr, OwnedBuffer::copy_from(buf));
// remove query
parent_ptr->RemovePending(self);
@ -742,10 +760,14 @@ namespace llarp::dns
{
if (auto res_ptr = resolver.lock())
{
log::debug(
log::trace(
logcat, "check resolver {} for dns from {} to {}", res_ptr->ResolverName(), from, to);
if (res_ptr->MaybeHookDNS(ptr, msg, to, from))
{
log::trace(
logcat, "resolver {} handling dns from {} to {}", res_ptr->ResolverName(), from, to);
return true;
}
}
}
return false;

@ -197,16 +197,6 @@ namespace llarp::dns
const Message& query,
const SockAddr& to,
const SockAddr& from) = 0;
/// Returns true if a packet with to and from addresses is something that would cause a
/// resolution loop and thus should not be used on this resolver
virtual bool
WouldLoop(const SockAddr& to, const SockAddr& from) const
{
(void)to;
(void)from;
return false;
}
};
// Base class for DNS proxy

@ -12,6 +12,94 @@ extern "C"
#include <windivert.h>
}
namespace
{
using namespace oxen::log::literals;
std::string
windivert_addr_to_string(const WINDIVERT_ADDRESS& addr)
{
std::string layer_str{};
std::string ifidx_str{};
switch (addr.Layer)
{
case WINDIVERT_LAYER_NETWORK:
layer_str = "WINDIVERT_LAYER_NETWORK";
ifidx_str =
"Network: [IfIdx: {}, SubIfIdx: {}]"_format(addr.Network.IfIdx, addr.Network.SubIfIdx);
break;
case WINDIVERT_LAYER_NETWORK_FORWARD:
layer_str = "WINDIVERT_LAYER_NETWORK_FORWARD";
break;
case WINDIVERT_LAYER_FLOW:
layer_str = "WINDIVERT_LAYER_FLOW";
break;
case WINDIVERT_LAYER_SOCKET:
layer_str = "WINDIVERT_LAYER_SOCKET";
break;
case WINDIVERT_LAYER_REFLECT:
layer_str = "WINDIVERT_LAYER_REFLECT";
break;
default:
layer_str = "unknown";
}
std::string event_str{};
switch (addr.Event)
{
case WINDIVERT_EVENT_NETWORK_PACKET:
event_str = "WINDIVERT_EVENT_NETWORK_PACKET";
break;
case WINDIVERT_EVENT_FLOW_ESTABLISHED:
event_str = "WINDIVERT_EVENT_FLOW_ESTABLISHED";
break;
case WINDIVERT_EVENT_FLOW_DELETED:
event_str = "WINDIVERT_EVENT_FLOW_DELETED";
break;
case WINDIVERT_EVENT_SOCKET_BIND:
event_str = "WINDIVERT_EVENT_SOCKET_BIND";
break;
case WINDIVERT_EVENT_SOCKET_CONNECT:
event_str = "WINDIVERT_EVENT_SOCKET_CONNECT";
break;
case WINDIVERT_EVENT_SOCKET_LISTEN:
event_str = "WINDIVERT_EVENT_SOCKET_LISTEN";
break;
case WINDIVERT_EVENT_SOCKET_ACCEPT:
event_str = "WINDIVERT_EVENT_SOCKET_ACCEPT";
break;
case WINDIVERT_EVENT_SOCKET_CLOSE:
event_str = "WINDIVERT_EVENT_SOCKET_CLOSE";
break;
case WINDIVERT_EVENT_REFLECT_OPEN:
event_str = "WINDIVERT_EVENT_REFLECT_OPEN";
break;
case WINDIVERT_EVENT_REFLECT_CLOSE:
event_str = "WINDIVERT_EVENT_REFLECT_CLOSE";
break;
default:
event_str = "unknown";
}
return fmt::format(
"Windivert WINDIVERT_ADDRESS -- Timestamp: {}, Layer: {}, Event: {}, Sniffed: {}, "
"Outbound: {}, Loopback: {}, Imposter: {}, IPv6: {}, IPChecksum: {}, TCPChecksum: {}, "
"UDPChecksum: {}, {}",
addr.Timestamp,
layer_str,
event_str,
addr.Sniffed ? "true" : "false",
addr.Outbound ? "true" : "false",
addr.Loopback ? "true" : "false",
addr.Impostor ? "true" : "false",
addr.IPv6 ? "true" : "false",
addr.IPChecksum ? "true" : "false",
addr.TCPChecksum ? "true" : "false",
addr.UDPChecksum ? "true" : "false",
ifidx_str);
}
} // namespace
namespace llarp::win32
{
static auto logcat = log::Cat("windivert");
@ -23,6 +111,7 @@ namespace llarp::win32
decltype(::WinDivertOpen)* open = nullptr;
decltype(::WinDivertClose)* close = nullptr;
decltype(::WinDivertShutdown)* shutdown = nullptr;
decltype(::WinDivertHelperCalcChecksums)* calc_checksum = nullptr;
decltype(::WinDivertSend)* send = nullptr;
decltype(::WinDivertRecv)* recv = nullptr;
decltype(::WinDivertHelperFormatIPv4Address)* format_ip4 = nullptr;
@ -41,6 +130,7 @@ namespace llarp::win32
"WinDivertOpen", open,
"WinDivertClose", close,
"WinDivertShutdown", shutdown,
"WinDivertHelperCalcChecksums", calc_checksum,
"WinDivertSend", send,
"WinDivertRecv", recv,
"WinDivertHelperFormatIPv4Address", format_ip4,
@ -106,18 +196,28 @@ namespace llarp::win32
throw win32::error{
err, fmt::format("failed to receive packet from windivert (code={})", err)};
}
log::trace(logcat, "got packet of size {}B", sz);
pkt.resize(sz);
log::trace(logcat, "got packet of size {}B", sz);
log::trace(logcat, "{}", windivert_addr_to_string(addr));
return Packet{std::move(pkt), std::move(addr)};
}
void
send_packet(const Packet& w_pkt) const
send_packet(Packet w_pkt) const
{
const auto& pkt = w_pkt.pkt;
const auto* addr = &w_pkt.addr;
auto& pkt = w_pkt.pkt;
auto* addr = &w_pkt.addr;
addr->Outbound = !addr->Outbound; // re-used from recv, so invert direction
log::trace(logcat, "send dns packet of size {}B", pkt.size());
log::trace(logcat, "{}", windivert_addr_to_string(w_pkt.addr));
UINT sz{};
// recalc IP packet checksum in case it needs it
wd::calc_checksum(pkt.data(), pkt.size(), addr, 0);
if (!wd::send(m_Handle, pkt.data(), pkt.size(), &sz, addr))
throw win32::error{"windivert send failed"};
}

Loading…
Cancel
Save