lokinet/include/llarp/iwp/frame_state.hpp

113 lines
2.1 KiB
C++

#pragma once
#include "codel.hpp"
#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 <queue>
#include <unordered_map>
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, transit_message * > 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);
};