#pragma once #include #include #include "frame_header.hpp" #include "inbound_message.hpp" #include "llarp/logger.hpp" #include "llarp/time.h" #include "llarp/types.h" #include "sendbuf.hpp" #include "transit_message.hpp" #include #include enum msgtype { eALIV = 0x00, eXMIT = 0x01, eACKS = 0x02, eFRAG = 0x03 }; static inline byte_t * init_sendbuf(sendbuf_t *buf, msgtype t, uint16_t sz, uint8_t flags) { frame_header hdr(buf->data()); hdr.version() = 0; hdr.msgtype() = t; hdr.setsize(sz); buf->data()[4] = 0; buf->data()[5] = flags; return hdr.data(); } struct llarp_router; struct llarp_link_session; struct frame_state { byte_t rxflags = 0; byte_t txflags = 0; uint64_t rxids = 0; uint64_t txids = 0; llarp_time_t lastEvent = 0; std::unordered_map< uint64_t, llarp::ShortHash > rxIDs; std::unordered_map< llarp::ShortHash, transit_message *, llarp::ShortHash::Hash > rx; std::unordered_map< uint64_t, transit_message * > tx; typedef std::queue< sendbuf_t * > sendqueue_t; typedef llarp::util::CoDelQueue< InboundMessage *, InboundMessage::GetTime, InboundMessage::PutTime, llarp::util::DummyMutex, llarp::util::DummyLock > recvqueue_t; llarp_link_session *parent = nullptr; sendqueue_t sendqueue; recvqueue_t recvqueue; uint64_t nextMsgID = 0; frame_state(llarp_link_session *session) : parent(session), recvqueue("iwp_inbound_message") { } /// return true if both sides have the same state flags bool flags_agree(byte_t flags) const; bool process_inbound_queue(); llarp_router * Router(); void clear(); bool inbound_frame_complete(uint64_t id); void push_ackfor(uint64_t id, uint32_t bitmask); bool got_xmit(frame_header hdr, size_t sz); void alive(); bool got_frag(frame_header hdr, size_t sz); bool got_acks(frame_header hdr, size_t sz); // queue new outbound message void queue_tx(uint64_t id, transit_message *msg); void retransmit(llarp_time_t now); // get next frame to encrypt and transmit bool next_frame(llarp_buffer_t *buf); void pop_next_frame(); bool process(byte_t *buf, size_t sz); };