#ifndef LLARP_DNS_SERVER_HPP #define LLARP_DNS_SERVER_HPP #include #include #include #include #include #include namespace llarp { namespace dns { /// handler of dns query hooking struct IQueryHandler { virtual ~IQueryHandler() = default; /// return true if we should hook this message virtual bool ShouldHookDNSMessage(const Message& msg) const = 0; /// handle a hooked message virtual bool HandleHookedDNSMessage(Message query, std::function sendReply) = 0; }; struct Proxy : public std::enable_shared_from_this { using Logic_ptr = std::shared_ptr; Proxy( llarp_ev_loop_ptr serverLoop, Logic_ptr serverLogic, llarp_ev_loop_ptr clientLoop, Logic_ptr clientLogic, IQueryHandler* handler); bool Start(const IpAddress& addr, const std::vector& resolvers); void Stop(); void Restart(); using Buffer_t = std::vector; private: /// low level packet handler static void HandleUDPRecv_client(llarp_udp_io*, const SockAddr&, ManagedBuffer); static void HandleUDPRecv_server(llarp_udp_io*, const SockAddr&, ManagedBuffer); /// low level ticker static void HandleTick(llarp_udp_io*); void HandlePktClient(const SockAddr& from, Buffer_t buf); void HandlePktServer(const SockAddr& from, Buffer_t buf); void SendClientMessageTo(const SockAddr& to, Message msg); void SendServerMessageBufferTo(const SockAddr& to, const llarp_buffer_t& buf); void SendServerMessageTo(const SockAddr& to, Message msg); void HandleUpstreamResponse(SockAddr to, std::vector buf); void HandleUpstreamFailure(const SockAddr& to, Message msg); IpAddress PickRandomResolver() const; bool SetupUnboundResolver(const std::vector& resolvers); private: llarp_udp_io m_Server; llarp_udp_io m_Client; llarp_ev_loop_ptr m_ServerLoop; llarp_ev_loop_ptr m_ClientLoop; Logic_ptr m_ServerLogic; Logic_ptr m_ClientLogic; IQueryHandler* m_QueryHandler; std::vector m_Resolvers; std::shared_ptr m_UnboundResolver; struct TX { MsgID_t txid; IpAddress from; bool operator==(const TX& other) const { return txid == other.txid && from == other.from; } struct Hash { size_t operator()(const TX& t) const noexcept { return t.txid ^ IpAddress::Hash()(t.from); } }; }; // maps tx to who to send reply to std::unordered_map m_Forwarded; }; } // namespace dns } // namespace llarp #endif