diff --git a/include/llarp/messages/discard.hpp b/include/llarp/messages/discard.hpp new file mode 100644 index 000000000..14e1f8982 --- /dev/null +++ b/include/llarp/messages/discard.hpp @@ -0,0 +1,80 @@ +#ifndef LLARP_MESSAGES_DISCARD_HPP +#define LLARP_MESSAGES_DISCARD_HPP +#include + +namespace llarp +{ + /// a dummy link message that is discarded + struct DiscardMessage : public ILinkMessage + { + std::vector< byte_t > Z; + + ~DiscardMessage() + { + } + + DiscardMessage(const RouterID& id) : ILinkMessage(id) + { + } + + DiscardMessage(const RouterID& other, std::size_t padding) + : ILinkMessage(other) + { + Z.resize(padding); + std::fill(Z.begin(), Z.end(), 'z'); + } + + virtual bool + DecodeKey(llarp_buffer_t key, llarp_buffer_t* buf) + { + llarp_buffer_t strbuf; + if(llarp_buffer_eq(key, "v")) + { + if(!bencode_read_integer(buf, &version)) + return false; + return version == LLARP_PROTO_VERSION; + } + if(llarp_buffer_eq(key, "z")) + { + if(!bencode_read_string(buf, &strbuf)) + return false; + Z.resize(strbuf.sz); + memcpy(Z.data(), strbuf.base, strbuf.sz); + return true; + } + return false; + } + + virtual bool + BEncode(llarp_buffer_t* buf) const + { + if(!bencode_start_dict(buf)) + return false; + + if(!bencode_write_bytestring(buf, "a", 1)) + return false; + if(!bencode_write_bytestring(buf, "z", 1)) + return false; + + if(!bencode_write_version_entry(buf)) + return false; + + if(!bencode_write_bytestring(buf, "z", 1)) + return false; + if(!bencode_write_bytestring(buf, Z.data(), Z.size())) + return false; + + return bencode_end(buf); + } + + virtual bool + HandleMessage(llarp_router* router) const + { + (void)router; + llarp::Info("got discard message of size ", Z.size(), " bytes"); + return true; + } + }; +} + +#endif diff --git a/llarp/link_message.cpp b/llarp/link_message.cpp index 6d4a9cdca..cb738281e 100644 --- a/llarp/link_message.cpp +++ b/llarp/link_message.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include "buffer.hpp" @@ -63,6 +64,8 @@ namespace llarp case 'c': handler->msg = new LR_CommitMessage(handler->GetCurrentFrom()); break; + case 'z': + handler->msg = new DiscardMessage(handler->GetCurrentFrom()); default: return false; } diff --git a/llarp/router.cpp b/llarp/router.cpp index 512916cd8..ba1f6633b 100644 --- a/llarp/router.cpp +++ b/llarp/router.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "buffer.hpp" #include "encode.hpp" @@ -265,6 +266,46 @@ llarp_router::on_verify_server_rc(llarp_async_verify_rc *job) delete job; } +void +llarp_router::handle_router_ticker(void *user, uint64_t orig, uint64_t left) +{ + if(left) + return; + llarp_router *self = static_cast< llarp_router * >(user); + self->ticker_job_id = 0; + self->Tick(); + self->ScheduleTicker(orig); +} + +void +llarp_router::Tick() +{ + if(sendPadding) + { + for(auto &link : links) + { + link->iter_sessions(link, {this, nullptr, &send_padded_message}); + } + } +} + +bool +llarp_router::send_padded_message(llarp_link_session_iter *itr, + llarp_link_session *peer) +{ + auto msg = new llarp::DiscardMessage({}, 4096); + llarp_router *self = static_cast< llarp_router * >(itr->user); + self->SendToOrQueue(peer->get_remote_router(peer)->pubkey, {msg}); + return true; +} + +void +llarp_router::ScheduleTicker(uint64_t ms) +{ + ticker_job_id = + llarp_logic_call_later(logic, {ms, this, &handle_router_ticker}); +} + void llarp_router::SessionClosed(const llarp::RouterID &remote) { diff --git a/llarp/router.hpp b/llarp/router.hpp index df7597e15..47e5f28dd 100644 --- a/llarp/router.hpp +++ b/llarp/router.hpp @@ -61,6 +61,11 @@ struct llarp_router // buffer for serializing link messages byte_t linkmsg_buffer[MAX_LINK_MSG_SIZE]; + // should we be sending padded messages every interval? + bool sendPadding = false; + + uint32_t ticker_job_id = 0; + llarp::InboundMessageParser inbound_msg_parser; std::list< llarp_link * > links; @@ -126,6 +131,14 @@ struct llarp_router void SessionClosed(const llarp::RouterID &remote); + /// call internal router ticker + void + Tick(); + + /// schedule ticker to call i ms from now + void + ScheduleTicker(uint64_t i = 1000); + void async_verify_RC(llarp_link_session *session, bool isExpectingClient, llarp_link_establish_job *job = nullptr); @@ -145,6 +158,13 @@ struct llarp_router static void on_verify_server_rc(llarp_async_verify_rc *context); + + static void + handle_router_ticker(void *user, uint64_t orig, uint64_t left); + + static bool + send_padded_message(struct llarp_link_session_iter *itr, + struct llarp_link_session *peer); }; #endif