#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(); } std::weak_ptr GetWeak() override { return weak_from_this(); } void Thaw() override; // Reconfigures DNS servers and restarts libunbound with the new servers. Returns the old set // of configured dns servers. std::vector ReconfigureDNS(std::vector servers); 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; std::optional GetExitPolicy() const override { return m_TrafficPolicy; } std::set GetOwnedRanges() const override { return m_OwnedRanges; } llarp_time_t PathAlignmentTimeout() const override { return m_PathAlignmentTimeout; } /// ip packet against any exit policies we have /// returns false if this traffic is disallowed by any of those policies /// returns true otherwise bool ShouldAllowTraffic(const net::IPPacket& pkt) 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(); /// flush writing ip packets to interface void FlushWrite(); /// 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; /// dns host files list std::vector m_hostfiles; /// 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; std::optional m_TrafficPolicy; /// ranges we advetise as reachable std::set m_OwnedRanges; /// how long to wait for path alignment llarp_time_t m_PathAlignmentTimeout; /// idempotent wakeup for writing packets to user std::shared_ptr m_PacketSendWaker; /// idempotent wakeup for writing messages to network std::shared_ptr m_MessageSendWaker; /// a file to load / store the ephemeral address map to std::optional m_PersistAddrMapFile; }; } // namespace handlers } // namespace llarp