#pragma once #include #include #include #include #include #include namespace llarp { namespace iwp { enum Command { /// keep alive message ePING = 0, /// begin transission eXMIT = 1, /// fragment data eDATA = 2, /// acknolege fragments eACKS = 3, /// negative ack eNACK = 4, /// multiack eMACK = 5, /// close session eCLOS = 0xff, }; /// max size of data fragments static constexpr size_t FragmentSize = 1024; /// plaintext header overhead size 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 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; 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 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(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 m_Acks; 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 sendpkt, llarp_time_t now); ILinkSession::Packet_t ACKS() const; }; } // namespace iwp } // namespace llarp