You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
lokinet/llarp/dns/server.cpp

136 lines
3.2 KiB
C++

6 years ago
#include <llarp/dns/server.hpp>
namespace llarp
{
namespace dns
{
Proxy::Proxy(llarp_ev_loop* loop, IQueryHandler* h)
: m_Loop(loop), m_QueryHandler(h)
{
m_UDP.user = this;
m_UDP.tick = &HandleTick;
m_UDP.recvfrom = &HandleUDPRecv;
}
void
Proxy::Stop()
{
}
bool
Proxy::Start(const llarp::Addr& addr,
const std::vector< llarp::Addr >& resolvers)
{
m_Resolvers.clear();
m_Resolvers = resolvers;
if(m_Resolvers.size() == 0)
{
llarp::LogError("no upstream dns provide specified");
return false;
}
return llarp_ev_add_udp(m_Loop, &m_UDP, addr) == 0;
}
void
Proxy::HandleUDPRecv(llarp_udp_io* u, const sockaddr* from,
llarp_buffer_t buf)
{
static_cast< Proxy* >(u->user)->HandlePkt(*from, &buf);
}
llarp::Addr
Proxy::PickRandomResolver() const
{
size_t sz = m_Resolvers.size();
if(sz == 0)
return llarp::Addr("1.1.1.1", 52);
if(sz == 1)
return m_Resolvers[0];
auto itr = m_Resolvers.begin();
std::advance(itr, llarp_randint() % sz);
return *itr;
}
void
Proxy::HandleTick(llarp_udp_io*)
{
}
void
Proxy::SendMessageTo(llarp::Addr to, Message msg)
{
byte_t tmp[1500] = {0};
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
if(msg.Encode(&buf))
{
buf.sz = buf.cur - buf.base;
buf.cur = buf.base;
llarp_ev_udp_sendto(&m_UDP, to, buf);
}
else
llarp::LogWarn("failed to encode dns message when sending");
}
void
Proxy::HandlePkt(llarp::Addr from, llarp_buffer_t* pkt)
{
MessageHeader hdr;
if(!hdr.Decode(pkt))
{
llarp::LogWarn("failed to parse dns header from ", from);
return;
}
TX tx = {hdr.id, from};
auto itr = m_Forwarded.find(tx);
if(itr != m_Forwarded.end())
{
llarp_buffer_t buf;
buf.sz = pkt->sz;
buf.base = pkt->base;
buf.cur = buf.base;
// forward
llarp_ev_udp_sendto(&m_UDP, itr->second, buf);
// remove pending
m_Forwarded.erase(itr);
return;
}
Message msg(hdr);
6 years ago
if(!msg.Decode(pkt))
{
llarp::LogWarn("failed to parse dns message from ", from);
6 years ago
return;
}
6 years ago
if(m_QueryHandler && m_QueryHandler->ShouldHookDNSMessage(msg))
{
if(!m_QueryHandler->HandleHookedDNSMessage(
std::move(msg),
6 years ago
std::bind(&Proxy::SendMessageTo, this, from,
std::placeholders::_1)))
{
llarp::LogWarn("failed to handle hooked dns");
}
return;
}
else if(itr == m_Forwarded.end())
6 years ago
{
// new forwarded query
tx.from = PickRandomResolver();
m_Forwarded[tx] = from;
llarp_buffer_t buf;
buf.sz = pkt->sz;
buf.base = pkt->base;
buf.cur = buf.base;
// do query
llarp_ev_udp_sendto(&m_UDP, tx.from, buf);
6 years ago
}
else
{
// drop (?)
6 years ago
}
}
} // namespace dns
} // namespace llarp