@ -5,49 +5,45 @@
# include <array>
# include <utility>
namespace llarp
namespace llarp : : dns
{
namespace dns
static std : : vector < byte_t >
MessageToBuffer ( Message msg )
{
Proxy : : Proxy (
llarp_ev_loop_ptr serverLoop ,
Logic_ptr serverLogic ,
llarp_ev_loop_ptr clientLoop ,
Logic_ptr clientLogic ,
IQueryHandler * h )
: m_ServerLoop ( std : : move ( serverLoop ) )
, m_ClientLoop ( std : : move ( clientLoop ) )
, m_ServerLogic ( std : : move ( serverLogic ) )
, m_ClientLogic ( std : : move ( clientLogic ) )
, m_QueryHandler ( h )
std : : array < byte_t , 1500 > tmp = { { 0 } } ;
llarp_buffer_t buf { tmp } ;
if ( not msg . Encode ( & buf ) )
throw std : : runtime_error ( " cannot encode dns message " ) ;
std : : vector < byte_t > pkt ;
pkt . resize ( buf . cur - buf . base ) ;
std : : copy_n ( tmp . data ( ) , pkt . size ( ) , pkt . data ( ) ) ;
return pkt ;
}
PacketHandler : : PacketHandler ( Logic_ptr logic , IQueryHandler * h )
: m_QueryHandler { h } , m_Logic { logic }
{ }
Proxy : : Proxy ( llarp_ev_loop_ptr loop , Logic_ptr logic , IQueryHandler * h )
: PacketHandler { logic , h } , m_Loop ( std : : move ( loop ) )
{
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 ;
m_Server . recvfrom = & HandleUDP ;
}
void
P roxy : : Stop ( )
P acketHandle r: : Stop ( )
{
if ( m_UnboundResolver )
m_UnboundResolver - > Stop ( ) ;
}
bool
Proxy : : Start ( const IpAddress & addr , const std : : vector < IpAddress > & resolvers )
{
if ( resolvers . size ( ) )
Proxy : : Start ( SockAddr addr , std : : vector < IpAddress > resolvers )
{
if ( not SetupUnboundResolver ( resolvers ) )
{
llarp : : LogError ( " Failed to add upstream resolvers during DNS server setup. " ) ;
if ( not PacketHandler : : Start ( addr , std : : move ( resolvers ) ) )
return false ;
}
}
return ( llarp_ev_add_udp ( m_ServerLoop , & m_Server , addr . createSockAddr ( ) ) = = 0 ) ;
return ( llarp_ev_add_udp ( m_Loop , & m_Server , addr ) = = 0 ) ;
}
static Proxy : : Buffer_t
@ -59,35 +55,15 @@ namespace llarp
}
void
Proxy : : HandleUDP Recv_server ( llarp_udp_io * u , const SockAddr & from , ManagedBuffer buf )
Proxy : : HandleUDP ( llarp_udp_io * u , const SockAddr & from , ManagedBuffer buf )
{
Buffer_t msgbuf = CopyBuffer ( buf . underlying ) ;
auto self = static_cast < Proxy * > ( u - > user ) ;
self - > HandlePktServer ( from , msgbuf ) ;
}
void
Proxy : : HandleUDPRecv_client ( llarp_udp_io * u , const SockAddr & from , ManagedBuffer buf )
{
Buffer_t msgbuf = CopyBuffer ( buf . underlying ) ;
auto self = static_cast < Proxy * > ( u - > user ) - > shared_from_this ( ) ;
LogicCall (
self - > m_ServerLogic , [ self , from , msgbuf ] ( ) { self - > HandlePktClient ( from , msgbuf ) ; } ) ;
}
IpAddress
Proxy : : PickRandomResolver ( ) const
{
const size_t sz = m_Resolvers . size ( ) ;
if ( sz < = 1 )
return m_Resolvers [ 0 ] ;
auto itr = m_Resolvers . begin ( ) ;
std : : advance ( itr , llarp : : randint ( ) % sz ) ;
return * itr ;
self - > HandlePacket ( from , from , std : : move ( msgbuf ) ) ;
}
void
P roxy : : Restart ( )
PacketHandler : : Restart ( )
{
if ( m_UnboundResolver )
{
@ -97,26 +73,33 @@ namespace llarp
}
bool
Proxy : : SetupUnboundResolver ( const std : : vector < IpAddress > & resolvers )
PacketHandler : : Start ( SockAddr , std : : vector < IpAddress > resolvers )
{
auto failFunc = [ self = weak_from_this ( ) ] ( SockAddr to , Message msg ) {
return SetupUnboundResolver ( std : : move ( resolvers ) ) ;
}
bool
PacketHandler : : SetupUnboundResolver ( std : : vector < IpAddress > resolvers )
{
auto failFunc = [ self = weak_from_this ( ) ] ( SockAddr from , SockAddr to , Message msg ) {
auto this_ptr = self . lock ( ) ;
if ( this_ptr )
{
this_ptr - > SendServerMessageTo ( to , std : : move ( msg ) ) ;
this_ptr - > SendServerMessage Buffer To( from, to, MessageToBuffer( std: : move ( msg ) ) ) ;
}
} ;
auto replyFunc = [ self = weak_from_this ( ) ] ( SockAddr to , std : : vector < byte_t > buf ) {
auto replyFunc = [ self = weak_from_this ( ) ] (
SockAddr from , SockAddr to , std : : vector < byte_t > buf ) {
auto this_ptr = self . lock ( ) ;
if ( this_ptr )
{
this_ptr - > HandleUpstreamResponse ( to , std : : move ( buf ) ) ;
this_ptr - > SendServerMessageBufferTo ( from , to , std : : move ( buf ) ) ;
}
} ;
m_UnboundResolver = std : : make_shared < UnboundResolver > (
m_ServerLoop , std : : move ( replyFunc ) , std : : move ( failFunc ) ) ;
m_UnboundResolver =
std : : make_shared < UnboundResolver > ( m_Logic , std : : move ( replyFunc ) , std : : move ( failFunc ) ) ;
if ( not m_UnboundResolver - > Init ( ) )
{
llarp : : LogError ( " Failed to initialize upstream DNS resolver. " ) ;
@ -131,125 +114,60 @@ namespace llarp
m_UnboundResolver = nullptr ;
return false ;
}
m_Resolvers . emplace ( resolver ) ;
}
return true ;
}
void
Proxy : : HandleTick ( llarp_udp_io * )
{ }
void
Proxy : : SendServerMessageBufferTo ( const SockAddr & to , const llarp_buffer_t & buf )
Proxy : : SendServerMessageBufferTo ( SockAddr , SockAddr to , Buffer_t buf )
{
if ( llarp_ev_udp_sendto ( & m_Server , to , buf ) < 0 )
llarp : : LogError ( " dns reply failed " ) ;
}
void
Proxy : : SendServerMessageTo ( const SockAddr & to , Message msg )
{
auto self = shared_from_this ( ) ;
LogicCall ( m_ServerLogic , [ to , msg = std : : move ( msg ) , self ] ( ) {
std : : array < byte_t , 1500 > tmp = { { 0 } } ;
llarp_buffer_t buf ( tmp ) ;
if ( msg . Encode ( & buf ) )
bool
PacketHandler : : ShouldHandlePacket ( SockAddr to , SockAddr from , Buffer_t buf ) const
{
buf . sz = buf . cur - buf . base ;
buf . cur = buf . base ;
self - > SendServerMessageBufferTo ( to , buf ) ;
}
else
llarp : : LogWarn ( " failed to encode dns message when sending " ) ;
} ) ;
}
( void ) from ;
void
Proxy : : HandleUpstreamResponse ( SockAddr to , std : : vector < byte_t > buf )
MessageHeader hdr ;
llarp_buffer_t pkt { buf } ;
if ( not hdr . Decode ( & pkt ) )
{
auto self = shared_from_this ( ) ;
LogicCall ( m_ServerLogic , [ to , buffer = std : : move ( buf ) , self ] ( ) {
llarp_buffer_t buf ( buffer ) ;
self - > SendServerMessageBufferTo ( to , buf ) ;
} ) ;
return false ;
}
void
Proxy : : SendClientMessageTo ( const SockAddr & to , Message msg )
{
auto self = shared_from_this ( ) ;
LogicCall ( m_ClientLogic , [ to , msg , self ] ( ) {
std : : array < byte_t , 1500 > tmp = { { 0 } } ;
llarp_buffer_t buf ( tmp ) ;
if ( msg . Encode ( & buf ) )
Message msg { hdr } ;
if ( not msg . Decode ( & pkt ) )
{
buf . sz = buf . cur - buf . base ;
buf . cur = buf . base ;
llarp_ev_udp_sendto ( & self - > m_Client , to , buf ) ;
}
else
llarp : : LogWarn ( " failed to encode dns message when sending " ) ;
} ) ;
return false ;
}
void
Proxy : : HandlePktClient ( const SockAddr & from , Buffer_t buf )
{
llarp_buffer_t pkt ( buf ) ;
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 ( ) )
return ;
const auto & requester = itr - > second ;
auto self = shared_from_this ( ) ;
Message msg ( hdr ) ;
if ( msg . Decode ( & pkt ) )
{
if ( m_QueryHandler & & m_QueryHandler - > ShouldHookDNSMessage ( msg ) )
{
msg . hdr_id = itr - > first . txid ;
if ( ! m_QueryHandler - > HandleHookedDNSMessage (
std : : move ( msg ) ,
std : : bind (
& Proxy : : SendServerMessageTo ,
self ,
requester . createSockAddr ( ) ,
std : : placeholders : : _1 ) ) )
if ( m_QueryHandler and m_QueryHandler - > ShouldHookDNSMessage ( msg ) )
return true ;
if ( m_Resolvers . find ( to ) ! = m_Resolvers . end ( ) )
{
llarp : : LogWarn ( " failed to handle hooked dns " ) ;
}
return ;
}
return false ;
}
LogicCall ( m_ServerLogic , [ = ] ( ) {
// forward reply to requester via server
const llarp_buffer_t tmpbuf ( buf ) ;
llarp_ev_udp_sendto ( & self - > m_Server , requester . createSockAddr ( ) , tmpbuf ) ;
} ) ;
// remove pending
m_Forwarded . erase ( itr ) ;
return true ;
}
void
Proxy : : HandlePktServer ( const SockAddr & from , Buffer_t buf )
PacketHandler : : HandlePacket ( SockAddr resolver , SockAddr from , Buffer_t buf )
{
MessageHeader hdr ;
llarp_buffer_t pkt ( buf ) ;
if ( ! hdr . Decode ( & pkt ) )
llarp_buffer_t pkt { buf } ;
if ( not hdr . Decode ( & pkt ) )
{
llarp : : LogWarn ( " failed to parse dns header from " , from ) ;
return ;
}
Message msg ( hdr ) ;
if ( ! msg . Decode ( & pkt ) )
if ( not msg . Decode ( & pkt ) )
{
llarp : : LogWarn ( " failed to parse dns message from " , from ) ;
return ;
@ -268,17 +186,17 @@ namespace llarp
// yea it is, let's turn off DoH because god is dead.
msg . AddNXReply ( ) ;
// press F to pay respects
SendServerMessage To( from, std: : move ( msg ) ) ;
SendServerMessage Buffer To( resolver, from, MessageToBuffer( std: : move ( msg ) ) ) ;
return ;
}
}
auto self = shared_from_this ( ) ;
if ( m_QueryHandler & & m_QueryHandler - > ShouldHookDNSMessage ( msg ) )
{
if ( ! m_QueryHandler - > HandleHookedDNSMessage (
std : : move ( msg ) ,
std : : bind ( & Proxy : : SendServerMessageTo , self , from , std : : placeholders : : _1 ) ) )
auto reply = [ self = shared_from_this ( ) , to = from , resolver ] ( dns : : Message msg ) {
self - > SendServerMessageBufferTo ( resolver , to , MessageToBuffer ( std : : move ( msg ) ) ) ;
} ;
if ( ! m_QueryHandler - > HandleHookedDNSMessage ( std : : move ( msg ) , reply ) )
{
llarp : : LogWarn ( " failed to handle hooked dns " ) ;
}
@ -288,14 +206,11 @@ namespace llarp
// no upstream resolvers
// let's serv fail it
msg . AddServFail ( ) ;
SendServerMessageTo ( from , std : : move ( msg ) ) ;
SendServerMessageBufferTo ( resolver , from , MessageToBuffer ( std : : move ( msg ) ) ) ;
}
else
{
m_UnboundResolver - > Lookup ( from , std : : move ( msg ) ) ;
m_UnboundResolver - > Lookup ( resolver , from , std : : move ( msg ) ) ;
}
}
} // namespace dns
} // namespace llarp
} // namespace llarp::dns