llarp/iwp/message_buffer.hpp

Namespaces

Name
llarp
[crypto.hpp]
llarp::iwp

Classes

Name
struct llarp::iwp::OutboundMessage
struct llarp::iwp::InboundMessage

Source code

#pragma once
#include <vector>
#include <llarp/constants/link_layer.hpp>
#include <llarp/link/session.hpp>
#include <llarp/util/aligned.hpp>
#include <llarp/util/buffer.hpp>
#include <llarp/util/types.hpp>

namespace llarp
{
  namespace iwp
  {
    enum Command
    {
      ePING = 0,
      eXMIT = 1,
      eDATA = 2,
      eACKS = 3,
      eNACK = 4,
      eMACK = 5,
      eCLOS = 0xff,
    };

    static constexpr size_t FragmentSize = 1024;
    static constexpr size_t CommandOverhead = 2;

    struct OutboundMessage
    {
      OutboundMessage() = default;
      OutboundMessage(
          uint64_t msgid,
          ILinkSession::Message_t data,
          llarp_time_t now,
          ILinkSession::CompletionHandler handler,
          uint16_t priority);

      ILinkSession::Message_t m_Data;
      uint64_t m_MsgID = 0;
      std::bitset<MAX_LINK_MSG_SIZE / FragmentSize> m_Acks;
      ILinkSession::CompletionHandler m_Completed;
      llarp_time_t m_LastFlush = 0s;
      ShortHash m_Digest;
      llarp_time_t m_StartedAt = 0s;
      uint16_t m_ResendPriority;

      inline size_t
      size() const
      {
        return m_Data.size();
      }

      inline const byte_t*
      data() const
      {
        return m_Data.data();
      }

      bool
      operator<(const OutboundMessage& other) const
      {
        // yes, the first order is reversed as higher means more important
        // second part is for queue order
        int prioA = -m_ResendPriority, prioB = -other.m_ResendPriority;
        return std::tie(prioA, m_MsgID) < std::tie(prioB, other.m_MsgID);
      }

      ILinkSession::Packet_t
      XMIT() const;

      void
      Ack(byte_t bitmask);

      void
      FlushUnAcked(std::function<void(ILinkSession::Packet_t)> sendpkt, llarp_time_t now);

      bool
      ShouldFlush(llarp_time_t now) const;

      void
      Completed();

      bool
      IsTransmitted() const;

      bool
      IsTimedOut(llarp_time_t now) const;

      void
      InformTimeout();
    };

    struct InboundMessage
    {
      InboundMessage() = default;
      InboundMessage(const InboundMessage&) = default;
      InboundMessage(uint64_t msgid, uint16_t sz, ShortHash h, llarp_time_t now);

      ILinkSession::Message_t m_Data;
      ShortHash m_Digset;
      uint64_t m_MsgID = 0;
      llarp_time_t m_LastACKSent = 0s;
      llarp_time_t m_LastActiveAt = 0s;
      std::bitset<MAX_LINK_MSG_SIZE / FragmentSize> m_Acks;

      inline uint64_t
      msgid() const
      {
        return m_MsgID;
      }

      void
      HandleData(uint16_t idx, const llarp_buffer_t& buf, llarp_time_t now);

      bool
      IsCompleted() const;

      bool
      IsTimedOut(llarp_time_t now) const;

      bool
      Verify() const;

      byte_t
      AcksBitmask() const;

      bool
      ShouldSendACKS(llarp_time_t now) const;

      void
      SendACKS(std::function<void(ILinkSession::Packet_t)> sendpkt, llarp_time_t now);

      ILinkSession::Packet_t
      ACKS() const;
    };

  }  // namespace iwp
}  // namespace llarp

Updated on 2026-01-10 at 22:49:45 +0000