#pragma once #include #include #include #include #include namespace llarp { namespace handlers { struct NullEndpoint final : public llarp::service::Endpoint, public std::enable_shared_from_this { NullEndpoint(AbstractRouter* r, llarp::service::Context* parent) : llarp::service::Endpoint(r, parent) { r->loop()->add_ticker([this] { while (not m_InboundQuic.empty()) { m_InboundQuic.top().process(); m_InboundQuic.pop(); } Pump(Now()); }); } struct QUICEvent { uint64_t seqno; std::function process; bool operator<(const QUICEvent& other) const { return other.seqno < seqno; } }; std::priority_queue m_InboundQuic; virtual bool HandleInboundPacket( const service::ConvoTag tag, const llarp_buffer_t& buf, service::ProtocolType t, uint64_t seqno) override { if (t == service::ProtocolType::Control) return true; if (t != service::ProtocolType::QUIC) return false; auto* quic = GetQUICTunnel(); if (!quic) { LogWarn("incoming quic packet but this endpoint is not quic capable; dropping"); return false; } if (buf.sz < 4) { LogWarn("invalid incoming quic packet, dropping"); return false; } MarkConvoTagActive(tag); std::vector copy; copy.resize(buf.sz); std::copy_n(buf.base, buf.sz, copy.data()); m_InboundQuic.push({seqno, [quic, buf = copy, tag]() { quic->receive_packet(tag, buf); }}); m_router->loop()->wakeup(); return true; } std::string GetIfName() const override { return ""; } path::PathSet_ptr GetSelf() override { return shared_from_this(); } bool SupportsV6() const override { return false; } void SendPacketToRemote(const llarp_buffer_t&, service::ProtocolType) override{}; huint128_t ObtainIPForAddr(std::variant) override { return {0}; } std::optional> ObtainAddrForIP( huint128_t) const override { return std::nullopt; } }; } // namespace handlers } // namespace llarp