diff --git a/llarp/exit/endpoint.cpp b/llarp/exit/endpoint.cpp index 62071ec90..453e7afc1 100644 --- a/llarp/exit/endpoint.cpp +++ b/llarp/exit/endpoint.cpp @@ -74,7 +74,13 @@ namespace llarp { if(ExpiresSoon(now, timeout)) return true; - return now > m_LastActive && now - m_LastActive > timeout; + auto path = GetCurrentPath(); + if(!path) + return true; + auto lastPing = path->LastRemoteActivityAt(); + if(now > lastPing && now - lastPing > timeout) + return now > m_LastActive && now - m_LastActive > timeout; + return true; } bool diff --git a/llarp/messages/dht.hpp b/llarp/messages/dht.hpp index e81c5e04a..d20c1a1cf 100644 --- a/llarp/messages/dht.hpp +++ b/llarp/messages/dht.hpp @@ -24,6 +24,13 @@ namespace llarp bool HandleMessage(IMessageHandler* h, llarp::Router* r) const override; + + void + Clear() override + { + M.clear(); + } + }; } // namespace routing } // namespace llarp diff --git a/llarp/messages/discard.hpp b/llarp/messages/discard.hpp index 9cbfd9813..a44ce3143 100644 --- a/llarp/messages/discard.hpp +++ b/llarp/messages/discard.hpp @@ -61,6 +61,8 @@ namespace llarp version = LLARP_PROTO_VERSION; } + void Clear() override {} + bool HandleMessage(IMessageHandler* h, llarp::Router* r) const override { diff --git a/llarp/messages/exit.hpp b/llarp/messages/exit.hpp index 89d863444..251d6c961 100644 --- a/llarp/messages/exit.hpp +++ b/llarp/messages/exit.hpp @@ -31,6 +31,13 @@ namespace llarp ObtainExitMessage& operator=(const ObtainExitMessage& other); + void + Clear() override + { + B.clear(); + W.clear(); + } + /// populates I and signs bool Sign(llarp::Crypto* c, const llarp::SecretKey& sk); @@ -79,6 +86,9 @@ namespace llarp bool HandleMessage(IMessageHandler* h, llarp::Router* r) const override; + + void + Clear() override {} }; struct RejectExitMessage final : public IMessage @@ -98,6 +108,12 @@ namespace llarp { } + void + Clear() override + { + R.clear(); + } + RejectExitMessage& operator=(const RejectExitMessage& other); @@ -132,6 +148,9 @@ namespace llarp { } + void + Clear() override {} + UpdateExitVerifyMessage& operator=(const UpdateExitVerifyMessage& other); @@ -184,6 +203,9 @@ namespace llarp bool HandleMessage(IMessageHandler* h, llarp::Router* r) const override; + + void + Clear() override {} }; struct CloseExitMessage final : public IMessage @@ -218,6 +240,9 @@ namespace llarp bool Verify(llarp::Crypto* c, const llarp::PubKey& pk) const; + + void + Clear() override {} }; } // namespace routing diff --git a/llarp/messages/path_confirm.hpp b/llarp/messages/path_confirm.hpp index 3827e7255..8ebf729ce 100644 --- a/llarp/messages/path_confirm.hpp +++ b/llarp/messages/path_confirm.hpp @@ -23,6 +23,9 @@ namespace llarp bool HandleMessage(IMessageHandler* h, llarp::Router* r) const override; + + void + Clear() override {}; }; } // namespace routing } // namespace llarp diff --git a/llarp/messages/path_latency.hpp b/llarp/messages/path_latency.hpp index f762a5bf5..38c433031 100644 --- a/llarp/messages/path_latency.hpp +++ b/llarp/messages/path_latency.hpp @@ -19,6 +19,8 @@ namespace llarp bool DecodeKey(llarp_buffer_t key, llarp_buffer_t* val) override; + void Clear() override {}; + bool HandleMessage(IMessageHandler* h, llarp::Router* r) const override; }; diff --git a/llarp/messages/path_transfer.hpp b/llarp/messages/path_transfer.hpp index a52583445..9a569b92d 100644 --- a/llarp/messages/path_transfer.hpp +++ b/llarp/messages/path_transfer.hpp @@ -32,6 +32,12 @@ namespace llarp bool HandleMessage(IMessageHandler*, llarp::Router* r) const override; + + void + Clear() override + { + T.Clear(); + } }; } // namespace routing diff --git a/llarp/messages/transfer_traffic.hpp b/llarp/messages/transfer_traffic.hpp index bcd5d0c2e..f9698d1c0 100644 --- a/llarp/messages/transfer_traffic.hpp +++ b/llarp/messages/transfer_traffic.hpp @@ -19,6 +19,11 @@ namespace llarp std::vector< llarp::Encrypted< MaxExitMTU + ExitOverhead > > X; size_t _size = 0; + void Clear() override + { + X.clear(); + } + size_t Size() const { diff --git a/llarp/path.cpp b/llarp/path.cpp index 20e310ea4..7c487b9d8 100644 --- a/llarp/path.cpp +++ b/llarp/path.cpp @@ -553,7 +553,7 @@ namespace llarp bool Path::HandleRoutingMessage(llarp_buffer_t buf, llarp::Router* r) { - if(!m_InboundMessageParser.ParseMessageBuffer(buf, this, RXID(), r)) + if(!r->ParseRoutingMessageBuffer(buf, this, RXID())) { llarp::LogWarn("Failed to parse inbound routing message"); return false; diff --git a/llarp/path.hpp b/llarp/path.hpp index 4c0893d16..a4e32b6bc 100644 --- a/llarp/path.hpp +++ b/llarp/path.hpp @@ -122,6 +122,10 @@ namespace llarp HandleDownstream(llarp_buffer_t X, const TunnelNonce& Y, llarp::Router* r) = 0; + /// return timestamp last remote activity happened at + virtual llarp_time_t + LastRemoteActivityAt() const = 0; + uint64_t NextSeqNo() { @@ -146,6 +150,7 @@ namespace llarp // 10 minutes default llarp_time_t lifetime = DEFAULT_PATH_LIFETIME; llarp_proto_version_t version; + llarp_time_t m_LastActivity = 0; bool IsEndpoint(const RouterID& us) const @@ -155,7 +160,12 @@ namespace llarp llarp_time_t ExpireTime() const; - llarp::routing::InboundMessageParser m_MessageParser; + + llarp_time_t + LastRemoteActivityAt() const override + { + return m_LastActivity; + } friend std::ostream& operator<<(std::ostream& out, const TransitHop& h) @@ -337,6 +347,12 @@ namespace llarp return _status; } + llarp_time_t + LastRemoteActivityAt() const override + { + return m_LastRecvMessage; + } + void SetBuildResultHook(BuildResultHookFunc func); @@ -509,9 +525,6 @@ namespace llarp SendExitClose(const llarp::routing::CloseExitMessage* msg, llarp::Router* r); - protected: - llarp::routing::InboundMessageParser m_InboundMessageParser; - private: /// call obtained exit hooks bool diff --git a/llarp/router.cpp b/llarp/router.cpp index 2862d4b07..0382eb2f5 100644 --- a/llarp/router.cpp +++ b/llarp/router.cpp @@ -525,6 +525,12 @@ namespace llarp self->ScheduleTicker(orig); } + bool + Router::ParseRoutingMessageBuffer(llarp_buffer_t buf, routing::IMessageHandler * h, PathID_t rxid) + { + return inbound_routing_msg_parser.ParseMessageBuffer(buf, h, rxid, this); + } + bool Router::ConnectionToRouterAllowed(const llarp::RouterID &router) const { diff --git a/llarp/router.hpp b/llarp/router.hpp index 601bc2c2f..87bdbbd6b 100644 --- a/llarp/router.hpp +++ b/llarp/router.hpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -339,6 +340,12 @@ namespace llarp llarp::ILinkLayer * GetLinkWithSessionByPubkey(const llarp::RouterID &remote); + + /// parse a routing message in a buffer and handle it with a handler if successful parsing + /// return true on parse and handle success otherwise return false + bool + ParseRoutingMessageBuffer(llarp_buffer_t buf, routing::IMessageHandler * h, PathID_t rxid); + void ConnectToRandomRouters(int N); diff --git a/llarp/routing/handler.hpp b/llarp/routing/handler.hpp index 16e27f433..7febe2dd0 100644 --- a/llarp/routing/handler.hpp +++ b/llarp/routing/handler.hpp @@ -18,6 +18,8 @@ namespace llarp // handles messages on the routing level struct IMessageHandler { + + virtual bool HandleObtainExitMessage(const ObtainExitMessage *msg, llarp::Router *r) = 0; diff --git a/llarp/routing/message.hpp b/llarp/routing/message.hpp index e06bd52c9..c22b8f77a 100644 --- a/llarp/routing/message.hpp +++ b/llarp/routing/message.hpp @@ -25,23 +25,12 @@ namespace llarp virtual bool HandleMessage(IMessageHandler* h, llarp::Router* r) const = 0; + + virtual void + Clear() = 0; }; - struct InboundMessageParser - { - InboundMessageParser(); - bool - ParseMessageBuffer(llarp_buffer_t buf, IMessageHandler* handler, - const PathID_t& from, llarp::Router* r); - - private: - static bool - OnKey(dict_reader* r, llarp_buffer_t* key); - bool firstKey; - char key; - dict_reader reader; - std::unique_ptr< IMessage > msg; - }; + } // namespace routing } // namespace llarp diff --git a/llarp/routing/message_parser.cpp b/llarp/routing/message_parser.cpp index 1c386689d..8e20f39ed 100644 --- a/llarp/routing/message_parser.cpp +++ b/llarp/routing/message_parser.cpp @@ -1,10 +1,5 @@ #include -#include -#include -#include -#include -#include -#include +#include namespace llarp { @@ -43,40 +38,40 @@ namespace llarp switch(self->key) { case 'D': - self->msg.reset(new DataDiscardMessage()); + self->msg = &self->m_Holder.D; break; case 'L': - self->msg.reset(new PathLatencyMessage()); + self->msg = &self->m_Holder.L; break; case 'M': - self->msg.reset(new DHTMessage()); + self->msg = &self->m_Holder.M; break; case 'P': - self->msg.reset(new PathConfirmMessage()); + self->msg = &self->m_Holder.P; break; case 'T': - self->msg.reset(new PathTransferMessage()); + self->msg = &self->m_Holder.T; break; case 'H': - self->msg.reset(new service::ProtocolFrame()); + self->msg = &self->m_Holder.H; break; case 'I': - self->msg.reset(new TransferTrafficMessage()); + self->msg = &self->m_Holder.I; break; case 'G': - self->msg.reset(new GrantExitMessage()); + self->msg = &self->m_Holder.G; break; case 'J': - self->msg.reset(new RejectExitMessage()); + self->msg = &self->m_Holder.J; break; case 'O': - self->msg.reset(new ObtainExitMessage()); + self->msg = &self->m_Holder.O; break; case 'U': - self->msg.reset(new UpdateExitMessage()); + self->msg = &self->m_Holder.U; break; case 'C': - self->msg.reset(new CloseExitMessage()); + self->msg = &self->m_Holder.C; break; default: llarp::LogError("invalid routing message id: ", *strbuf.cur); @@ -111,7 +106,8 @@ namespace llarp llarp::LogError("read dict failed in routing layer"); llarp::DumpBuffer< llarp_buffer_t, 128 >(buf); } - msg.reset(); + msg->Clear(); + msg = nullptr; return result; } } // namespace routing diff --git a/llarp/routing/message_parser.hpp b/llarp/routing/message_parser.hpp new file mode 100644 index 000000000..be55eb06d --- /dev/null +++ b/llarp/routing/message_parser.hpp @@ -0,0 +1,56 @@ +#ifndef LLARP_ROUTING_MESSAGE_PARSER_HPP +#define LLARP_ROUTING_MESSAGE_PARSER_HPP +#include +#include +#include +#include +#include +#include +#include +#include + +namespace llarp +{ + struct Router; + + namespace routing + { + struct IMessageHandler; + + struct InboundMessageParser + { + InboundMessageParser(); + + bool + ParseMessageBuffer(llarp_buffer_t buf, IMessageHandler* handler, + const PathID_t& from, llarp::Router* r); + + private: + static bool + OnKey(dict_reader* r, llarp_buffer_t* key); + bool firstKey; + char key; + dict_reader reader; + + struct MessageHolder + { + DataDiscardMessage D; + PathLatencyMessage L; + DHTMessage M; + PathConfirmMessage P; + PathTransferMessage T; + service::ProtocolFrame H; + TransferTrafficMessage I; + GrantExitMessage G; + RejectExitMessage J; + ObtainExitMessage O; + UpdateExitMessage U; + CloseExitMessage C; + }; + + IMessage * msg = nullptr; + MessageHolder m_Holder; + }; + } +} +#endif \ No newline at end of file diff --git a/llarp/service/protocol.hpp b/llarp/service/protocol.hpp index 41ec9f377..8c6a519d9 100644 --- a/llarp/service/protocol.hpp +++ b/llarp/service/protocol.hpp @@ -116,6 +116,12 @@ namespace llarp bool BEncode(llarp_buffer_t* buf) const override; + void + Clear() override + { + D.Clear(); + } + bool Verify(llarp::Crypto* c, const ServiceInfo& from) const; diff --git a/llarp/transit_hop.cpp b/llarp/transit_hop.cpp index 2cd5dae0f..c8a810a99 100644 --- a/llarp/transit_hop.cpp +++ b/llarp/transit_hop.cpp @@ -101,7 +101,12 @@ namespace llarp r->crypto.xchacha20(buf, pathKey, Y); if(IsEndpoint(r->pubkey())) { - return m_MessageParser.ParseMessageBuffer(buf, this, info.rxID, r); + if(r->ParseRoutingMessageBuffer(buf, this, info.rxID)) + { + m_LastActivity = r->Now(); + return true; + } + return false; } else {