lokinet/llarp/iwp/linklayer.hpp
Jason Rhinelander 74215fc44c Fix link layer delivery race condition (fix random ping delays)
We trigger a pump immediately, but this is racey because we add to our
plaintext data in a worker thread; if the worker thread runs after the
pump then it ends up leaving plaintext to be handled, but there's no
wakeup until the next one.

This was the cause of seeing a random +1s and bunching added to ping
responses sometimes: it wasn't until the *next* ping goes through the
network that the plaintext queue gets processed, at which point it
flushes the old one and often the new one together.

The fix here gets rid of the map of sessions needing wakeups and instead
adds an atomic flag to all of them to let us figure out which ones
need to be flushed.
2021-11-15 13:36:28 -04:00

71 lines
1.6 KiB
C++

#pragma once
#include <llarp/constants/link_layer.hpp>
#include <llarp/crypto/crypto.hpp>
#include <llarp/crypto/encrypted.hpp>
#include <llarp/crypto/types.hpp>
#include <llarp/link/server.hpp>
#include <llarp/config/key_manager.hpp>
#include <memory>
#include <llarp/ev/ev.hpp>
namespace llarp::iwp
{
struct Session;
struct LinkLayer final : public ILinkLayer
{
LinkLayer(
std::shared_ptr<KeyManager> keyManager,
std::shared_ptr<EventLoop> ev,
GetRCFunc getrc,
LinkMessageHandler h,
SignBufferFunc sign,
BeforeConnectFunc_t before,
SessionEstablishedHandler est,
SessionRenegotiateHandler reneg,
TimeoutHandler timeout,
SessionClosedHandler closed,
PumpDoneHandler pumpDone,
WorkerFunc_t dowork,
bool permitInbound);
std::shared_ptr<ILinkSession>
NewOutboundSession(const RouterContact& rc, const AddressInfo& ai) override;
const char*
Name() const override;
uint16_t
Rank() const override;
void
RecvFrom(const SockAddr& from, ILinkSession::Packet_t pkt) override;
bool
MapAddr(const RouterID& pk, ILinkSession* s) override;
void
UnmapAddr(const SockAddr& addr);
void
WakeupPlaintext();
std::string
PrintableName() const;
private:
void
HandleWakeupPlaintext();
const std::shared_ptr<EventLoopWakeup> m_Wakeup;
std::unordered_map<SockAddr, RouterID> m_AuthedAddrs;
std::vector<ILinkSession*> m_WakingUp;
const bool m_Inbound;
};
using LinkLayer_ptr = std::shared_ptr<LinkLayer>;
} // namespace llarp::iwp