lokinet/llarp/dns/server.cpp

162 lines
4.0 KiB
C++
Raw Normal View History

2018-12-12 00:58:08 +00:00
#include <dns/server.hpp>
2018-12-03 22:22:59 +00:00
#include <crypto/crypto.hpp>
2019-02-02 23:12:42 +00:00
#include <array>
2018-12-03 22:22:59 +00:00
namespace llarp
{
namespace dns
{
2019-04-08 12:01:52 +00:00
Proxy::Proxy(llarp_ev_loop_ptr loop, IQueryHandler* h)
: m_Loop(std::move(loop)), m_QueryHandler(h)
2018-12-03 22:22:59 +00:00
{
2018-12-04 16:35:25 +00:00
m_Client.user = this;
m_Server.user = this;
m_Client.tick = nullptr;
m_Server.tick = nullptr;
m_Client.recvfrom = &HandleUDPRecv_client;
m_Server.recvfrom = &HandleUDPRecv_server;
2018-12-03 22:22:59 +00:00
}
void
Proxy::Stop()
{
}
bool
Proxy::Start(const llarp::Addr& addr,
const std::vector< llarp::Addr >& resolvers)
{
m_Resolvers.clear();
m_Resolvers = resolvers;
2018-12-04 16:35:25 +00:00
llarp::Addr any("0.0.0.0", 0);
2019-04-08 12:01:52 +00:00
return llarp_ev_add_udp(m_Loop.get(), &m_Server, addr) == 0
&& llarp_ev_add_udp(m_Loop.get(), &m_Client, any) == 0;
2018-12-03 22:22:59 +00:00
}
void
2018-12-04 16:35:25 +00:00
Proxy::HandleUDPRecv_server(llarp_udp_io* u, const sockaddr* from,
2019-02-03 00:48:10 +00:00
ManagedBuffer buf)
2018-12-03 22:22:59 +00:00
{
2019-02-02 23:12:42 +00:00
static_cast< Proxy* >(u->user)->HandlePktServer(*from, &buf.underlying);
2018-12-04 16:35:25 +00:00
}
void
Proxy::HandleUDPRecv_client(llarp_udp_io* u, const sockaddr* from,
2019-02-03 00:48:10 +00:00
ManagedBuffer buf)
2018-12-04 16:35:25 +00:00
{
2019-02-02 23:12:42 +00:00
static_cast< Proxy* >(u->user)->HandlePktClient(*from, &buf.underlying);
2018-12-03 22:22:59 +00:00
}
llarp::Addr
Proxy::PickRandomResolver() const
{
const size_t sz = m_Resolvers.size();
if(sz <= 1)
2018-12-03 22:22:59 +00:00
return m_Resolvers[0];
auto itr = m_Resolvers.begin();
std::advance(itr, llarp::randint() % sz);
2018-12-03 22:22:59 +00:00
return *itr;
}
void
Proxy::HandleTick(llarp_udp_io*)
{
}
void
Proxy::SendMessageTo(llarp::Addr to, Message msg)
{
2019-02-05 00:29:09 +00:00
std::array< byte_t, 1500 > tmp = {{0}};
2019-02-02 23:12:42 +00:00
llarp_buffer_t buf(tmp);
2018-12-03 22:22:59 +00:00
if(msg.Encode(&buf))
{
buf.sz = buf.cur - buf.base;
buf.cur = buf.base;
2018-12-04 16:35:25 +00:00
llarp_ev_udp_sendto(&m_Server, to, buf);
2018-12-03 22:22:59 +00:00
}
else
llarp::LogWarn("failed to encode dns message when sending");
}
void
2018-12-04 16:35:25 +00:00
Proxy::HandlePktClient(llarp::Addr from, llarp_buffer_t* pkt)
2018-12-03 22:22:59 +00:00
{
2018-12-04 16:16:43 +00:00
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;
2018-12-04 16:35:25 +00:00
// forward reply
llarp_ev_udp_sendto(&m_Server, itr->second, buf);
2018-12-04 16:16:43 +00:00
// remove pending
m_Forwarded.erase(itr);
}
2018-12-04 16:35:25 +00:00
}
2018-12-04 16:16:43 +00:00
2018-12-04 16:35:25 +00:00
void
Proxy::HandlePktServer(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);
2018-12-04 16:16:43 +00:00
Message msg(hdr);
2018-12-03 22:22:59 +00:00
if(!msg.Decode(pkt))
{
2018-12-04 16:16:43 +00:00
llarp::LogWarn("failed to parse dns message from ", from);
2018-12-03 22:22:59 +00:00
return;
}
2018-12-04 16:16:43 +00:00
2018-12-03 22:22:59 +00:00
if(m_QueryHandler && m_QueryHandler->ShouldHookDNSMessage(msg))
{
if(!m_QueryHandler->HandleHookedDNSMessage(
2018-12-04 16:16:43 +00:00
std::move(msg),
2018-12-03 22:22:59 +00:00
std::bind(&Proxy::SendMessageTo, this, from,
std::placeholders::_1)))
{
llarp::LogWarn("failed to handle hooked dns");
}
}
else if(m_Resolvers.size() == 0)
{
// no upstream resolvers
// let's serv fail it
msg.AddServFail();
SendMessageTo(from, std::move(msg));
}
2018-12-04 16:16:43 +00:00
else if(itr == m_Forwarded.end())
2018-12-03 22:22:59 +00:00
{
// new forwarded query
tx.from = PickRandomResolver();
m_Forwarded[tx] = from;
2018-12-04 16:16:43 +00:00
llarp_buffer_t buf;
buf.sz = pkt->sz;
buf.base = pkt->base;
buf.cur = buf.base;
// do query
2018-12-04 16:35:25 +00:00
llarp_ev_udp_sendto(&m_Client, tx.from, buf);
2018-12-03 22:22:59 +00:00
}
else
{
2018-12-04 16:16:43 +00:00
// drop (?)
2018-12-03 22:22:59 +00:00
}
}
} // namespace dns
} // namespace llarp