#pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "service/protocol_type.hpp" namespace llarp { namespace handlers { struct TunEndpoint : public service::Endpoint, public dns::IQueryHandler, public std::enable_shared_from_this { TunEndpoint(AbstractRouter* r, llarp::service::Context* parent); ~TunEndpoint() override; path::PathSet_ptr GetSelf() override { return shared_from_this(); } void Thaw() override; bool Configure(const NetworkConfig& conf, const DnsConfig& dnsConf) override; void SendPacketToRemote(const llarp_buffer_t&, service::ProtocolType) override{}; std::string GetIfName() const override; void Tick(llarp_time_t now) override; util::StatusObject ExtractStatus() const override; std::unordered_map NotifyParams() const override; bool SupportsV6() const override; bool ShouldHookDNSMessage(const dns::Message& msg) const override; bool HandleHookedDNSMessage( dns::Message query, std::function sendreply) override; void TickTun(llarp_time_t now); bool MapAddress(const service::Address& remote, huint128_t ip, bool SNode); bool Start() override; bool Stop() override; bool IsSNode() const; /// set up tun interface, blocking bool SetupTun(); /// overrides Endpoint bool SetupNetworking() override; /// overrides Endpoint bool HandleInboundPacket( const service::ConvoTag tag, const llarp_buffer_t& pkt, service::ProtocolType t, uint64_t seqno) override; /// handle inbound traffic bool HandleWriteIPPacket( const llarp_buffer_t& buf, huint128_t src, huint128_t dst, uint64_t seqno); /// queue outbound packet to the world bool QueueOutboundTraffic(llarp::net::IPPacket&& pkt); /// we got a packet from the user void HandleGotUserPacket(llarp::net::IPPacket pkt); /// get the local interface's address huint128_t GetIfAddr() const override; /// we have an interface addr bool HasIfAddr() const override { return true; } bool HasLocalIP(const huint128_t& ip) const; /// get a key for ip address std::optional> ObtainAddrForIP(huint128_t ip) const override; bool HasAddress(const AlignedBuffer<32>& addr) const { return m_AddrToIP.find(addr) != m_AddrToIP.end(); } /// get ip address for key unconditionally huint128_t ObtainIPForAddr(std::variant addr) override; /// flush network traffic void Flush(); void ResetInternalState() override; protected: using PacketQueue_t = llarp::util::CoDelQueue< net::IPPacket, net::IPPacket::GetTime, net::IPPacket::PutTime, net::IPPacket::CompareOrder, net::IPPacket::GetNow>; /// queue for sending packets over the network from us PacketQueue_t m_UserToNetworkPktQueue; struct WritePacket { uint64_t seqno; net::IPPacket pkt; bool operator<(const WritePacket& other) const { return other.seqno < seqno; } }; /// queue for sending packets to user from network std::priority_queue m_NetworkToUserPktQueue; /// return true if we have a remote loki address for this ip address bool HasRemoteForIP(huint128_t ipv4) const; /// mark this address as active void MarkIPActive(huint128_t ip); /// mark this address as active forever void MarkIPActiveForever(huint128_t ip); /// flush ip packets virtual void FlushSend(); /// maps ip to key (host byte order) std::unordered_map> m_IPToAddr; /// maps key to ip (host byte order) std::unordered_map, huint128_t> m_AddrToIP; /// maps key to true if key is a service node, maps key to false if key is /// a hidden service std::unordered_map, bool> m_SNodes; private: template void SendDNSReply( Addr_t addr, Endpoint_t ctx, std::shared_ptr query, std::function reply, bool sendIPv6) { if (ctx) { huint128_t ip = ObtainIPForAddr(addr); query->answers.clear(); query->AddINReply(ip, sendIPv6); } else query->AddNXReply(); reply(*query); } /// our dns resolver std::shared_ptr m_Resolver; /// maps ip address to timestamp last active std::unordered_map m_IPActivity; /// our ip address (host byte order) huint128_t m_OurIP; /// our network interface's ipv6 address huint128_t m_OurIPv6; /// next ip address to allocate (host byte order) huint128_t m_NextIP; /// highest ip address to allocate (host byte order) huint128_t m_MaxIP; /// our ip range we are using llarp::IPRange m_OurRange; /// upstream dns resolver list std::vector m_UpstreamResolvers; /// local dns IpAddress m_LocalResolverAddr; /// list of strict connect addresses for hooks std::vector m_StrictConnectAddrs; /// use v6? bool m_UseV6; std::string m_IfName; std::optional m_BaseV6Address; std::shared_ptr m_NetIf; std::unique_ptr m_PacketRouter; }; } // namespace handlers } // namespace llarp