2021-03-09 22:24:35 +00:00
|
|
|
#pragma once
|
2019-06-26 21:39:29 +00:00
|
|
|
|
2021-03-09 22:24:35 +00:00
|
|
|
#include "i_outbound_message_handler.hpp"
|
2019-06-26 21:39:29 +00:00
|
|
|
|
2021-03-09 22:24:35 +00:00
|
|
|
#include <llarp/ev/ev.hpp>
|
|
|
|
#include <llarp/util/thread/queue.hpp>
|
|
|
|
#include <llarp/path/path_types.hpp>
|
|
|
|
#include <llarp/router_id.hpp>
|
2019-06-26 21:39:29 +00:00
|
|
|
|
|
|
|
#include <list>
|
|
|
|
#include <unordered_map>
|
|
|
|
#include <utility>
|
2020-06-11 11:44:02 +00:00
|
|
|
#include <queue>
|
2019-06-26 21:39:29 +00:00
|
|
|
|
|
|
|
struct llarp_buffer_t;
|
|
|
|
|
|
|
|
namespace llarp
|
|
|
|
{
|
|
|
|
struct ILinkManager;
|
2020-11-10 14:24:58 +00:00
|
|
|
struct I_RCLookupHandler;
|
2019-06-26 21:39:29 +00:00
|
|
|
enum class SessionResult;
|
|
|
|
|
|
|
|
struct OutboundMessageHandler final : public IOutboundMessageHandler
|
|
|
|
{
|
|
|
|
public:
|
2019-07-30 23:42:13 +00:00
|
|
|
~OutboundMessageHandler() override = default;
|
2019-06-26 21:39:29 +00:00
|
|
|
|
2019-10-25 21:13:11 +00:00
|
|
|
OutboundMessageHandler(size_t maxQueueSize = MAX_OUTBOUND_QUEUE_SIZE);
|
|
|
|
|
2019-06-26 21:39:29 +00:00
|
|
|
bool
|
2020-04-07 18:38:56 +00:00
|
|
|
QueueMessage(const RouterID& remote, const ILinkMessage* msg, SendStatusHandler callback)
|
|
|
|
override EXCLUDES(_mutex);
|
2019-06-26 21:39:29 +00:00
|
|
|
|
2019-10-25 21:13:11 +00:00
|
|
|
void
|
|
|
|
Tick() override;
|
|
|
|
|
|
|
|
void
|
2020-04-07 18:38:56 +00:00
|
|
|
QueueRemoveEmptyPath(const PathID_t& pathid) override;
|
2019-10-25 21:13:11 +00:00
|
|
|
|
2019-06-26 21:39:29 +00:00
|
|
|
util::StatusObject
|
|
|
|
ExtractStatus() const override;
|
|
|
|
|
|
|
|
void
|
2021-03-02 07:02:59 +00:00
|
|
|
Init(ILinkManager* linkManager, I_RCLookupHandler* lookupHandler, EventLoop_ptr loop);
|
2019-06-26 21:39:29 +00:00
|
|
|
|
|
|
|
private:
|
2020-04-07 18:38:56 +00:00
|
|
|
using Message = std::pair<std::vector<byte_t>, SendStatusHandler>;
|
2019-10-25 21:13:11 +00:00
|
|
|
|
|
|
|
struct MessageQueueEntry
|
|
|
|
{
|
2020-01-17 16:33:37 +00:00
|
|
|
uint16_t priority;
|
2019-10-25 21:13:11 +00:00
|
|
|
Message message;
|
|
|
|
PathID_t pathid;
|
|
|
|
RouterID router;
|
2020-01-17 16:33:37 +00:00
|
|
|
|
|
|
|
bool
|
2020-04-07 18:38:56 +00:00
|
|
|
operator<(const MessageQueueEntry& other) const
|
2020-01-17 16:33:37 +00:00
|
|
|
{
|
|
|
|
return other.priority < priority;
|
|
|
|
}
|
2019-10-25 21:13:11 +00:00
|
|
|
};
|
|
|
|
|
2020-01-17 17:14:24 +00:00
|
|
|
struct MessageQueueStats
|
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
uint64_t queued = 0;
|
|
|
|
uint64_t dropped = 0;
|
|
|
|
uint64_t sent = 0;
|
2020-01-17 17:14:24 +00:00
|
|
|
uint32_t queueWatermark = 0;
|
|
|
|
|
|
|
|
uint32_t perTickMax = 0;
|
2020-04-07 18:38:56 +00:00
|
|
|
uint32_t numTicks = 0;
|
2020-01-17 17:14:24 +00:00
|
|
|
};
|
|
|
|
|
2020-04-07 18:38:56 +00:00
|
|
|
using MessageQueue = std::priority_queue<MessageQueueEntry>;
|
2019-06-26 21:39:29 +00:00
|
|
|
|
|
|
|
void
|
2020-04-07 18:38:56 +00:00
|
|
|
OnSessionEstablished(const RouterID& router);
|
2019-06-26 21:39:29 +00:00
|
|
|
|
|
|
|
void
|
2020-04-07 18:38:56 +00:00
|
|
|
OnConnectTimeout(const RouterID& router);
|
2019-06-26 21:39:29 +00:00
|
|
|
|
|
|
|
void
|
2020-04-07 18:38:56 +00:00
|
|
|
OnRouterNotFound(const RouterID& router);
|
2019-06-26 21:39:29 +00:00
|
|
|
|
|
|
|
void
|
2020-04-07 18:38:56 +00:00
|
|
|
OnInvalidRouter(const RouterID& router);
|
2019-06-26 21:39:29 +00:00
|
|
|
|
|
|
|
void
|
2020-04-07 18:38:56 +00:00
|
|
|
OnNoLink(const RouterID& router);
|
2019-06-26 21:39:29 +00:00
|
|
|
|
|
|
|
void
|
2020-04-07 18:38:56 +00:00
|
|
|
OnSessionResult(const RouterID& router, const SessionResult result);
|
2019-06-26 21:39:29 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
DoCallback(SendStatusHandler callback, SendStatus status);
|
|
|
|
|
|
|
|
void
|
2020-04-07 18:38:56 +00:00
|
|
|
QueueSessionCreation(const RouterID& remote);
|
2019-06-26 21:39:29 +00:00
|
|
|
|
|
|
|
bool
|
2020-04-07 18:38:56 +00:00
|
|
|
EncodeBuffer(const ILinkMessage* msg, llarp_buffer_t& buf);
|
2019-06-26 21:39:29 +00:00
|
|
|
|
|
|
|
bool
|
2020-04-07 18:38:56 +00:00
|
|
|
Send(const RouterID& remote, const Message& msg);
|
2019-06-26 21:39:29 +00:00
|
|
|
|
|
|
|
bool
|
2020-04-07 18:38:56 +00:00
|
|
|
SendIfSession(const RouterID& remote, const Message& msg);
|
2019-06-26 21:39:29 +00:00
|
|
|
|
2019-10-25 21:13:11 +00:00
|
|
|
bool
|
2020-04-07 18:38:56 +00:00
|
|
|
QueueOutboundMessage(
|
|
|
|
const RouterID& remote, Message&& msg, const PathID_t& pathid, uint16_t priority = 0);
|
2019-10-25 21:13:11 +00:00
|
|
|
|
2019-06-26 21:39:29 +00:00
|
|
|
void
|
2019-10-25 21:13:11 +00:00
|
|
|
ProcessOutboundQueue();
|
|
|
|
|
|
|
|
void
|
|
|
|
RemoveEmptyPathQueues();
|
|
|
|
|
|
|
|
void
|
|
|
|
SendRoundRobin();
|
|
|
|
|
|
|
|
void
|
2020-04-07 18:38:56 +00:00
|
|
|
FinalizeSessionRequest(const RouterID& router, SendStatus status) EXCLUDES(_mutex);
|
2019-06-26 21:39:29 +00:00
|
|
|
|
2020-04-07 18:38:56 +00:00
|
|
|
llarp::thread::Queue<MessageQueueEntry> outboundQueue;
|
|
|
|
llarp::thread::Queue<PathID_t> removedPaths;
|
2019-10-25 21:13:11 +00:00
|
|
|
bool removedSomePaths;
|
|
|
|
|
|
|
|
mutable util::Mutex _mutex; // protects pendingSessionMessageQueues
|
2019-06-26 21:39:29 +00:00
|
|
|
|
2021-03-09 18:39:40 +00:00
|
|
|
std::unordered_map<RouterID, MessageQueue> pendingSessionMessageQueues GUARDED_BY(_mutex);
|
2019-10-25 21:13:11 +00:00
|
|
|
|
2021-03-09 18:39:40 +00:00
|
|
|
std::unordered_map<PathID_t, MessageQueue> outboundMessageQueues;
|
2019-10-25 21:13:11 +00:00
|
|
|
|
2020-04-07 18:38:56 +00:00
|
|
|
std::queue<PathID_t> roundRobinOrder;
|
2019-06-26 21:39:29 +00:00
|
|
|
|
2020-04-07 18:38:56 +00:00
|
|
|
ILinkManager* _linkManager;
|
2020-11-10 14:24:58 +00:00
|
|
|
I_RCLookupHandler* _lookupHandler;
|
2021-03-02 07:02:59 +00:00
|
|
|
EventLoop_ptr _loop;
|
2019-10-25 21:13:11 +00:00
|
|
|
|
2019-11-14 18:50:45 +00:00
|
|
|
util::ContentionKiller m_Killer;
|
|
|
|
|
2019-10-29 02:28:59 +00:00
|
|
|
// paths cannot have pathid "0", so it can be used as the "pathid"
|
|
|
|
// for non-traffic (control) messages, so they can be prioritized.
|
|
|
|
static const PathID_t zeroID;
|
2020-01-17 17:14:24 +00:00
|
|
|
|
|
|
|
MessageQueueStats m_queueStats;
|
2019-06-26 21:39:29 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace llarp
|