mirror of https://github.com/oxen-io/lokinet
Merge remote-tracking branch 'sachaaaa/refactor' into hidden-service-dht
This commit is contained in:
commit
dfa567e816
|
@ -13,6 +13,7 @@
|
|||
},
|
||||
"includePath": [
|
||||
"${workspaceFolder}/include",
|
||||
"${workspaceFolder}/llarp",
|
||||
"${workspaceFolder}/vendor/cppbackport-master/lib"
|
||||
],
|
||||
"defines": [],
|
||||
|
|
|
@ -82,7 +82,7 @@ if(RELEASE_MOTTO)
|
|||
endif()
|
||||
|
||||
set(EXE llarpd)
|
||||
set(EXE_SRC daemon/main.c)
|
||||
set(EXE_SRC daemon/main.cpp)
|
||||
|
||||
if(SODIUM_INCLUDE_DIR)
|
||||
include_directories(${SODIUM_INCLUDE_DIR})
|
||||
|
@ -134,7 +134,7 @@ endif()
|
|||
|
||||
set(LIB_SRC
|
||||
llarp/address_info.cpp
|
||||
llarp/bencode.c
|
||||
llarp/bencode.cpp
|
||||
llarp/buffer.cpp
|
||||
llarp/config.cpp
|
||||
llarp/context.cpp
|
||||
|
@ -145,10 +145,8 @@ set(LIB_SRC
|
|||
llarp/encrypted_frame.cpp
|
||||
llarp/ev.cpp
|
||||
llarp/exit_info.cpp
|
||||
llarp/exit_route.c
|
||||
llarp/iwp_link.cpp
|
||||
llarp/exit_route.cpp
|
||||
llarp/logger.cpp
|
||||
llarp/link.c
|
||||
llarp/link_intro.cpp
|
||||
llarp/link_message.cpp
|
||||
llarp/logic.cpp
|
||||
|
@ -174,6 +172,12 @@ set(LIB_SRC
|
|||
llarp/api/client.cpp
|
||||
llarp/api/message.cpp
|
||||
llarp/api/parser.cpp
|
||||
llarp/iwp/frame_header.cpp
|
||||
llarp/iwp/frame_state.cpp
|
||||
llarp/iwp/session.cpp
|
||||
llarp/iwp/transit_message.cpp
|
||||
llarp/iwp/xmit.cpp
|
||||
llarp/link/encoder.cpp
|
||||
llarp/routing/dht_message.cpp
|
||||
llarp/routing/message_parser.cpp
|
||||
llarp/routing/path_confirm.cpp
|
||||
|
|
|
@ -166,6 +166,7 @@ x is the timestamp seconds since epoch that this introduction expires at
|
|||
|
||||
{
|
||||
k: "<32 bytes public identity key of router>",
|
||||
l: advertised_path_latency_ms_uint64, (optional)
|
||||
p: "<16 bytes path id>",
|
||||
v: 0,
|
||||
x: time_expires_seconds_since_epoch_uint64
|
||||
|
|
|
@ -73,6 +73,6 @@ namespace llarp
|
|||
|
||||
std::ostream &out;
|
||||
};
|
||||
}
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
||||
|
|
|
@ -11,10 +11,6 @@
|
|||
* utilities for handling addresses on the llarp network
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define MAX_AI_DIALECT_SIZE 5
|
||||
|
||||
/// address information model
|
||||
|
@ -92,8 +88,4 @@ struct llarp_ai_list_iter
|
|||
void
|
||||
llarp_ai_list_iterate(struct llarp_ai_list *l, struct llarp_ai_list_iter *iter);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -14,10 +14,6 @@
|
|||
* we utilize llarp_buffer which provides memory management
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
bool
|
||||
bencode_write_bytestring(llarp_buffer_t* buff, const void* data, size_t sz);
|
||||
|
||||
|
@ -88,7 +84,4 @@ struct list_reader
|
|||
bool
|
||||
bencode_read_list(llarp_buffer_t* buff, struct list_reader* r);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -13,10 +13,6 @@
|
|||
* generic memory buffer
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef uint8_t byte_t;
|
||||
|
||||
/**
|
||||
|
@ -86,8 +82,4 @@ llarp_buffer_read_until(llarp_buffer_t *buff, char delim, byte_t *result,
|
|||
bool
|
||||
llarp_buffer_eq(llarp_buffer_t buff, const char *data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -7,10 +7,6 @@
|
|||
* library configuration utilties
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct llarp_config;
|
||||
|
||||
/// allocate config
|
||||
|
@ -42,7 +38,4 @@ void
|
|||
llarp_config_iter(struct llarp_config *conf,
|
||||
struct llarp_config_iterator *iter);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -12,10 +12,6 @@
|
|||
* potentially allow libssl support in the future
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define PUBKEYSIZE 32
|
||||
#define SECKEYSIZE 64
|
||||
#define NONCESIZE 24
|
||||
|
@ -110,8 +106,4 @@ llarp_crypto_libsodium_init(struct llarp_crypto *c);
|
|||
bool
|
||||
llarp_crypto_initialized(struct llarp_crypto *c);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -41,6 +41,6 @@ namespace llarp
|
|||
typedef AlignedBuffer< 24 > SymmNonce;
|
||||
|
||||
typedef AlignedBuffer< 32 > SymmKey;
|
||||
}
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
||||
|
|
|
@ -12,10 +12,6 @@
|
|||
* asynchronous crypto functions
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/// context for doing asynchronous cryptography for iwp
|
||||
/// with a worker threadpool
|
||||
/// defined in crypto_async.cpp
|
||||
|
@ -182,6 +178,24 @@ struct iwp_async_frame
|
|||
byte_t buf[1500];
|
||||
};
|
||||
|
||||
// TODO: remove
|
||||
struct FramePutTime
|
||||
{
|
||||
void
|
||||
operator()(iwp_async_frame *frame) const
|
||||
{
|
||||
frame->created = llarp_time_now_ms();
|
||||
}
|
||||
};
|
||||
struct FrameGetTime
|
||||
{
|
||||
llarp_time_t
|
||||
operator()(const iwp_async_frame *frame) const
|
||||
{
|
||||
return frame->created;
|
||||
}
|
||||
};
|
||||
|
||||
/// synchronously decrypt a frame
|
||||
bool
|
||||
iwp_decrypt_frame(struct iwp_async_frame *frame);
|
||||
|
@ -200,7 +214,4 @@ void
|
|||
iwp_call_async_frame_encrypt(struct llarp_async_iwp *iwp,
|
||||
struct iwp_async_frame *frame);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -10,10 +10,6 @@
|
|||
* DHT functions
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct llarp_dht_context;
|
||||
|
||||
/// allocator
|
||||
|
@ -72,7 +68,4 @@ void
|
|||
llarp_dht_lookup_router(struct llarp_dht_context* ctx,
|
||||
struct llarp_router_lookup_job* job);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#ifndef LLARP_DTLS_H_
|
||||
#define LLARP_DTLS_H_
|
||||
|
||||
#include <llarp/link.h>
|
||||
#include <llarp/mem.h>
|
||||
|
||||
/**
|
||||
|
@ -12,10 +11,6 @@
|
|||
* on DTLS
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/// DTLS configuration
|
||||
struct llarp_dtls_args
|
||||
{
|
||||
|
@ -29,7 +24,4 @@ void
|
|||
dtls_link_init(struct llarp_link* link, struct llarp_dtls_args args,
|
||||
struct llarp_msg_muxer* muxer);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -9,6 +9,6 @@ namespace llarp
|
|||
DecryptInPlace(const byte_t* symkey, const byte_t* nonce,
|
||||
llarp_crypto* crypto);
|
||||
};
|
||||
}
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
|
@ -13,10 +13,6 @@
|
|||
* event handler (cross platform high performance event system for IO)
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// forward declare
|
||||
struct llarp_threadpool;
|
||||
struct llarp_logic;
|
||||
|
@ -70,7 +66,4 @@ llarp_ev_udp_sendto(struct llarp_udp_io *udp, const struct sockaddr *to,
|
|||
int
|
||||
llarp_ev_close_udp(struct llarp_udp_io *udp);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -10,10 +10,6 @@
|
|||
* utilities for handling exits on the llarp network
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/// Exit info model
|
||||
struct llarp_xi
|
||||
{
|
||||
|
@ -60,7 +56,4 @@ struct llarp_xi_list_iter
|
|||
void
|
||||
llarp_xi_list_iterate(struct llarp_xi_list *l, struct llarp_xi_list_iter *iter);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -3,9 +3,6 @@
|
|||
#include <llarp/buffer.h>
|
||||
#include <llarp/net.h>
|
||||
#include <stdint.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct llarp_xr
|
||||
{
|
||||
|
@ -20,7 +17,4 @@ llarp_xr_bencode(struct llarp_xr* xr, llarp_buffer_t* buff);
|
|||
bool
|
||||
llarp_xr_bdecode(struct llarp_xr* xr, llarp_buffer_t* buff);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
#ifndef LLARP_IWP_H_
|
||||
#define LLARP_IWP_H_
|
||||
#include <llarp/crypto.h>
|
||||
#include <llarp/link.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "router.hpp"
|
||||
|
||||
struct llarp_iwp_args
|
||||
{
|
||||
|
@ -16,10 +12,4 @@ struct llarp_iwp_args
|
|||
const char* keyfile;
|
||||
};
|
||||
|
||||
void
|
||||
iwp_link_init(struct llarp_link* link, struct llarp_iwp_args args);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
#pragma once
|
||||
|
||||
#include "llarp/address_info.h"
|
||||
|
||||
struct llarp_link;
|
||||
struct llarp_link_session;
|
||||
|
||||
struct llarp_link_establish_job
|
||||
{
|
||||
void *user;
|
||||
void (*result)(struct llarp_link_establish_job *);
|
||||
struct llarp_ai ai;
|
||||
uint64_t timeout;
|
||||
uint16_t retries;
|
||||
|
||||
byte_t pubkey[PUBKEYSIZE];
|
||||
/** set on success by try_establish */
|
||||
struct llarp_link *link;
|
||||
/** set on success by try_establish */
|
||||
struct llarp_link_session *session;
|
||||
};
|
|
@ -0,0 +1,39 @@
|
|||
#pragma once
|
||||
|
||||
#include "llarp/buffer.h"
|
||||
|
||||
enum header_flag
|
||||
{
|
||||
eSessionInvalidated = (1 << 0),
|
||||
eHighPacketDrop = (1 << 1),
|
||||
eHighMTUDetected = (1 << 2),
|
||||
eProtoUpgrade = (1 << 3)
|
||||
};
|
||||
|
||||
struct frame_header
|
||||
{
|
||||
byte_t *ptr;
|
||||
|
||||
frame_header(byte_t *buf);
|
||||
|
||||
byte_t *
|
||||
data();
|
||||
|
||||
uint8_t &
|
||||
version();
|
||||
|
||||
uint8_t &
|
||||
msgtype();
|
||||
|
||||
uint16_t
|
||||
size() const;
|
||||
|
||||
void
|
||||
setsize(uint16_t sz);
|
||||
|
||||
uint8_t &
|
||||
flags();
|
||||
|
||||
void
|
||||
setflag(header_flag f);
|
||||
};
|
|
@ -0,0 +1,112 @@
|
|||
#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);
|
||||
};
|
|
@ -0,0 +1,59 @@
|
|||
#pragma once
|
||||
|
||||
#include "buffer.hpp"
|
||||
#include "llarp/time.h"
|
||||
#include "llarp/types.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
struct InboundMessage
|
||||
{
|
||||
uint64_t msgid;
|
||||
std::vector< byte_t > msg;
|
||||
llarp_time_t queued = 0;
|
||||
|
||||
InboundMessage(uint64_t id, const std::vector< byte_t > &m)
|
||||
: msgid(id), msg(m)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
operator>(const InboundMessage &other) const
|
||||
{
|
||||
// order in ascending order for codel queue
|
||||
return msgid > other.msgid;
|
||||
}
|
||||
|
||||
llarp_buffer_t
|
||||
Buffer()
|
||||
{
|
||||
return llarp::Buffer< decltype(msg) >(msg);
|
||||
}
|
||||
|
||||
struct GetTime
|
||||
{
|
||||
llarp_time_t
|
||||
operator()(const InboundMessage *msg)
|
||||
{
|
||||
return msg->queued;
|
||||
}
|
||||
};
|
||||
|
||||
struct OrderCompare
|
||||
{
|
||||
bool
|
||||
operator()(const InboundMessage *left, const InboundMessage *right)
|
||||
{
|
||||
return left->msgid < right->msgid;
|
||||
}
|
||||
};
|
||||
|
||||
struct PutTime
|
||||
{
|
||||
void
|
||||
operator()(InboundMessage *msg)
|
||||
{
|
||||
msg->queued = llarp_time_now_ms();
|
||||
}
|
||||
};
|
||||
};
|
|
@ -0,0 +1,35 @@
|
|||
#pragma once
|
||||
|
||||
#include "llarp/buffer.h"
|
||||
|
||||
#include <queue>
|
||||
|
||||
struct sendbuf_t
|
||||
{
|
||||
sendbuf_t(size_t s) : sz(s)
|
||||
{
|
||||
buf = new byte_t[s];
|
||||
}
|
||||
|
||||
~sendbuf_t()
|
||||
{
|
||||
delete[] buf;
|
||||
}
|
||||
|
||||
byte_t *buf;
|
||||
size_t sz;
|
||||
|
||||
size_t
|
||||
size() const
|
||||
{
|
||||
return sz;
|
||||
}
|
||||
|
||||
byte_t *
|
||||
data()
|
||||
{
|
||||
return buf;
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::queue< sendbuf_t * > sendqueue_t;
|
|
@ -0,0 +1,454 @@
|
|||
#pragma once
|
||||
|
||||
#include "llarp/iwp.h"
|
||||
#include "llarp/iwp/establish_job.hpp"
|
||||
#include "router.hpp"
|
||||
#include "session.hpp"
|
||||
#include "str.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <mutex>
|
||||
|
||||
struct llarp_link
|
||||
{
|
||||
typedef std::mutex mtx_t;
|
||||
typedef std::lock_guard< mtx_t > lock_t;
|
||||
|
||||
llarp_router *router;
|
||||
llarp_crypto *crypto;
|
||||
llarp_logic *logic;
|
||||
llarp_ev_loop *netloop;
|
||||
llarp_async_iwp *iwp;
|
||||
llarp_threadpool *worker;
|
||||
llarp_link *parent = nullptr;
|
||||
llarp_udp_io udp;
|
||||
llarp::Addr addr;
|
||||
char keyfile[255];
|
||||
uint32_t timeout_job_id;
|
||||
|
||||
const char *
|
||||
name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
const char *m_name;
|
||||
|
||||
typedef std::unordered_map< llarp::Addr, llarp_link_session *,
|
||||
llarp::addrhash >
|
||||
LinkMap_t;
|
||||
|
||||
LinkMap_t m_sessions;
|
||||
mtx_t m_sessions_Mutex;
|
||||
|
||||
typedef std::unordered_map< llarp::PubKey, llarp::Addr, llarp::PubKeyHash >
|
||||
SessionMap_t;
|
||||
|
||||
SessionMap_t m_Connected;
|
||||
mtx_t m_Connected_Mutex;
|
||||
|
||||
typedef std::unordered_map< llarp::Addr, llarp_link_session *,
|
||||
llarp::addrhash >
|
||||
PendingSessionMap_t;
|
||||
PendingSessionMap_t m_PendingSessions;
|
||||
mtx_t m_PendingSessions_Mutex;
|
||||
|
||||
llarp::SecretKey seckey;
|
||||
|
||||
llarp_link(const llarp_iwp_args &args)
|
||||
: router(args.router)
|
||||
, crypto(args.crypto)
|
||||
, logic(args.logic)
|
||||
, worker(args.cryptoworker)
|
||||
, m_name("IWP")
|
||||
{
|
||||
strncpy(keyfile, args.keyfile, sizeof(keyfile));
|
||||
iwp = llarp_async_iwp_new(crypto, logic, worker);
|
||||
}
|
||||
|
||||
~llarp_link()
|
||||
{
|
||||
llarp_async_iwp_free(iwp);
|
||||
}
|
||||
|
||||
bool
|
||||
has_intro_from(const llarp::Addr &from)
|
||||
{
|
||||
std::unique_lock< std::mutex > lock(m_PendingSessions_Mutex);
|
||||
return m_PendingSessions.find(from) != m_PendingSessions.end();
|
||||
}
|
||||
|
||||
void
|
||||
put_intro_from(llarp_link_session *s)
|
||||
{
|
||||
std::unique_lock< std::mutex > lock(m_PendingSessions_Mutex);
|
||||
m_PendingSessions[s->addr] = s;
|
||||
}
|
||||
|
||||
void
|
||||
remove_intro_from(const llarp::Addr &from)
|
||||
{
|
||||
std::unique_lock< std::mutex > lock(m_PendingSessions_Mutex);
|
||||
m_PendingSessions.erase(from);
|
||||
}
|
||||
|
||||
// set that src address has identity pubkey
|
||||
void
|
||||
MapAddr(const llarp::Addr &src, const llarp::PubKey &identity)
|
||||
{
|
||||
lock_t lock(m_Connected_Mutex);
|
||||
m_Connected[identity] = src;
|
||||
}
|
||||
|
||||
static bool
|
||||
has_session_to(llarp_link *serv, const byte_t *pubkey)
|
||||
{
|
||||
llarp::PubKey pk(pubkey);
|
||||
lock_t lock(serv->m_Connected_Mutex);
|
||||
return serv->m_Connected.find(pk) != serv->m_Connected.end();
|
||||
}
|
||||
|
||||
void
|
||||
TickSessions()
|
||||
{
|
||||
auto now = llarp_time_now_ms();
|
||||
{
|
||||
lock_t lock(m_sessions_Mutex);
|
||||
std::set< llarp::Addr > remove;
|
||||
for(auto &itr : m_sessions)
|
||||
{
|
||||
llarp_link_session *s = itr.second;
|
||||
if(s && s->Tick(now))
|
||||
remove.insert(itr.first);
|
||||
}
|
||||
|
||||
for(const auto &addr : remove)
|
||||
RemoveSessionByAddr(addr);
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
sendto(llarp_link *serv, const byte_t *pubkey, llarp_buffer_t buf)
|
||||
{
|
||||
// lock_t lock(serv->m_Connected_Mutex);
|
||||
auto itr = serv->m_Connected.find(pubkey);
|
||||
if(itr != serv->m_Connected.end())
|
||||
{
|
||||
// lock_t innerlock(serv->m_sessions_Mutex);
|
||||
auto inner_itr = serv->m_sessions.find(itr->second);
|
||||
if(inner_itr != serv->m_sessions.end())
|
||||
{
|
||||
llarp_link_session *link = inner_itr->second;
|
||||
return link->sendto(buf);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
UnmapAddr(const llarp::Addr &src)
|
||||
{
|
||||
lock_t lock(m_Connected_Mutex);
|
||||
// std::unordered_map< llarp::pubkey, llarp::Addr, llarp::pubkeyhash >
|
||||
auto itr = std::find_if(
|
||||
m_Connected.begin(), m_Connected.end(),
|
||||
[src](const std::pair< llarp::PubKey, llarp::Addr > &item) -> bool {
|
||||
return src == item.second;
|
||||
});
|
||||
if(itr == std::end(m_Connected))
|
||||
return;
|
||||
|
||||
// tell router we are done with this session
|
||||
router->SessionClosed(itr->first);
|
||||
|
||||
m_Connected.erase(itr);
|
||||
}
|
||||
|
||||
llarp_link_session *
|
||||
create_session(llarp::Addr src)
|
||||
{
|
||||
return new llarp_link_session(this, seckey, src);
|
||||
}
|
||||
|
||||
bool
|
||||
has_session_to(const llarp::Addr &dst)
|
||||
{
|
||||
lock_t lock(m_sessions_Mutex);
|
||||
return m_sessions.find(dst) != m_sessions.end();
|
||||
}
|
||||
|
||||
llarp_link_session *
|
||||
find_session(const llarp::Addr &addr)
|
||||
{
|
||||
lock_t lock(m_sessions_Mutex);
|
||||
auto itr = m_sessions.find(addr);
|
||||
if(itr == m_sessions.end())
|
||||
return nullptr;
|
||||
else
|
||||
return itr->second;
|
||||
}
|
||||
|
||||
void
|
||||
put_session(const llarp::Addr &src, llarp_link_session *impl)
|
||||
{
|
||||
lock_t lock(m_sessions_Mutex);
|
||||
m_sessions.emplace(src, impl);
|
||||
impl->our_router = &router->rc;
|
||||
}
|
||||
|
||||
void
|
||||
clear_sessions()
|
||||
{
|
||||
lock_t lock(m_sessions_Mutex);
|
||||
auto itr = m_sessions.begin();
|
||||
while(itr != m_sessions.end())
|
||||
{
|
||||
delete itr->second;
|
||||
itr = m_sessions.erase(itr);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RemoveSessionByAddr(const llarp::Addr &addr)
|
||||
{
|
||||
auto itr = m_sessions.find(addr);
|
||||
if(itr != m_sessions.end())
|
||||
{
|
||||
llarp::LogDebug("removing session ", addr);
|
||||
UnmapAddr(addr);
|
||||
llarp_link_session *s = itr->second;
|
||||
s->done();
|
||||
m_sessions.erase(itr);
|
||||
delete s;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t *
|
||||
pubkey()
|
||||
{
|
||||
return llarp::seckey_topublic(seckey);
|
||||
}
|
||||
|
||||
bool
|
||||
ensure_privkey()
|
||||
{
|
||||
llarp::LogDebug("ensure transport private key at ", keyfile);
|
||||
std::error_code ec;
|
||||
if(!fs::exists(keyfile, ec))
|
||||
{
|
||||
if(!keygen(keyfile))
|
||||
return false;
|
||||
}
|
||||
std::ifstream f(keyfile);
|
||||
if(f.is_open())
|
||||
{
|
||||
f.read((char *)seckey.data(), seckey.size());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
keygen(const char *fname)
|
||||
{
|
||||
crypto->encryption_keygen(seckey);
|
||||
llarp::LogInfo("new transport key generated");
|
||||
std::ofstream f(fname);
|
||||
if(f.is_open())
|
||||
{
|
||||
f.write((char *)seckey.data(), seckey.size());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
handle_cleanup_timer(void *l, uint64_t orig, uint64_t left)
|
||||
{
|
||||
if(left)
|
||||
return;
|
||||
llarp_link *link = static_cast< llarp_link * >(l);
|
||||
link->timeout_job_id = 0;
|
||||
link->TickSessions();
|
||||
link->issue_cleanup_timer(orig);
|
||||
}
|
||||
|
||||
// this is called in net threadpool
|
||||
static void
|
||||
handle_recvfrom(struct llarp_udp_io *udp, const struct sockaddr *saddr,
|
||||
const void *buf, ssize_t sz)
|
||||
{
|
||||
llarp_link *link = static_cast< llarp_link * >(udp->user);
|
||||
|
||||
llarp_link_session *s = link->find_session(*saddr);
|
||||
if(s == nullptr)
|
||||
{
|
||||
// new inbound session
|
||||
s = link->create_session(*saddr);
|
||||
}
|
||||
s->recv(buf, sz);
|
||||
}
|
||||
|
||||
void
|
||||
cancel_timer()
|
||||
{
|
||||
if(timeout_job_id)
|
||||
{
|
||||
llarp_logic_cancel_call(logic, timeout_job_id);
|
||||
}
|
||||
timeout_job_id = 0;
|
||||
}
|
||||
|
||||
void
|
||||
issue_cleanup_timer(uint64_t timeout)
|
||||
{
|
||||
timeout_job_id = llarp_logic_call_later(
|
||||
logic, {timeout, this, &llarp_link::handle_cleanup_timer});
|
||||
}
|
||||
|
||||
void
|
||||
get_our_address(struct llarp_ai *addr)
|
||||
{
|
||||
addr->rank = 1;
|
||||
strncpy(addr->dialect, "IWP", sizeof(addr->dialect));
|
||||
memcpy(addr->enc_key, pubkey(), 32);
|
||||
memcpy(addr->ip.s6_addr, this->addr.addr6(), 16);
|
||||
addr->port = this->addr.port();
|
||||
}
|
||||
|
||||
bool
|
||||
configure(struct llarp_ev_loop *netloop, const char *ifname, int af,
|
||||
uint16_t port)
|
||||
{
|
||||
if(!ensure_privkey())
|
||||
{
|
||||
llarp::LogError("failed to ensure private key");
|
||||
return false;
|
||||
}
|
||||
|
||||
llarp::LogDebug("configure link ifname=", ifname, " af=", af,
|
||||
" port=", port);
|
||||
// bind
|
||||
sockaddr_in ip4addr;
|
||||
sockaddr_in6 ip6addr;
|
||||
sockaddr *addr = nullptr;
|
||||
switch(af)
|
||||
{
|
||||
case AF_INET:
|
||||
addr = (sockaddr *)&ip4addr;
|
||||
llarp::Zero(addr, sizeof(ip4addr));
|
||||
break;
|
||||
case AF_INET6:
|
||||
addr = (sockaddr *)&ip6addr;
|
||||
llarp::Zero(addr, sizeof(ip6addr));
|
||||
break;
|
||||
// TODO: AF_PACKET
|
||||
default:
|
||||
llarp::LogError(__FILE__, "unsupported address family", af);
|
||||
return false;
|
||||
}
|
||||
|
||||
addr->sa_family = af;
|
||||
|
||||
if(!llarp::StrEq(ifname, "*"))
|
||||
{
|
||||
if(!llarp_getifaddr(ifname, af, addr))
|
||||
{
|
||||
llarp::LogError("failed to get address of network interface ", ifname);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
m_name = "OWP"; // outboundLink_name;
|
||||
|
||||
switch(af)
|
||||
{
|
||||
case AF_INET:
|
||||
ip4addr.sin_port = htons(port);
|
||||
break;
|
||||
case AF_INET6:
|
||||
ip6addr.sin6_port = htons(port);
|
||||
break;
|
||||
// TODO: AF_PACKET
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
this->addr = *addr;
|
||||
this->netloop = netloop;
|
||||
udp.recvfrom = &llarp_link::handle_recvfrom;
|
||||
udp.user = this;
|
||||
udp.tick = nullptr;
|
||||
llarp::LogDebug("bind IWP link to ", addr);
|
||||
if(llarp_ev_add_udp(netloop, &udp, addr) == -1)
|
||||
{
|
||||
llarp::LogError("failed to bind to ", addr);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
start_link(struct llarp_logic *logic)
|
||||
{
|
||||
// give link implementations
|
||||
// link->parent = l;
|
||||
timeout_job_id = 0;
|
||||
logic = logic;
|
||||
// start cleanup timer
|
||||
issue_cleanup_timer(500);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
stop_link()
|
||||
{
|
||||
cancel_timer();
|
||||
llarp_ev_close_udp(&udp);
|
||||
clear_sessions();
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
iter_sessions(llarp_link_session_iter iter)
|
||||
{
|
||||
auto sz = m_sessions.size();
|
||||
if(sz)
|
||||
{
|
||||
llarp::LogDebug("we have ", sz, "sessions");
|
||||
iter.link = this;
|
||||
// TODO: race condition with cleanup timer
|
||||
for(auto &item : m_sessions)
|
||||
if(item.second)
|
||||
if(!iter.visit(&iter, item.second))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
try_establish(struct llarp_link_establish_job *job)
|
||||
{
|
||||
llarp::Addr dst(job->ai);
|
||||
llarp::LogDebug("establish session to ", dst);
|
||||
llarp_link_session *s = find_session(dst);
|
||||
if(s == nullptr)
|
||||
{
|
||||
s = create_session(dst);
|
||||
put_session(dst, s);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
s->establish_job = job;
|
||||
s->frame.alive(); // mark it alive
|
||||
s->introduce(job->ai.enc_key);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
mark_session_active(llarp_link_session *s)
|
||||
{
|
||||
s->frame.alive();
|
||||
}
|
||||
};
|
|
@ -0,0 +1,170 @@
|
|||
#pragma once
|
||||
|
||||
#include "codel.hpp"
|
||||
#include "frame_state.hpp"
|
||||
#include "llarp/buffer.h"
|
||||
#include "llarp/crypto.hpp"
|
||||
#include "llarp/crypto_async.h"
|
||||
#include "llarp/router_contact.h"
|
||||
#include "llarp/time.h"
|
||||
#include "llarp/types.h"
|
||||
#include "net.hpp"
|
||||
|
||||
struct llarp_udp_io;
|
||||
struct llarp_async_iwp;
|
||||
struct llarp_logic;
|
||||
struct llarp_link;
|
||||
struct transit_message;
|
||||
struct llarp_link_establish_job;
|
||||
|
||||
struct llarp_link_session
|
||||
{
|
||||
static constexpr llarp_time_t SESSION_TIMEOUT = 10000;
|
||||
static constexpr llarp_time_t KEEP_ALIVE_INTERVAL = SESSION_TIMEOUT / 4;
|
||||
static constexpr size_t MAX_PAD = 128;
|
||||
|
||||
llarp_link_session(llarp_link *l, const byte_t *seckey, const llarp::Addr &a);
|
||||
|
||||
~llarp_link_session();
|
||||
|
||||
void
|
||||
session_start();
|
||||
|
||||
bool sendto(llarp_buffer_t);
|
||||
|
||||
bool
|
||||
has_timed_out();
|
||||
bool
|
||||
timedout(llarp_time_t now, llarp_time_t timeout = SESSION_TIMEOUT);
|
||||
|
||||
void
|
||||
close();
|
||||
|
||||
void
|
||||
session_established();
|
||||
|
||||
llarp_link *
|
||||
get_parent();
|
||||
llarp_rc *
|
||||
get_remote_router();
|
||||
|
||||
bool
|
||||
CheckRCValid();
|
||||
bool
|
||||
IsEstablished();
|
||||
void
|
||||
send_LIM();
|
||||
bool
|
||||
is_invalidated() const;
|
||||
|
||||
void
|
||||
done();
|
||||
void
|
||||
pump();
|
||||
void
|
||||
introduce(uint8_t *pub);
|
||||
|
||||
void
|
||||
intro_ack();
|
||||
void
|
||||
on_intro_ack(const void *buf, size_t sz);
|
||||
void
|
||||
on_intro(const void *buf, size_t sz);
|
||||
void
|
||||
on_session_start(const void *buf, size_t sz);
|
||||
void
|
||||
encrypt_frame_async_send(const void *buf, size_t sz);
|
||||
|
||||
// void send_keepalive(void *user);
|
||||
bool
|
||||
Tick(llarp_time_t now);
|
||||
void
|
||||
PumpCryptoOutbound();
|
||||
|
||||
// this is called from net thread
|
||||
void
|
||||
recv(const void *buf, size_t sz);
|
||||
|
||||
llarp_router *
|
||||
Router();
|
||||
|
||||
llarp_udp_io *udp;
|
||||
llarp_crypto *crypto;
|
||||
llarp_async_iwp *iwp;
|
||||
llarp_logic *logic;
|
||||
|
||||
llarp_link *serv = nullptr;
|
||||
|
||||
llarp_rc *our_router = nullptr;
|
||||
llarp_rc remote_router;
|
||||
|
||||
llarp::SecretKey eph_seckey;
|
||||
llarp::PubKey remote;
|
||||
llarp::SharedSecret sessionkey;
|
||||
|
||||
llarp_link_establish_job *establish_job = nullptr;
|
||||
|
||||
/// cached timestamp for frame creation
|
||||
llarp_time_t now;
|
||||
llarp_time_t lastKeepalive = 0;
|
||||
uint32_t establish_job_id = 0;
|
||||
uint32_t frames = 0;
|
||||
bool working = false;
|
||||
|
||||
llarp::util::CoDelQueue< iwp_async_frame *, FrameGetTime, FramePutTime >
|
||||
outboundFrames;
|
||||
/*
|
||||
std::mutex m_EncryptedFramesMutex;
|
||||
std::queue< iwp_async_frame > encryptedFrames;
|
||||
llarp::util::CoDelQueue< iwp_async_frame *, FrameGetTime, FramePutTime >
|
||||
decryptedFrames;
|
||||
*/
|
||||
|
||||
uint32_t pump_send_timer_id = 0;
|
||||
uint32_t pump_recv_timer_id = 0;
|
||||
|
||||
llarp::Addr addr;
|
||||
iwp_async_intro intro;
|
||||
iwp_async_introack introack;
|
||||
iwp_async_session_start start;
|
||||
// frame_state frame;
|
||||
bool started_inbound_codel = false;
|
||||
|
||||
byte_t token[32];
|
||||
byte_t workbuf[MAX_PAD + 128];
|
||||
|
||||
enum State
|
||||
{
|
||||
eInitial,
|
||||
eIntroRecv,
|
||||
eIntroSent,
|
||||
eIntroAckSent,
|
||||
eIntroAckRecv,
|
||||
eSessionStartSent,
|
||||
eLIMSent,
|
||||
eEstablished,
|
||||
eTimeout
|
||||
};
|
||||
|
||||
State state;
|
||||
void
|
||||
EnterState(State st);
|
||||
|
||||
void
|
||||
add_outbound_message(uint64_t id, transit_message *msg);
|
||||
void
|
||||
EncryptOutboundFrames();
|
||||
iwp_async_frame *
|
||||
alloc_frame(const void *buf, size_t sz);
|
||||
void
|
||||
decrypt_frame(const void *buf, size_t sz);
|
||||
|
||||
frame_state frame;
|
||||
};
|
||||
|
||||
struct llarp_link_session_iter
|
||||
{
|
||||
void *user;
|
||||
struct llarp_link *link;
|
||||
bool (*visit)(struct llarp_link_session_iter *, struct llarp_link_session *);
|
||||
};
|
|
@ -0,0 +1,69 @@
|
|||
#pragma once
|
||||
|
||||
#include "llarp/types.h"
|
||||
#include "sendbuf.hpp"
|
||||
#include "xmit.hpp"
|
||||
|
||||
#include <bitset>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
struct transit_message
|
||||
{
|
||||
xmit msginfo;
|
||||
std::bitset< 32 > status = {};
|
||||
|
||||
typedef std::vector< byte_t > fragment_t;
|
||||
|
||||
std::unordered_map< byte_t, fragment_t > frags;
|
||||
fragment_t lastfrag;
|
||||
llarp_time_t lastAck = 0;
|
||||
llarp_time_t started;
|
||||
|
||||
void
|
||||
clear();
|
||||
|
||||
// calculate acked bitmask
|
||||
uint32_t
|
||||
get_bitmask() const;
|
||||
|
||||
// outbound
|
||||
transit_message(llarp_buffer_t buf, const byte_t *hash, uint64_t id,
|
||||
uint16_t mtu = 1024);
|
||||
|
||||
// inbound
|
||||
transit_message(const xmit &x);
|
||||
|
||||
/// ack packets based off a bitmask
|
||||
void
|
||||
ack(uint32_t bitmask);
|
||||
|
||||
bool
|
||||
should_send_ack(llarp_time_t now) const;
|
||||
|
||||
bool
|
||||
should_resend_xmit(llarp_time_t now) const;
|
||||
bool
|
||||
completed() const;
|
||||
|
||||
// template < typename T >
|
||||
void
|
||||
generate_xmit(sendqueue_t &queue, byte_t flags = 0);
|
||||
|
||||
// template < typename T >
|
||||
void
|
||||
retransmit_frags(sendqueue_t &queue, byte_t flags = 0);
|
||||
|
||||
bool
|
||||
reassemble(std::vector< byte_t > &buffer);
|
||||
|
||||
void
|
||||
put_message(llarp_buffer_t buf, const byte_t *hash, uint64_t id,
|
||||
uint16_t mtu = 1024);
|
||||
|
||||
void
|
||||
put_lastfrag(byte_t *buf, size_t sz);
|
||||
|
||||
bool
|
||||
put_frag(byte_t fragno, byte_t *buf);
|
||||
};
|
|
@ -0,0 +1,43 @@
|
|||
#pragma once
|
||||
|
||||
#include "llarp/buffer.h"
|
||||
|
||||
struct xmit
|
||||
{
|
||||
byte_t buffer[48];
|
||||
|
||||
xmit() = default;
|
||||
|
||||
xmit(byte_t *ptr);
|
||||
|
||||
xmit(const xmit &other);
|
||||
|
||||
void
|
||||
set_info(const byte_t *hash, uint64_t id, uint16_t fragsz, uint16_t lastsz,
|
||||
uint8_t numfrags, uint8_t flags = 0x01);
|
||||
|
||||
const byte_t *
|
||||
hash() const;
|
||||
|
||||
uint64_t
|
||||
msgid() const;
|
||||
|
||||
// size of each full fragment
|
||||
uint16_t
|
||||
fragsize() const;
|
||||
|
||||
// number of full fragments
|
||||
uint8_t
|
||||
numfrags() const;
|
||||
|
||||
// size of the entire message
|
||||
size_t
|
||||
totalsize() const;
|
||||
|
||||
// size of the last fragment
|
||||
uint16_t
|
||||
lastfrag() const;
|
||||
|
||||
uint8_t
|
||||
flags();
|
||||
};
|
|
@ -1,127 +0,0 @@
|
|||
#ifndef LLARP_LINK_H_
|
||||
#define LLARP_LINK_H_
|
||||
#include <llarp/address_info.h>
|
||||
#include <llarp/crypto.h>
|
||||
#include <llarp/ev.h>
|
||||
#include <llarp/logic.h>
|
||||
#include <llarp/mem.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** 2^15 bytes */
|
||||
#define MAX_LINK_MSG_SIZE (32768)
|
||||
|
||||
/**
|
||||
* wire layer transport interface
|
||||
*/
|
||||
struct llarp_link;
|
||||
|
||||
/**
|
||||
* wire layer transport session for point to point communication between us
|
||||
* and another
|
||||
*/
|
||||
struct llarp_link_session;
|
||||
|
||||
/** outbound session establish job */
|
||||
struct llarp_link_establish_job
|
||||
{
|
||||
void *user;
|
||||
void (*result)(struct llarp_link_establish_job *);
|
||||
struct llarp_ai ai;
|
||||
uint64_t timeout;
|
||||
uint16_t retries;
|
||||
|
||||
byte_t pubkey[PUBKEYSIZE];
|
||||
/** set on success by try_establish */
|
||||
struct llarp_link *link;
|
||||
/** set on success by try_establish */
|
||||
struct llarp_link_session *session;
|
||||
};
|
||||
|
||||
struct llarp_link_session_iter
|
||||
{
|
||||
void *user;
|
||||
struct llarp_link *link;
|
||||
bool (*visit)(struct llarp_link_session_iter *, struct llarp_link_session *);
|
||||
};
|
||||
|
||||
struct llarp_link_ev_listener
|
||||
{
|
||||
void *user;
|
||||
void (*established)(struct llarp_link_ev_listener *,
|
||||
struct llarp_link_session *, bool);
|
||||
void (*timeout)(struct llarp_link_ev_listener *, struct llarp_link_session *,
|
||||
bool);
|
||||
void (*tx)(struct llarp_link_ev_listener *, struct llarp_link_session *,
|
||||
size_t);
|
||||
void (*rx)(struct llarp_link_ev_listener *, struct llarp_link_session *,
|
||||
size_t);
|
||||
void (*error)(struct llarp_link_ev_listener *, struct llarp_link_session *,
|
||||
const char *);
|
||||
};
|
||||
|
||||
// forward declare
|
||||
struct llarp_router;
|
||||
|
||||
struct llarp_link
|
||||
{
|
||||
void *impl;
|
||||
struct llarp_router *router;
|
||||
const char *(*name)(void);
|
||||
void (*get_our_address)(struct llarp_link *, struct llarp_ai *);
|
||||
/*
|
||||
int (*register_listener)(struct llarp_link *, struct
|
||||
llarp_link_ev_listener); void (*deregister_listener)(struct llarp_link *,
|
||||
int);
|
||||
*/
|
||||
bool (*configure)(struct llarp_link *, struct llarp_ev_loop *, const char *,
|
||||
int, uint16_t);
|
||||
bool (*start_link)(struct llarp_link *, struct llarp_logic *);
|
||||
bool (*stop_link)(struct llarp_link *);
|
||||
void (*iter_sessions)(struct llarp_link *, struct llarp_link_session_iter);
|
||||
bool (*try_establish)(struct llarp_link *, struct llarp_link_establish_job *);
|
||||
/// send to already established session given its public identity key
|
||||
/// returns false if we don't have this session
|
||||
/// returns true if the messages were queued
|
||||
bool (*sendto)(struct llarp_link *, const byte_t *, llarp_buffer_t);
|
||||
/// return true if we have a session to router given public identity key
|
||||
bool (*has_session_to)(struct llarp_link *, const byte_t *);
|
||||
void (*mark_session_active)(struct llarp_link *, struct llarp_link_session *);
|
||||
void (*free_impl)(struct llarp_link *);
|
||||
};
|
||||
|
||||
/** checks if all members are initialized */
|
||||
bool
|
||||
llarp_link_initialized(struct llarp_link *link);
|
||||
|
||||
struct llarp_link_session
|
||||
{
|
||||
void *impl;
|
||||
/** send an entire message, splits up into smaller pieces and does
|
||||
* encryption
|
||||
*/
|
||||
bool (*sendto)(struct llarp_link_session *, llarp_buffer_t);
|
||||
/** return true if this session is timed out */
|
||||
bool (*timeout)(struct llarp_link_session *);
|
||||
/** explicit close session */
|
||||
void (*close)(struct llarp_link_session *);
|
||||
/** set session established */
|
||||
void (*established)(struct llarp_link_session *);
|
||||
/** get parent link */
|
||||
struct llarp_link *(*get_parent)(struct llarp_link_session *);
|
||||
/** get router contact of remote router */
|
||||
struct llarp_rc *(*get_remote_router)(struct llarp_link_session *);
|
||||
};
|
||||
|
||||
bool
|
||||
llarp_link_session_initialized(struct llarp_link_session *s);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
|
@ -1,13 +1,16 @@
|
|||
#ifndef LLARP_LINK_MESSAGE_HPP
|
||||
#define LLARP_LINK_MESSAGE_HPP
|
||||
|
||||
#include <llarp/link.h>
|
||||
#include <llarp/bencode.hpp>
|
||||
#include <llarp/router_id.hpp>
|
||||
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
|
||||
struct llarp_router;
|
||||
struct llarp_link_session;
|
||||
struct llarp_link_session_iter;
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
struct ILinkMessage;
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
#ifndef LLARP_LOGGER_H
|
||||
#define LLARP_LOGGER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum LogLevel
|
||||
{
|
||||
eLogDebug,
|
||||
|
@ -16,8 +12,4 @@ enum LogLevel
|
|||
void
|
||||
cSetLogLevel(enum LogLevel lvl);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,11 +3,12 @@
|
|||
#include <llarp/mem.h>
|
||||
#include <llarp/threadpool.h>
|
||||
#include <llarp/timer.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct llarp_logic;
|
||||
struct llarp_logic
|
||||
{
|
||||
struct llarp_threadpool* thread;
|
||||
struct llarp_timer_context* timer;
|
||||
};
|
||||
|
||||
struct llarp_logic*
|
||||
llarp_init_logic();
|
||||
|
@ -40,7 +41,4 @@ llarp_logic_stop(struct llarp_logic* logic);
|
|||
void
|
||||
llarp_logic_mainloop(struct llarp_logic* logic);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -4,16 +4,8 @@
|
|||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** constant time memcmp */
|
||||
bool
|
||||
llarp_eq(const void *a, const void *b, size_t sz);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -22,6 +22,6 @@ namespace llarp
|
|||
bool
|
||||
HandleMessage(llarp_router* router) const;
|
||||
};
|
||||
}
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
||||
|
|
|
@ -7,14 +7,7 @@
|
|||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
bool
|
||||
llarp_getifaddr(const char* ifname, int af, struct sockaddr* addr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -10,10 +10,6 @@
|
|||
* persistent storage API for router contacts
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct llarp_nodedb;
|
||||
|
||||
/// create an empty nodedb
|
||||
|
@ -139,7 +135,4 @@ struct llarp_async_load_rc
|
|||
void
|
||||
llarp_nodedb_async_load_rc(struct llarp_async_load_rc *job);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -7,10 +7,6 @@
|
|||
#define DEFAULT_PATH_LIFETIME (10 * 60 * 1000)
|
||||
#define PATH_BUILD_TIMEOUT (30 * 1000)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct llarp_path_hop
|
||||
{
|
||||
struct llarp_rc router;
|
||||
|
@ -28,7 +24,4 @@ struct llarp_path_hops
|
|||
void
|
||||
llarp_path_hops_free(struct llarp_path_hops* hops);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
|
@ -10,10 +10,6 @@
|
|||
* path api functions
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/// forard declare
|
||||
struct llarp_router;
|
||||
struct llarp_dht_context;
|
||||
|
@ -62,7 +58,4 @@ struct llarp_pathbuild_job
|
|||
void
|
||||
llarp_pathbuilder_build_path(struct llarp_pathbuild_job* job);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
#ifndef LLARP_QUIC_H_
|
||||
#define LLARP_QUIC_H_
|
||||
|
||||
#include <llarp/link.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "llarp/iwp/server.h"
|
||||
|
||||
struct llarp_quic_args
|
||||
{
|
||||
|
@ -15,7 +11,4 @@ bool
|
|||
quic_link_init(struct llarp_link* link, struct llarp_quic_args args,
|
||||
struct llarp_msg_muxer* muxer);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -2,17 +2,12 @@
|
|||
#define LLARP_ROUTER_H_
|
||||
#include <llarp/config.h>
|
||||
#include <llarp/ev.h>
|
||||
#include <llarp/link.h>
|
||||
#include <llarp/logic.h>
|
||||
#include <llarp/nodedb.h>
|
||||
#include <llarp/pathbuilder.h>
|
||||
#include <llarp/router_contact.h>
|
||||
#include <llarp/threadpool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct llarp_router;
|
||||
|
||||
bool
|
||||
|
@ -54,8 +49,4 @@ void
|
|||
llarp_router_iterate_links(struct llarp_router *router,
|
||||
struct llarp_router_link_iter iter);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,9 +3,6 @@
|
|||
#include <llarp/address_info.h>
|
||||
#include <llarp/crypto.h>
|
||||
#include <llarp/exit_info.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// forward declare
|
||||
struct llarp_alloc;
|
||||
|
@ -29,7 +26,6 @@ struct llarp_rc
|
|||
byte_t signature[SIGSIZE];
|
||||
uint64_t last_updated;
|
||||
|
||||
#ifdef __cplusplus
|
||||
bool
|
||||
BEncode(llarp_buffer_t *buf) const
|
||||
{
|
||||
|
@ -41,7 +37,6 @@ struct llarp_rc
|
|||
{
|
||||
return llarp_rc_bdecode(this, buf);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -87,7 +82,4 @@ llarp_rc_read(const char *fpath);
|
|||
bool
|
||||
llarp_rc_write(struct llarp_rc *rc, const char *our_rc_file);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -16,23 +16,23 @@ namespace llarp
|
|||
struct IMessageHandler
|
||||
{
|
||||
virtual bool
|
||||
HandlePathTransferMessage(const PathTransferMessage* msg,
|
||||
llarp_router* r) = 0;
|
||||
HandlePathTransferMessage(const PathTransferMessage *msg,
|
||||
llarp_router *r) = 0;
|
||||
|
||||
virtual bool
|
||||
HandleHiddenServiceData(llarp_buffer_t buf, llarp_router* r) = 0;
|
||||
HandleHiddenServiceData(llarp_buffer_t buf, llarp_router *r) = 0;
|
||||
|
||||
virtual bool
|
||||
HandlePathConfirmMessage(const PathConfirmMessage* msg,
|
||||
llarp_router* r) = 0;
|
||||
HandlePathConfirmMessage(const PathConfirmMessage *msg,
|
||||
llarp_router *r) = 0;
|
||||
|
||||
virtual bool
|
||||
HandlePathLatencyMessage(const PathLatencyMessage* msg,
|
||||
llarp_router* r) = 0;
|
||||
HandlePathLatencyMessage(const PathLatencyMessage *msg,
|
||||
llarp_router *r) = 0;
|
||||
|
||||
virtual bool
|
||||
|
||||
HandleDHTMessage(const llarp::dht::IMessage* msg, llarp_router* r) = 0;
|
||||
HandleDHTMessage(const llarp::dht::IMessage *msg, llarp_router *r) = 0;
|
||||
};
|
||||
} // namespace routing
|
||||
} // namespace llarp
|
||||
|
|
|
@ -13,6 +13,6 @@ namespace llarp
|
|||
{
|
||||
virtual ~IRoutingEndpoint(){};
|
||||
};
|
||||
}
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
|
@ -1,9 +1,6 @@
|
|||
#ifndef LLARP_STRING_H
|
||||
#define LLARP_STRING_H
|
||||
#include <llarp/common.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
#if !(__APPLE__ && __MACH__)
|
||||
|
@ -18,7 +15,4 @@ strnlen(const char* str, size_t sz)
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
#ifndef LLARP_THREADPOOL_H
|
||||
#define LLARP_THREADPOOL_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct llarp_threadpool;
|
||||
|
||||
|
@ -26,8 +23,6 @@ struct llarp_thread_job
|
|||
/** called in threadpool worker thread */
|
||||
llarp_thread_work_func work;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
llarp_thread_job(void *u, llarp_thread_work_func w) : user(u), work(w)
|
||||
{
|
||||
}
|
||||
|
@ -35,8 +30,6 @@ struct llarp_thread_job
|
|||
llarp_thread_job() : user(nullptr), work(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
/// for single process mode
|
||||
|
@ -55,8 +48,4 @@ llarp_threadpool_join(struct llarp_threadpool *tp);
|
|||
void
|
||||
llarp_threadpool_wait(struct llarp_threadpool *tp);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,16 +1,10 @@
|
|||
#ifndef LLARP_TIME_H
|
||||
#define LLARP_TIME_H
|
||||
#include <llarp/types.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
llarp_time_t
|
||||
llarp_time_now_ms();
|
||||
llarp_seconds_t
|
||||
llarp_time_now_sec();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -2,9 +2,6 @@
|
|||
#define LLARP_TIMER_H
|
||||
#include <llarp/common.h>
|
||||
#include <llarp/threadpool.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** called with userptr, original timeout, left */
|
||||
typedef void (*llarp_timer_handler_func)(void *, uint64_t, uint64_t);
|
||||
|
@ -47,7 +44,4 @@ llarp_timer_tick_all(struct llarp_timer_context *t,
|
|||
void
|
||||
llarp_free_timer(struct llarp_timer_context **t);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -2,15 +2,8 @@
|
|||
#define LLARP_TYPES_H
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef uint8_t llarp_proto_version_t;
|
||||
typedef uint64_t llarp_time_t;
|
||||
typedef uint64_t llarp_seconds_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -117,8 +117,6 @@ llarp_ai_list_iter_bencode(struct llarp_ai_list_iter *iter, struct llarp_ai *ai)
|
|||
return llarp_ai_bencode(ai, static_cast< llarp_buffer_t * >(iter->user));
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
bool
|
||||
llarp_ai_bdecode(struct llarp_ai *ai, llarp_buffer_t *buff)
|
||||
{
|
||||
|
@ -261,4 +259,3 @@ llarp_ai_list_bdecode(struct llarp_ai_list *l, llarp_buffer_t *buff)
|
|||
.buffer = nullptr, .user = l, .on_item = &llarp_ai_list_bdecode_item};
|
||||
return bencode_read_list(buff, &r);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
size_t
|
||||
llarp_buffer_size_left(llarp_buffer_t buff)
|
||||
{
|
||||
|
@ -78,4 +76,3 @@ llarp_buffer_eq(llarp_buffer_t buf, const char* str)
|
|||
}
|
||||
return *str == 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,6 @@ namespace llarp
|
|||
buff.sz = t.size();
|
||||
return buff;
|
||||
}
|
||||
}
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef LLARP_CODEL_QUEUE_HPP
|
||||
#define LLARP_CODEL_QUEUE_HPP
|
||||
#include <llarp/time.h>
|
||||
#include "llarp/logger.hpp"
|
||||
|
||||
#include <cmath>
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
|
|
|
@ -35,8 +35,6 @@ namespace llarp
|
|||
|
||||
} // namespace llarp
|
||||
|
||||
extern "C" {
|
||||
|
||||
void
|
||||
llarp_new_config(struct llarp_config **conf)
|
||||
{
|
||||
|
@ -78,4 +76,3 @@ llarp_config_iter(struct llarp_config *conf, struct llarp_config_iterator *iter)
|
|||
iter->visit(iter, section.first.c_str(), item.first.c_str(),
|
||||
item.second.c_str());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,11 +22,9 @@ namespace llarp
|
|||
};
|
||||
} // namespace llarp
|
||||
|
||||
extern "C" {
|
||||
struct llarp_config
|
||||
{
|
||||
llarp::Config impl;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -298,7 +298,6 @@ namespace llarp
|
|||
}
|
||||
} // namespace llarp
|
||||
|
||||
extern "C" {
|
||||
struct llarp_main
|
||||
{
|
||||
std::unique_ptr< llarp::Context > ctx;
|
||||
|
@ -436,4 +435,3 @@ llarp_main_free(struct llarp_main *ptr)
|
|||
{
|
||||
delete ptr;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -345,7 +345,6 @@ namespace iwp
|
|||
}
|
||||
} // namespace iwp
|
||||
|
||||
extern "C" {
|
||||
void
|
||||
iwp_call_async_keygen(struct llarp_async_iwp *iwp,
|
||||
struct iwp_async_keygen *keygen)
|
||||
|
@ -490,4 +489,3 @@ llarp_async_iwp_free(struct llarp_async_iwp *iwp)
|
|||
{
|
||||
delete iwp;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -131,7 +131,6 @@ namespace llarp
|
|||
|
||||
} // namespace llarp
|
||||
|
||||
extern "C" {
|
||||
const byte_t *
|
||||
llarp_seckey_topublic(const byte_t *secret)
|
||||
{
|
||||
|
@ -160,4 +159,3 @@ llarp_crypto_libsodium_init(struct llarp_crypto *c)
|
|||
c->randbytes(&seed, sizeof(seed));
|
||||
srand(seed);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -805,7 +805,6 @@ llarp_dht_context::llarp_dht_context(llarp_router *router)
|
|||
parent = router;
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
struct llarp_dht_context *
|
||||
llarp_dht_context_new(struct llarp_router *router)
|
||||
{
|
||||
|
@ -861,4 +860,3 @@ llarp_dht_lookup_router(struct llarp_dht_context *ctx,
|
|||
llarp_logic_queue_job(ctx->parent->logic,
|
||||
{job, &llarp::dht::Context::queue_router_lookup});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,4 +24,4 @@ namespace llarp
|
|||
src += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace llarp
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include "ev_kqueue.hpp"
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
void
|
||||
llarp_ev_loop_alloc(struct llarp_ev_loop **ev)
|
||||
{
|
||||
|
@ -85,4 +84,3 @@ llarp_ev_udp_sendto(struct llarp_udp_io *udp, const sockaddr *to,
|
|||
{
|
||||
return static_cast< llarp::ev_io * >(udp->impl)->sendto(to, buf, sz);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,8 +10,6 @@ struct llarp_xi_list
|
|||
std::list< llarp_xi > list;
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
|
||||
struct llarp_xi_list *
|
||||
llarp_xi_list_new()
|
||||
{
|
||||
|
@ -188,4 +186,3 @@ llarp_xi_list_bdecode(struct llarp_xi_list *l, llarp_buffer_t *buff)
|
|||
list_reader r = {buff, l, &llarp_xi_list_decode_item};
|
||||
return bencode_read_list(buff, &r);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
#include "llarp/iwp/frame_header.hpp"
|
||||
|
||||
frame_header::frame_header(byte_t *buf) : ptr(buf)
|
||||
{
|
||||
}
|
||||
|
||||
byte_t *
|
||||
frame_header::data()
|
||||
{
|
||||
return ptr + 6;
|
||||
}
|
||||
|
||||
uint8_t &
|
||||
frame_header::version()
|
||||
{
|
||||
return ptr[0];
|
||||
}
|
||||
|
||||
uint8_t &
|
||||
frame_header::msgtype()
|
||||
{
|
||||
return ptr[1];
|
||||
}
|
||||
|
||||
uint16_t
|
||||
frame_header::size() const
|
||||
{
|
||||
uint16_t sz;
|
||||
memcpy(&sz, ptr + 2, 2);
|
||||
return sz;
|
||||
}
|
||||
|
||||
void
|
||||
frame_header::setsize(uint16_t sz)
|
||||
{
|
||||
memcpy(ptr + 2, &sz, 2);
|
||||
}
|
||||
|
||||
uint8_t &
|
||||
frame_header::flags()
|
||||
{
|
||||
return ptr[5];
|
||||
}
|
||||
|
||||
void
|
||||
frame_header::setflag(header_flag f)
|
||||
{
|
||||
ptr[5] |= f;
|
||||
}
|
|
@ -0,0 +1,378 @@
|
|||
#include "llarp/iwp/frame_state.hpp"
|
||||
#include "llarp/iwp/inbound_message.hpp"
|
||||
#include "llarp/iwp/session.hpp"
|
||||
|
||||
#include "buffer.hpp"
|
||||
#include "llarp/crypto.hpp"
|
||||
#include "llarp/logger.hpp"
|
||||
#include "router.hpp"
|
||||
|
||||
llarp_router *
|
||||
frame_state::Router()
|
||||
{
|
||||
return parent->Router();
|
||||
}
|
||||
|
||||
bool
|
||||
frame_state::process_inbound_queue()
|
||||
{
|
||||
std::priority_queue< InboundMessage *, std::vector< InboundMessage * >,
|
||||
InboundMessage::OrderCompare >
|
||||
q;
|
||||
recvqueue.Process(q);
|
||||
bool increment = false;
|
||||
while(q.size())
|
||||
{
|
||||
// TODO: is this right?
|
||||
auto &front = q.top();
|
||||
// the items are already sorted anyways so this doesn't really do much
|
||||
nextMsgID = std::max(nextMsgID, front->msgid);
|
||||
if(!Router()->HandleRecvLinkMessage(parent, front->Buffer()))
|
||||
{
|
||||
llarp::LogWarn("failed to process inbound message ", front->msgid);
|
||||
}
|
||||
delete front;
|
||||
q.pop();
|
||||
increment = true;
|
||||
}
|
||||
if(increment)
|
||||
++nextMsgID;
|
||||
// TODO: this isn't right
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
frame_state::flags_agree(byte_t flags) const
|
||||
{
|
||||
return ((rxflags & flags) & (txflags & flags)) == flags;
|
||||
}
|
||||
|
||||
void
|
||||
frame_state::clear()
|
||||
{
|
||||
auto _rx = rx;
|
||||
auto _tx = tx;
|
||||
for(auto &item : _rx)
|
||||
delete item.second;
|
||||
for(auto &item : _tx)
|
||||
delete item.second;
|
||||
rx.clear();
|
||||
tx.clear();
|
||||
}
|
||||
|
||||
bool
|
||||
frame_state::got_xmit(frame_header hdr, size_t sz)
|
||||
{
|
||||
if(hdr.size() > sz)
|
||||
{
|
||||
// overflow
|
||||
llarp::LogWarn("invalid XMIT frame size ", hdr.size(), " > ", sz);
|
||||
return false;
|
||||
}
|
||||
sz = hdr.size();
|
||||
|
||||
// extract xmit data
|
||||
xmit x(hdr.data());
|
||||
|
||||
const auto bufsz = sizeof(x.buffer);
|
||||
|
||||
if(sz - bufsz < x.lastfrag())
|
||||
{
|
||||
// bad size of last fragment
|
||||
llarp::LogWarn("XMIT frag size missmatch ", sz - bufsz, " < ",
|
||||
x.lastfrag());
|
||||
return false;
|
||||
}
|
||||
|
||||
// check LSB set on flags
|
||||
if(x.flags() & 0x01)
|
||||
{
|
||||
auto id = x.msgid();
|
||||
auto itr = rx.find(id);
|
||||
if(itr == rx.end())
|
||||
{
|
||||
auto msg = new transit_message(x);
|
||||
rx[id] = msg;
|
||||
llarp::LogDebug("got message XMIT with ", (int)x.numfrags(),
|
||||
" fragments");
|
||||
// inserted, put last fragment
|
||||
msg->put_lastfrag(hdr.data() + sizeof(x.buffer), x.lastfrag());
|
||||
push_ackfor(id, 0);
|
||||
if(x.numfrags() == 0)
|
||||
{
|
||||
return inbound_frame_complete(id);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
llarp::LogWarn("duplicate XMIT msgid=", x.msgid());
|
||||
}
|
||||
else
|
||||
llarp::LogWarn("LSB not set on flags");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
frame_state::got_frag(frame_header hdr, size_t sz)
|
||||
{
|
||||
if(hdr.size() > sz)
|
||||
{
|
||||
// overflow
|
||||
llarp::LogWarn("invalid FRAG frame size ", hdr.size(), " > ", sz);
|
||||
return false;
|
||||
}
|
||||
sz = hdr.size();
|
||||
|
||||
if(sz <= 9)
|
||||
{
|
||||
// underflow
|
||||
llarp::LogWarn("invalid FRAG frame size ", sz, " <= 9");
|
||||
return false;
|
||||
}
|
||||
|
||||
uint64_t msgid;
|
||||
byte_t fragno;
|
||||
// assumes big endian
|
||||
// TODO: implement little endian
|
||||
memcpy(&msgid, hdr.data(), 8);
|
||||
memcpy(&fragno, hdr.data() + 8, 1);
|
||||
|
||||
auto itr = rx.find(msgid);
|
||||
if(itr == rx.end())
|
||||
{
|
||||
llarp::LogWarn("no such RX fragment, msgid=", msgid);
|
||||
return true;
|
||||
}
|
||||
auto fragsize = itr->second->msginfo.fragsize();
|
||||
if(fragsize != sz - 9)
|
||||
{
|
||||
llarp::LogWarn("RX fragment size missmatch ", fragsize, " != ", sz - 9);
|
||||
return false;
|
||||
}
|
||||
llarp::LogDebug("RX got fragment ", (int)fragno, " msgid=", msgid);
|
||||
if(!itr->second->put_frag(fragno, hdr.data() + 9))
|
||||
{
|
||||
llarp::LogWarn("inbound message does not have fragment msgid=", msgid,
|
||||
" fragno=", (int)fragno);
|
||||
return false;
|
||||
}
|
||||
auto mask = itr->second->get_bitmask();
|
||||
if(itr->second->completed())
|
||||
{
|
||||
push_ackfor(msgid, mask);
|
||||
return inbound_frame_complete(msgid);
|
||||
}
|
||||
else if(itr->second->should_send_ack(llarp_time_now_ms()))
|
||||
{
|
||||
push_ackfor(msgid, mask);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
frame_state::push_ackfor(uint64_t id, uint32_t bitmask)
|
||||
{
|
||||
llarp::LogDebug("ACK for msgid=", id, " mask=", bitmask);
|
||||
sendqueue.push(new sendbuf_t(12 + 6));
|
||||
auto body_ptr = init_sendbuf(sendqueue.back(), eACKS, 12, txflags);
|
||||
// TODO: this assumes big endian
|
||||
memcpy(body_ptr, &id, 8);
|
||||
memcpy(body_ptr + 8, &bitmask, 4);
|
||||
}
|
||||
|
||||
bool
|
||||
frame_state::inbound_frame_complete(uint64_t id)
|
||||
{
|
||||
bool success = false;
|
||||
std::vector< byte_t > msg;
|
||||
auto rxmsg = rx[id];
|
||||
if(rxmsg->reassemble(msg))
|
||||
{
|
||||
auto router = Router();
|
||||
llarp::ShortHash digest;
|
||||
auto buf = llarp::Buffer< decltype(msg) >(msg);
|
||||
router->crypto.shorthash(digest, buf);
|
||||
if(memcmp(digest, rxmsg->msginfo.hash(), 32))
|
||||
{
|
||||
llarp::LogWarn("message hash missmatch ",
|
||||
llarp::AlignedBuffer< 32 >(digest),
|
||||
" != ", llarp::AlignedBuffer< 32 >(rxmsg->msginfo.hash()));
|
||||
return false;
|
||||
}
|
||||
if(id == nextMsgID)
|
||||
{
|
||||
llarp_link_session *impl = parent;
|
||||
|
||||
if(id == 0)
|
||||
{
|
||||
success = router->HandleRecvLinkMessage(parent, buf);
|
||||
if(impl->CheckRCValid())
|
||||
{
|
||||
if(!impl->IsEstablished())
|
||||
{
|
||||
impl->send_LIM();
|
||||
impl->session_established();
|
||||
}
|
||||
++nextMsgID;
|
||||
}
|
||||
else
|
||||
{
|
||||
llarp::PubKey k = impl->remote_router.pubkey;
|
||||
llarp::LogWarn("spoofed LIM from ", k);
|
||||
impl->close();
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
recvqueue.Put(new InboundMessage(id, msg));
|
||||
success = process_inbound_queue();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
llarp::LogWarn("out of order message expected ", nextMsgID, " but got ",
|
||||
id);
|
||||
recvqueue.Put(new InboundMessage(id, msg));
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
delete rxmsg;
|
||||
rx.erase(id);
|
||||
|
||||
if(!success)
|
||||
llarp::LogWarn("Failed to process inbound message ", id);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool
|
||||
frame_state::got_acks(frame_header hdr, size_t sz)
|
||||
{
|
||||
if(hdr.size() > sz)
|
||||
{
|
||||
llarp::LogError("invalid ACKS frame size ", hdr.size(), " > ", sz);
|
||||
return false;
|
||||
}
|
||||
sz = hdr.size();
|
||||
if(sz < 12)
|
||||
{
|
||||
llarp::LogError("invalid ACKS frame size ", sz, " < 12");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto ptr = hdr.data();
|
||||
uint64_t msgid;
|
||||
uint32_t bitmask;
|
||||
memcpy(&msgid, ptr, 8);
|
||||
memcpy(&bitmask, ptr + 8, 4);
|
||||
|
||||
auto itr = tx.find(msgid);
|
||||
if(itr == tx.end())
|
||||
{
|
||||
llarp::LogDebug("ACK for missing TX frame msgid=", msgid);
|
||||
return true;
|
||||
}
|
||||
|
||||
transit_message *msg = itr->second;
|
||||
|
||||
msg->ack(bitmask);
|
||||
|
||||
if(msg->completed())
|
||||
{
|
||||
llarp::LogDebug("message transmitted msgid=", msgid);
|
||||
tx.erase(msgid);
|
||||
delete msg;
|
||||
}
|
||||
else
|
||||
{
|
||||
llarp::LogDebug("message ", msgid, " retransmit fragments");
|
||||
msg->retransmit_frags(sendqueue, txflags);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
frame_state::process(byte_t *buf, size_t sz)
|
||||
{
|
||||
frame_header hdr(buf);
|
||||
if(hdr.flags() & eSessionInvalidated)
|
||||
{
|
||||
rxflags |= eSessionInvalidated;
|
||||
}
|
||||
switch(hdr.msgtype())
|
||||
{
|
||||
case eALIV:
|
||||
llarp::LogDebug("iwp_link::frame_state::process Got alive");
|
||||
if(rxflags & eSessionInvalidated)
|
||||
{
|
||||
txflags |= eSessionInvalidated;
|
||||
}
|
||||
return true;
|
||||
case eXMIT:
|
||||
llarp::LogDebug("iwp_link::frame_state::process Got xmit");
|
||||
return got_xmit(hdr, sz - 6);
|
||||
case eACKS:
|
||||
llarp::LogDebug("iwp_link::frame_state::process Got ack");
|
||||
return got_acks(hdr, sz - 6);
|
||||
case msgtype::eFRAG:
|
||||
llarp::LogDebug("iwp_link::frame_state::process Got frag");
|
||||
return got_frag(hdr, sz - 6);
|
||||
default:
|
||||
llarp::LogWarn(
|
||||
"iwp_link::frame_state::process - unknown header message type: ",
|
||||
(int)hdr.msgtype());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
frame_state::next_frame(llarp_buffer_t *buf)
|
||||
{
|
||||
auto left = sendqueue.size();
|
||||
llarp::LogDebug("next frame, ", left, " frames left in send queue");
|
||||
if(left)
|
||||
{
|
||||
sendbuf_t *send = sendqueue.front();
|
||||
buf->base = send->data();
|
||||
buf->cur = send->data();
|
||||
buf->sz = send->size();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
frame_state::pop_next_frame()
|
||||
{
|
||||
sendbuf_t *buf = sendqueue.front();
|
||||
sendqueue.pop();
|
||||
delete buf;
|
||||
}
|
||||
|
||||
void
|
||||
frame_state::queue_tx(uint64_t id, transit_message *msg)
|
||||
{
|
||||
tx.insert(std::make_pair(id, msg));
|
||||
msg->generate_xmit(sendqueue, txflags);
|
||||
}
|
||||
|
||||
void
|
||||
frame_state::retransmit(llarp_time_t now)
|
||||
{
|
||||
for(auto &item : tx)
|
||||
{
|
||||
if(item.second->should_resend_xmit(now))
|
||||
{
|
||||
item.second->generate_xmit(sendqueue, txflags);
|
||||
}
|
||||
item.second->retransmit_frags(sendqueue, txflags);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
frame_state::alive()
|
||||
{
|
||||
lastEvent = llarp_time_now_ms();
|
||||
}
|
|
@ -0,0 +1,789 @@
|
|||
#include <llarp/crypto.hpp>
|
||||
#include <llarp/iwp/server.hpp>
|
||||
#include <llarp/iwp/session.hpp>
|
||||
#include "address_info.hpp"
|
||||
#include "buffer.hpp"
|
||||
#include "link/encoder.hpp"
|
||||
|
||||
#include "llarp/ev.h" // for handle_frame_encrypt
|
||||
|
||||
static void
|
||||
handle_crypto_outbound(void *u)
|
||||
{
|
||||
llarp_link_session *self = static_cast< llarp_link_session * >(u);
|
||||
self->EncryptOutboundFrames();
|
||||
self->working = false;
|
||||
}
|
||||
|
||||
// TODO: move this orphan function?
|
||||
static void
|
||||
handle_frame_encrypt(iwp_async_frame *frame)
|
||||
{
|
||||
llarp_link_session *self = static_cast< llarp_link_session * >(frame->user);
|
||||
llarp::LogDebug("tx ", frame->sz);
|
||||
if(llarp_ev_udp_sendto(self->udp, self->addr, frame->buf, frame->sz) == -1)
|
||||
llarp::LogWarn("sendto failed");
|
||||
}
|
||||
|
||||
llarp_link_session::llarp_link_session(llarp_link *l, const byte_t *seckey,
|
||||
const llarp::Addr &a)
|
||||
: udp(&l->udp)
|
||||
, crypto(&l->router->crypto)
|
||||
, iwp(l->iwp)
|
||||
, logic(l->router->logic)
|
||||
, serv(l)
|
||||
, outboundFrames("iwp_outbound")
|
||||
//, decryptedFrames("iwp_inbound")
|
||||
, addr(a)
|
||||
, state(eInitial)
|
||||
, frame(this)
|
||||
{
|
||||
if(seckey)
|
||||
eph_seckey = seckey;
|
||||
else
|
||||
crypto->encryption_keygen(eph_seckey);
|
||||
llarp_rc_clear(&remote_router);
|
||||
crypto->randbytes(token, 32);
|
||||
llarp::LogInfo("session created");
|
||||
}
|
||||
|
||||
llarp_link_session::~llarp_link_session()
|
||||
{
|
||||
llarp_rc_free(&remote_router);
|
||||
frame.clear();
|
||||
}
|
||||
|
||||
llarp_router *
|
||||
llarp_link_session::Router()
|
||||
{
|
||||
return serv->router;
|
||||
}
|
||||
|
||||
bool
|
||||
llarp_link_session::sendto(llarp_buffer_t msg)
|
||||
{
|
||||
auto id = frame.txids++;
|
||||
// llarp::LogDebug("session sending to, number", id);
|
||||
llarp::ShortHash digest;
|
||||
crypto->shorthash(digest, msg);
|
||||
transit_message *m = new transit_message(msg, digest, id);
|
||||
add_outbound_message(id, m);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
llarp_link_session::timedout(llarp_time_t now, llarp_time_t timeout)
|
||||
{
|
||||
auto diff = now - frame.lastEvent;
|
||||
return diff >= timeout;
|
||||
}
|
||||
|
||||
bool
|
||||
llarp_link_session::has_timed_out()
|
||||
{
|
||||
auto now = llarp_time_now_ms();
|
||||
return timedout(now);
|
||||
}
|
||||
|
||||
static void
|
||||
send_keepalive(void *user)
|
||||
{
|
||||
llarp_link_session *self = static_cast< llarp_link_session * >(user);
|
||||
// if both sides agree on invalidation
|
||||
if(self->is_invalidated())
|
||||
{
|
||||
// don't send keepalive
|
||||
llarp::LogInfo("session cant send keepalive because were invalid");
|
||||
return;
|
||||
}
|
||||
// all zeros means keepalive
|
||||
byte_t tmp[8] = {0};
|
||||
// set flags for tx
|
||||
frame_header hdr(tmp);
|
||||
hdr.flags() = self->frame.txflags;
|
||||
|
||||
// send frame after encrypting
|
||||
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
|
||||
self->now = llarp_time_now_ms();
|
||||
self->lastKeepalive = self->now;
|
||||
self->encrypt_frame_async_send(buf.base, buf.sz);
|
||||
self->pump();
|
||||
self->PumpCryptoOutbound();
|
||||
}
|
||||
|
||||
void
|
||||
llarp_link_session::close()
|
||||
{
|
||||
// set our side invalidated and close async when the other side also marks
|
||||
// as session invalidated
|
||||
frame.txflags |= eSessionInvalidated;
|
||||
// TODO: add timer for session invalidation
|
||||
llarp_logic_queue_job(logic, {this, &send_keepalive});
|
||||
}
|
||||
|
||||
void
|
||||
llarp_link_session::session_established()
|
||||
{
|
||||
llarp::RouterID remote = remote_router.pubkey;
|
||||
llarp::LogInfo("Session to ", remote, " established");
|
||||
EnterState(eEstablished);
|
||||
serv->MapAddr(addr, remote_router.pubkey);
|
||||
llarp_logic_cancel_call(logic, establish_job_id);
|
||||
}
|
||||
|
||||
llarp_rc *
|
||||
llarp_link_session::get_remote_router()
|
||||
{
|
||||
return &remote_router;
|
||||
}
|
||||
|
||||
void
|
||||
llarp_link_session::add_outbound_message(uint64_t id, transit_message *msg)
|
||||
{
|
||||
llarp::LogDebug("add outbound message ", id, " of size ",
|
||||
msg->msginfo.totalsize(),
|
||||
" numfrags=", (int)msg->msginfo.numfrags(),
|
||||
" lastfrag=", (int)msg->msginfo.lastfrag());
|
||||
|
||||
frame.queue_tx(id, msg);
|
||||
pump();
|
||||
PumpCryptoOutbound();
|
||||
}
|
||||
|
||||
bool
|
||||
llarp_link_session::CheckRCValid()
|
||||
{
|
||||
// verify signatuire
|
||||
if(!llarp_rc_verify_sig(crypto, &remote_router))
|
||||
return false;
|
||||
|
||||
auto &list = remote_router.addrs->list;
|
||||
if(list.size() == 0) // the remote node is a client node so accept it
|
||||
return true;
|
||||
// check if the RC owns a pubkey that we are using
|
||||
for(auto &ai : list)
|
||||
{
|
||||
if(memcmp(ai.enc_key, remote, PUBKEYSIZE) == 0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
llarp_link_session::IsEstablished()
|
||||
{
|
||||
return state == eEstablished;
|
||||
}
|
||||
|
||||
void
|
||||
llarp_link_session::send_LIM()
|
||||
{
|
||||
llarp::LogDebug("send LIM");
|
||||
llarp::ShortHash digest;
|
||||
// 64 bytes overhead for link message
|
||||
byte_t tmp[MAX_RC_SIZE + 64];
|
||||
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
|
||||
// return a llarp_buffer_t of encoded link message
|
||||
if(llarp::EncodeLIM(&buf, our_router))
|
||||
{
|
||||
// rewind message buffer
|
||||
buf.sz = buf.cur - buf.base;
|
||||
buf.cur = buf.base;
|
||||
// hash message buffer
|
||||
crypto->shorthash(digest, buf);
|
||||
auto id = frame.txids++;
|
||||
auto msg = new transit_message(buf, digest, id);
|
||||
// put into outbound send queue
|
||||
add_outbound_message(id, msg);
|
||||
// enter state
|
||||
EnterState(eLIMSent);
|
||||
}
|
||||
else
|
||||
llarp::LogError("LIM Encode failed");
|
||||
}
|
||||
|
||||
static void
|
||||
handle_generated_session_start(iwp_async_session_start *start)
|
||||
{
|
||||
llarp_link_session *link = static_cast< llarp_link_session * >(start->user);
|
||||
link->working = false;
|
||||
if(llarp_ev_udp_sendto(link->udp, link->addr, start->buf, start->sz) == -1)
|
||||
llarp::LogError("sendto failed");
|
||||
link->EnterState(llarp_link_session::State::eSessionStartSent);
|
||||
link->serv->remove_intro_from(link->addr);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_verify_intro(iwp_async_intro *intro)
|
||||
{
|
||||
llarp_link_session *self = static_cast< llarp_link_session * >(intro->user);
|
||||
self->working = false;
|
||||
if(!intro->buf)
|
||||
{
|
||||
self->serv->remove_intro_from(self->addr);
|
||||
llarp::LogError("intro verify failed from ", self->addr, " via ",
|
||||
self->serv->addr);
|
||||
delete self;
|
||||
return;
|
||||
}
|
||||
self->intro_ack();
|
||||
}
|
||||
|
||||
static void
|
||||
handle_verify_introack(iwp_async_introack *introack)
|
||||
{
|
||||
llarp_link_session *link =
|
||||
static_cast< llarp_link_session * >(introack->user);
|
||||
|
||||
link->working = false;
|
||||
if(introack->buf == nullptr)
|
||||
{
|
||||
// invalid signature
|
||||
llarp::LogError("introack verify failed from ", link->addr);
|
||||
link->serv->remove_intro_from(link->addr);
|
||||
link->serv->RemoveSessionByAddr(link->addr);
|
||||
return;
|
||||
}
|
||||
link->EnterState(llarp_link_session::eIntroAckRecv);
|
||||
link->session_start();
|
||||
}
|
||||
|
||||
static void
|
||||
handle_establish_timeout(void *user, uint64_t orig, uint64_t left)
|
||||
{
|
||||
if(orig == 0)
|
||||
return;
|
||||
llarp_link_session *self = static_cast< llarp_link_session * >(user);
|
||||
self->establish_job_id = 0;
|
||||
if(self->establish_job)
|
||||
{
|
||||
auto job = self->establish_job;
|
||||
self->establish_job = nullptr;
|
||||
job->link = self->serv;
|
||||
if(self->IsEstablished())
|
||||
{
|
||||
job->session = self;
|
||||
}
|
||||
else
|
||||
{
|
||||
// timer timeout
|
||||
job->session = nullptr;
|
||||
}
|
||||
job->result(job);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
llarp_link_session::done()
|
||||
{
|
||||
auto logic = serv->logic;
|
||||
serv->remove_intro_from(addr);
|
||||
if(establish_job_id)
|
||||
{
|
||||
llarp_logic_remove_call(logic, establish_job_id);
|
||||
handle_establish_timeout(this, 0, 0);
|
||||
}
|
||||
if(pump_recv_timer_id)
|
||||
{
|
||||
llarp_logic_remove_call(logic, pump_recv_timer_id);
|
||||
}
|
||||
if(pump_send_timer_id)
|
||||
{
|
||||
llarp_logic_remove_call(logic, pump_send_timer_id);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
llarp_link_session::PumpCryptoOutbound()
|
||||
{
|
||||
working = true;
|
||||
llarp_threadpool_queue_job(serv->worker, {this, &handle_crypto_outbound});
|
||||
}
|
||||
|
||||
// void llarp_link_session::PumpCodelInbound()
|
||||
// {
|
||||
// pump_recv_timer_id =
|
||||
// llarp_logic_call_later(logic,
|
||||
// {decryptedFrames.nextTickInterval, this,
|
||||
// &handle_inbound_codel_delayed});
|
||||
// }
|
||||
|
||||
void
|
||||
llarp_link_session::EnterState(State st)
|
||||
{
|
||||
llarp::LogDebug("EnterState - entering state: ", st,
|
||||
state == eLIMSent ? "eLIMSent" : "",
|
||||
state == eSessionStartSent ? "eSessionStartSent" : "");
|
||||
frame.alive();
|
||||
state = st;
|
||||
if(state == eSessionStartSent || state == eIntroAckSent)
|
||||
{
|
||||
// llarp::LogInfo("EnterState - ", state==eLIMSent?"eLIMSent":"",
|
||||
// state==eSessionStartSent?"eSessionStartSent":"");
|
||||
// PumpCodelInbound();
|
||||
// PumpCodelOutbound();
|
||||
PumpCryptoOutbound();
|
||||
// StartInboundCodel();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
llarp_link_session::on_intro(const void *buf, size_t sz)
|
||||
{
|
||||
llarp::LogDebug("session onintro");
|
||||
if(sz >= sizeof(workbuf))
|
||||
{
|
||||
// too big?
|
||||
llarp::LogError("intro too big");
|
||||
delete this;
|
||||
return;
|
||||
}
|
||||
if(serv->has_intro_from(addr))
|
||||
{
|
||||
llarp::LogError("duplicate intro from ", addr);
|
||||
delete this;
|
||||
return;
|
||||
}
|
||||
serv->put_intro_from(this);
|
||||
// copy so we own it
|
||||
memcpy(workbuf, buf, sz);
|
||||
intro.buf = workbuf;
|
||||
intro.sz = sz;
|
||||
// give secret key
|
||||
intro.secretkey = eph_seckey;
|
||||
// and nonce
|
||||
intro.nonce = intro.buf + 32;
|
||||
intro.user = this;
|
||||
// set call back hook
|
||||
intro.hook = &handle_verify_intro;
|
||||
// put remote pubkey into this buffer
|
||||
intro.remote_pubkey = remote;
|
||||
|
||||
// call
|
||||
EnterState(eIntroRecv);
|
||||
working = true;
|
||||
iwp_call_async_verify_intro(iwp, &intro);
|
||||
}
|
||||
|
||||
void
|
||||
llarp_link_session::on_intro_ack(const void *buf, size_t sz)
|
||||
{
|
||||
if(sz >= sizeof(workbuf))
|
||||
{
|
||||
// too big?
|
||||
llarp::LogError("introack too big");
|
||||
serv->RemoveSessionByAddr(addr);
|
||||
return;
|
||||
}
|
||||
serv->put_intro_from(this);
|
||||
// copy buffer so we own it
|
||||
memcpy(workbuf, buf, sz);
|
||||
// set intro ack parameters
|
||||
introack.buf = workbuf;
|
||||
introack.sz = sz;
|
||||
introack.nonce = workbuf + 32;
|
||||
introack.remote_pubkey = remote;
|
||||
introack.token = token;
|
||||
introack.secretkey = eph_seckey;
|
||||
introack.user = this;
|
||||
introack.hook = &handle_verify_introack;
|
||||
// async verify
|
||||
working = true;
|
||||
iwp_call_async_verify_introack(iwp, &introack);
|
||||
}
|
||||
|
||||
bool
|
||||
llarp_link_session::is_invalidated() const
|
||||
{
|
||||
return frame.flags_agree(eSessionInvalidated);
|
||||
}
|
||||
|
||||
llarp_link *
|
||||
llarp_link_session::get_parent()
|
||||
{
|
||||
return serv;
|
||||
}
|
||||
|
||||
bool
|
||||
llarp_link_session::Tick(llarp_time_t now)
|
||||
{
|
||||
if(timedout(now, SESSION_TIMEOUT))
|
||||
{
|
||||
// we are timed out
|
||||
// when we are done doing stuff with all of our frames from the crypto
|
||||
// workers we are done
|
||||
llarp::LogWarn("Tick - ", addr, " timed out with ", frames, " frames left");
|
||||
return !working;
|
||||
}
|
||||
if(is_invalidated())
|
||||
{
|
||||
// both sides agreeed to session invalidation
|
||||
// terminate our session when all of our frames from the crypto workers
|
||||
// are done
|
||||
llarp::LogWarn("Tick - ", addr, " invaldiated session with ", frames,
|
||||
" frames left");
|
||||
return !working;
|
||||
}
|
||||
if(state == eLIMSent || state == eEstablished)
|
||||
{
|
||||
if(now - lastKeepalive > KEEP_ALIVE_INTERVAL)
|
||||
send_keepalive(this);
|
||||
}
|
||||
|
||||
// pump frame state
|
||||
if(state == eEstablished)
|
||||
{
|
||||
// llarp::LogDebug("Tick - pumping and retransmitting because we're
|
||||
// eEstablished");
|
||||
|
||||
frame.retransmit(now);
|
||||
pump();
|
||||
PumpCryptoOutbound();
|
||||
}
|
||||
return !frame.process_inbound_queue();
|
||||
}
|
||||
|
||||
void
|
||||
llarp_link_session::EncryptOutboundFrames()
|
||||
{
|
||||
std::queue< iwp_async_frame * > outq;
|
||||
outboundFrames.Process(outq);
|
||||
while(outq.size())
|
||||
{
|
||||
auto &front = outq.front();
|
||||
|
||||
// if(iwp_encrypt_frame(&front))
|
||||
// q.push(front);
|
||||
if(iwp_encrypt_frame(front))
|
||||
handle_frame_encrypt(front);
|
||||
delete front;
|
||||
outq.pop();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
handle_verify_session_start(iwp_async_session_start *s)
|
||||
{
|
||||
llarp_link_session *self = static_cast< llarp_link_session * >(s->user);
|
||||
self->serv->remove_intro_from(self->addr);
|
||||
self->working = false;
|
||||
if(!s->buf)
|
||||
{
|
||||
// verify fail
|
||||
// TODO: remove session?
|
||||
llarp::LogWarn("session start verify failed from ", self->addr);
|
||||
self->serv->RemoveSessionByAddr(self->addr);
|
||||
return;
|
||||
}
|
||||
self->send_LIM();
|
||||
}
|
||||
|
||||
static void
|
||||
handle_introack_generated(iwp_async_introack *i)
|
||||
{
|
||||
llarp_link_session *link = static_cast< llarp_link_session * >(i->user);
|
||||
if(i->buf && link->serv->has_intro_from(link->addr))
|
||||
{
|
||||
// track it with the server here
|
||||
if(link->serv->has_session_to(link->addr))
|
||||
{
|
||||
// duplicate session
|
||||
llarp::LogWarn("duplicate session to ", link->addr);
|
||||
return;
|
||||
}
|
||||
link->frame.alive();
|
||||
link->EnterState(llarp_link_session::State::eIntroAckSent);
|
||||
link->serv->put_session(link->addr, link);
|
||||
llarp::LogDebug("send introack to ", link->addr, " via ", link->serv->addr);
|
||||
llarp_ev_udp_sendto(link->udp, link->addr, i->buf, i->sz);
|
||||
}
|
||||
else
|
||||
{
|
||||
// failed to generate?
|
||||
llarp::LogWarn("failed to generate introack");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
handle_generated_intro(iwp_async_intro *i)
|
||||
{
|
||||
llarp_link_session *link = static_cast< llarp_link_session * >(i->user);
|
||||
link->working = false;
|
||||
if(i->buf)
|
||||
{
|
||||
llarp::LogInfo("send intro to ", link->addr);
|
||||
if(llarp_ev_udp_sendto(link->udp, link->addr, i->buf, i->sz) == -1)
|
||||
{
|
||||
llarp::LogWarn("send intro failed");
|
||||
return;
|
||||
}
|
||||
link->EnterState(llarp_link_session::eIntroSent);
|
||||
}
|
||||
else
|
||||
{
|
||||
llarp::LogWarn("failed to generate intro");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
llarp_link_session::introduce(uint8_t *pub)
|
||||
{
|
||||
llarp::LogDebug("session introduce");
|
||||
memcpy(remote, pub, PUBKEYSIZE);
|
||||
intro.buf = workbuf;
|
||||
size_t w0sz = (rand() % MAX_PAD);
|
||||
intro.sz = (32 * 3) + w0sz;
|
||||
// randomize w0
|
||||
if(w0sz)
|
||||
{
|
||||
crypto->randbytes(intro.buf + (32 * 3), w0sz);
|
||||
}
|
||||
|
||||
intro.nonce = intro.buf + 32;
|
||||
intro.secretkey = eph_seckey;
|
||||
// copy in pubkey
|
||||
intro.remote_pubkey = remote;
|
||||
// randomize nonce
|
||||
crypto->randbytes(intro.nonce, 32);
|
||||
// async generate intro packet
|
||||
intro.user = this;
|
||||
intro.hook = &handle_generated_intro;
|
||||
working = true;
|
||||
llarp::LogInfo("try introduce to transport adddress ",
|
||||
llarp::RouterID(remote));
|
||||
iwp_call_async_gen_intro(iwp, &intro);
|
||||
// start introduce timer
|
||||
establish_job_id =
|
||||
llarp_logic_call_later(logic, {5000, this, &handle_establish_timeout});
|
||||
}
|
||||
|
||||
static void
|
||||
handle_frame_decrypt(iwp_async_frame *frame)
|
||||
{
|
||||
llarp_link_session *self = static_cast< llarp_link_session * >(frame->user);
|
||||
llarp::LogDebug("rx ", frame->sz);
|
||||
if(frame->success)
|
||||
{
|
||||
if(self->frame.process(frame->buf + 64, frame->sz - 64))
|
||||
{
|
||||
self->frame.alive();
|
||||
self->pump();
|
||||
}
|
||||
else
|
||||
llarp::LogError("invalid frame from ", self->addr);
|
||||
}
|
||||
else
|
||||
llarp::LogError("decrypt frame fail from ", self->addr);
|
||||
}
|
||||
|
||||
void
|
||||
llarp_link_session::decrypt_frame(const void *buf, size_t sz)
|
||||
{
|
||||
if(sz > 64)
|
||||
{
|
||||
// auto frame = alloc_frame(inboundFrames, buf, sz);
|
||||
// inboundFrames.Put(frame);
|
||||
auto f = alloc_frame(buf, sz);
|
||||
/*
|
||||
if(iwp_decrypt_frame(f))
|
||||
{
|
||||
decryptedFrames.Put(f);
|
||||
if(state == eEstablished)
|
||||
{
|
||||
if(pump_recv_timer_id == 0)
|
||||
PumpCodelInbound();
|
||||
}
|
||||
else
|
||||
ManualPumpInboundCodel();
|
||||
}
|
||||
else
|
||||
llarp::LogWarn("decrypt frame fail");
|
||||
*/
|
||||
f->hook = &handle_frame_decrypt;
|
||||
iwp_call_async_frame_decrypt(iwp, f);
|
||||
}
|
||||
else
|
||||
llarp::LogWarn("short packet of ", sz, " bytes");
|
||||
}
|
||||
|
||||
void
|
||||
llarp_link_session::session_start()
|
||||
{
|
||||
llarp::LogInfo("session gen start");
|
||||
size_t w2sz = rand() % MAX_PAD;
|
||||
start.buf = workbuf;
|
||||
start.sz = w2sz + (32 * 3);
|
||||
start.nonce = workbuf + 32;
|
||||
crypto->randbytes(start.nonce, 32);
|
||||
start.token = token;
|
||||
memcpy(start.buf + 64, token, 32);
|
||||
if(w2sz)
|
||||
crypto->randbytes(start.buf + (32 * 3), w2sz);
|
||||
start.remote_pubkey = remote;
|
||||
start.secretkey = eph_seckey;
|
||||
start.sessionkey = sessionkey;
|
||||
start.user = this;
|
||||
start.hook = &handle_generated_session_start;
|
||||
working = true;
|
||||
iwp_call_async_gen_session_start(iwp, &start);
|
||||
}
|
||||
|
||||
void
|
||||
llarp_link_session::on_session_start(const void *buf, size_t sz)
|
||||
{
|
||||
llarp::LogInfo("session start");
|
||||
if(sz > sizeof(workbuf))
|
||||
{
|
||||
llarp::LogDebug("session start too big");
|
||||
return;
|
||||
}
|
||||
// own the buffer
|
||||
memcpy(workbuf, buf, sz);
|
||||
// verify session start
|
||||
start.buf = workbuf;
|
||||
start.sz = sz;
|
||||
start.nonce = workbuf + 32;
|
||||
start.token = token;
|
||||
start.remote_pubkey = remote;
|
||||
start.secretkey = eph_seckey;
|
||||
start.sessionkey = sessionkey;
|
||||
start.user = this;
|
||||
start.hook = &handle_verify_session_start;
|
||||
working = true;
|
||||
iwp_call_async_verify_session_start(iwp, &start);
|
||||
}
|
||||
|
||||
void
|
||||
llarp_link_session::intro_ack()
|
||||
{
|
||||
if(serv->has_session_to(addr))
|
||||
{
|
||||
llarp::LogWarn("won't ack intro for duplicate session from ", addr);
|
||||
return;
|
||||
}
|
||||
llarp::LogDebug("session introack");
|
||||
uint16_t w1sz = rand() % MAX_PAD;
|
||||
introack.buf = workbuf;
|
||||
introack.sz = (32 * 3) + w1sz;
|
||||
// randomize padding
|
||||
if(w1sz)
|
||||
crypto->randbytes(introack.buf + (32 * 3), w1sz);
|
||||
|
||||
// randomize nonce
|
||||
introack.nonce = introack.buf + 32;
|
||||
crypto->randbytes(introack.nonce, 32);
|
||||
// token
|
||||
introack.token = token;
|
||||
|
||||
// keys
|
||||
introack.remote_pubkey = remote;
|
||||
introack.secretkey = eph_seckey;
|
||||
|
||||
// call
|
||||
introack.user = this;
|
||||
introack.hook = &handle_introack_generated;
|
||||
working = true;
|
||||
iwp_call_async_gen_introack(iwp, &introack);
|
||||
}
|
||||
|
||||
// this is called from net thread
|
||||
void
|
||||
llarp_link_session::recv(const void *buf, size_t sz)
|
||||
{
|
||||
// llarp::LogDebug("session recv", state);
|
||||
|
||||
// frame_header hdr((byte_t *)buf);
|
||||
// llarp::LogDebug("recv - message header type ", (int)hdr.msgtype());
|
||||
|
||||
now = llarp_time_now_ms();
|
||||
switch(state)
|
||||
{
|
||||
case eInitial:
|
||||
case eIntroRecv:
|
||||
// got intro
|
||||
llarp::LogDebug("session recv - intro");
|
||||
on_intro(buf, sz);
|
||||
break;
|
||||
case eIntroSent:
|
||||
// got intro ack
|
||||
llarp::LogDebug("session recv - introack");
|
||||
on_intro_ack(buf, sz);
|
||||
break;
|
||||
case eIntroAckSent:
|
||||
// probably a session start
|
||||
llarp::LogDebug("session recv - sessionstart");
|
||||
on_session_start(buf, sz);
|
||||
break;
|
||||
|
||||
case eSessionStartSent:
|
||||
case eLIMSent:
|
||||
case eEstablished:
|
||||
// session is started
|
||||
llarp::LogDebug("session recv - ",
|
||||
state == eSessionStartSent ? "startsent" : "",
|
||||
state == eLIMSent ? "limset" : "",
|
||||
state == eEstablished ? "established" : "");
|
||||
|
||||
decrypt_frame(buf, sz);
|
||||
break;
|
||||
default:
|
||||
llarp::LogError("session recv - invalid state");
|
||||
// invalid state?
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: fix orphan
|
||||
iwp_async_frame *
|
||||
llarp_link_session::alloc_frame(const void *buf, size_t sz)
|
||||
{
|
||||
// TODO don't hard code 1500
|
||||
if(sz > 1500)
|
||||
{
|
||||
llarp::LogWarn("alloc frame - frame too big, >1500");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
iwp_async_frame *frame = new iwp_async_frame;
|
||||
if(buf)
|
||||
memcpy(frame->buf, buf, sz);
|
||||
frame->iwp = iwp;
|
||||
frame->sz = sz;
|
||||
frame->user = this;
|
||||
frame->sessionkey = sessionkey;
|
||||
/// TODO: this could be rather slow
|
||||
// frame->created = now;
|
||||
// llarp::LogInfo("alloc_frame putting into q");
|
||||
// q.Put(frame);
|
||||
return frame;
|
||||
}
|
||||
|
||||
void
|
||||
llarp_link_session::encrypt_frame_async_send(const void *buf, size_t sz)
|
||||
{
|
||||
// 64 bytes frame overhead for nonce and hmac
|
||||
iwp_async_frame *frame = alloc_frame(nullptr, sz + 64);
|
||||
memcpy(frame->buf + 64, buf, sz);
|
||||
// maybe add upto 128 random bytes to the packet
|
||||
auto padding = rand() % MAX_PAD;
|
||||
if(padding)
|
||||
crypto->randbytes(frame->buf + 64 + sz, padding);
|
||||
frame->sz += padding;
|
||||
// frame is modified, so now we can push it to queue
|
||||
outboundFrames.Put(frame);
|
||||
}
|
||||
|
||||
void
|
||||
llarp_link_session::pump()
|
||||
{
|
||||
// llarp::LogInfo("session pump");
|
||||
// TODO: in codel the timestamp may cause excssive drop when all the
|
||||
// packets have a similar timestamp
|
||||
now = llarp_time_now_ms();
|
||||
llarp_buffer_t buf;
|
||||
while(frame.next_frame(&buf))
|
||||
{
|
||||
encrypt_frame_async_send(buf.base, buf.sz);
|
||||
frame.pop_next_frame();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,179 @@
|
|||
#include "llarp/iwp/transit_message.hpp"
|
||||
#include "llarp/iwp/frame_state.hpp"
|
||||
#include "llarp/iwp/sendbuf.hpp"
|
||||
#include "llarp/time.h"
|
||||
|
||||
void
|
||||
transit_message::clear()
|
||||
{
|
||||
frags.clear();
|
||||
lastfrag.clear();
|
||||
}
|
||||
|
||||
// calculate acked bitmask
|
||||
uint32_t
|
||||
transit_message::get_bitmask() const
|
||||
{
|
||||
uint32_t bitmask = 0;
|
||||
uint8_t idx = 0;
|
||||
while(idx < 32)
|
||||
{
|
||||
bitmask |= (status.test(idx) ? (1 << idx) : 0);
|
||||
++idx;
|
||||
}
|
||||
return bitmask;
|
||||
}
|
||||
|
||||
// outbound
|
||||
transit_message::transit_message(llarp_buffer_t buf, const byte_t *hash,
|
||||
uint64_t id, uint16_t mtu)
|
||||
{
|
||||
started = llarp_time_now_ms();
|
||||
put_message(buf, hash, id, mtu);
|
||||
}
|
||||
|
||||
// inbound
|
||||
transit_message::transit_message(const xmit &x) : msginfo(x)
|
||||
{
|
||||
started = llarp_time_now_ms();
|
||||
byte_t fragidx = 0;
|
||||
uint16_t fragsize = x.fragsize();
|
||||
while(fragidx < x.numfrags())
|
||||
{
|
||||
frags[fragidx].resize(fragsize);
|
||||
++fragidx;
|
||||
}
|
||||
status.reset();
|
||||
}
|
||||
|
||||
/// ack packets based off a bitmask
|
||||
void
|
||||
transit_message::ack(uint32_t bitmask)
|
||||
{
|
||||
uint8_t idx = 0;
|
||||
while(idx < 32)
|
||||
{
|
||||
if(bitmask & (1 << idx))
|
||||
{
|
||||
status.set(idx);
|
||||
}
|
||||
++idx;
|
||||
}
|
||||
lastAck = llarp_time_now_ms();
|
||||
}
|
||||
|
||||
bool
|
||||
transit_message::should_send_ack(llarp_time_t now) const
|
||||
{
|
||||
if(msginfo.numfrags() == 0)
|
||||
return true;
|
||||
return now - lastAck > 250;
|
||||
}
|
||||
|
||||
bool
|
||||
transit_message::should_resend_xmit(llarp_time_t now) const
|
||||
{
|
||||
return lastAck == 0 && now - started > 1000;
|
||||
}
|
||||
|
||||
bool
|
||||
transit_message::completed() const
|
||||
{
|
||||
for(byte_t idx = 0; idx < msginfo.numfrags(); ++idx)
|
||||
{
|
||||
if(!status.test(idx))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// template < typename T >
|
||||
void
|
||||
transit_message::generate_xmit(sendqueue_t &queue, byte_t flags)
|
||||
{
|
||||
uint16_t sz = lastfrag.size() + sizeof(msginfo.buffer);
|
||||
queue.push(new sendbuf_t(sz + 6));
|
||||
auto body_ptr = init_sendbuf(queue.back(), eXMIT, sz, flags);
|
||||
memcpy(body_ptr, msginfo.buffer, sizeof(msginfo.buffer));
|
||||
body_ptr += sizeof(msginfo.buffer);
|
||||
memcpy(body_ptr, lastfrag.data(), lastfrag.size());
|
||||
}
|
||||
|
||||
// template < typename T >
|
||||
void
|
||||
transit_message::retransmit_frags(sendqueue_t &queue, byte_t flags)
|
||||
{
|
||||
auto msgid = msginfo.msgid();
|
||||
auto fragsize = msginfo.fragsize();
|
||||
for(auto &frag : frags)
|
||||
{
|
||||
if(status.test(frag.first))
|
||||
continue;
|
||||
uint16_t sz = 9 + fragsize;
|
||||
queue.push(new sendbuf_t(sz + 6));
|
||||
auto body_ptr = init_sendbuf(queue.back(), eFRAG, sz, flags);
|
||||
// TODO: assumes big endian
|
||||
memcpy(body_ptr, &msgid, 8);
|
||||
body_ptr[8] = frag.first;
|
||||
memcpy(body_ptr + 9, frag.second.data(), fragsize);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
transit_message::reassemble(std::vector< byte_t > &buffer)
|
||||
{
|
||||
auto total = msginfo.totalsize();
|
||||
buffer.resize(total);
|
||||
auto fragsz = msginfo.fragsize();
|
||||
auto ptr = &buffer[0];
|
||||
for(byte_t idx = 0; idx < msginfo.numfrags(); ++idx)
|
||||
{
|
||||
if(!status.test(idx))
|
||||
return false;
|
||||
memcpy(ptr, frags[idx].data(), fragsz);
|
||||
ptr += fragsz;
|
||||
}
|
||||
memcpy(ptr, lastfrag.data(), lastfrag.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
transit_message::put_message(llarp_buffer_t buf, const byte_t *hash,
|
||||
uint64_t id, uint16_t mtu)
|
||||
{
|
||||
status.reset();
|
||||
uint8_t fragid = 0;
|
||||
uint16_t fragsize = mtu;
|
||||
size_t left = buf.sz;
|
||||
while(left > fragsize)
|
||||
{
|
||||
auto &frag = frags[fragid];
|
||||
frag.resize(fragsize);
|
||||
memcpy(frag.data(), buf.cur, fragsize);
|
||||
buf.cur += fragsize;
|
||||
fragid++;
|
||||
left -= fragsize;
|
||||
}
|
||||
uint16_t lastfrag = buf.sz - (buf.cur - buf.base);
|
||||
// set info for xmit
|
||||
msginfo.set_info(hash, id, fragsize, lastfrag, fragid);
|
||||
put_lastfrag(buf.cur, lastfrag);
|
||||
}
|
||||
|
||||
void
|
||||
transit_message::put_lastfrag(byte_t *buf, size_t sz)
|
||||
{
|
||||
lastfrag.resize(sz);
|
||||
memcpy(lastfrag.data(), buf, sz);
|
||||
}
|
||||
|
||||
bool
|
||||
transit_message::put_frag(byte_t fragno, byte_t *buf)
|
||||
{
|
||||
auto itr = frags.find(fragno);
|
||||
if(itr == frags.end())
|
||||
return false;
|
||||
memcpy(itr->second.data(), buf, msginfo.fragsize());
|
||||
status.set(fragno);
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
#include "llarp/iwp/xmit.hpp"
|
||||
|
||||
xmit::xmit(byte_t *ptr)
|
||||
{
|
||||
memcpy(buffer, ptr, sizeof(buffer));
|
||||
}
|
||||
|
||||
xmit::xmit(const xmit &other)
|
||||
{
|
||||
memcpy(buffer, other.buffer, sizeof(buffer));
|
||||
}
|
||||
|
||||
void
|
||||
xmit::set_info(const byte_t *hash, uint64_t id, uint16_t fragsz,
|
||||
uint16_t lastsz, uint8_t numfrags, uint8_t flags)
|
||||
{
|
||||
// big endian assumed
|
||||
// TODO: implement little endian
|
||||
memcpy(buffer, hash, 32);
|
||||
memcpy(buffer + 32, &id, 8);
|
||||
memcpy(buffer + 40, &fragsz, 2);
|
||||
memcpy(buffer + 42, &lastsz, 2);
|
||||
buffer[44] = 0;
|
||||
buffer[45] = 0;
|
||||
buffer[46] = numfrags;
|
||||
buffer[47] = flags;
|
||||
}
|
||||
|
||||
const byte_t *
|
||||
xmit::hash() const
|
||||
{
|
||||
return &buffer[0];
|
||||
}
|
||||
|
||||
uint64_t
|
||||
xmit::msgid() const
|
||||
{
|
||||
// big endian assumed
|
||||
// TODO: implement little endian
|
||||
const byte_t *start = buffer + 32;
|
||||
const uint64_t *msgid = (const uint64_t *)start;
|
||||
return *msgid;
|
||||
}
|
||||
|
||||
// size of each full fragment
|
||||
uint16_t
|
||||
xmit::fragsize() const
|
||||
{
|
||||
// big endian assumed
|
||||
// TODO: implement little endian
|
||||
const byte_t *start = buffer + 40;
|
||||
const uint16_t *fragsz = (uint16_t *)start;
|
||||
return *fragsz;
|
||||
}
|
||||
|
||||
// number of full fragments
|
||||
uint8_t
|
||||
xmit::numfrags() const
|
||||
{
|
||||
return buffer[46];
|
||||
}
|
||||
|
||||
// size of the entire message
|
||||
size_t
|
||||
xmit::totalsize() const
|
||||
{
|
||||
return (fragsize() * numfrags()) + lastfrag();
|
||||
}
|
||||
|
||||
// size of the last fragment
|
||||
uint16_t
|
||||
xmit::lastfrag() const
|
||||
{
|
||||
// big endian assumed
|
||||
// TODO: implement little endian
|
||||
const byte_t *start = buffer + 42;
|
||||
const uint16_t *lastsz = (uint16_t *)start;
|
||||
return *lastsz;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
xmit::flags()
|
||||
{
|
||||
return buffer[47];
|
||||
}
|
2418
llarp/iwp_link.cpp
2418
llarp/iwp_link.cpp
File diff suppressed because it is too large
Load Diff
17
llarp/link.c
17
llarp/link.c
|
@ -1,17 +0,0 @@
|
|||
#include <llarp/link.h>
|
||||
|
||||
bool
|
||||
llarp_link_initialized(struct llarp_link* link)
|
||||
{
|
||||
return link && link->impl && link->name && link->get_our_address
|
||||
&& link->configure && link->start_link && link->stop_link
|
||||
&& link->iter_sessions && link->try_establish && link->sendto
|
||||
&& link->has_session_to && link->mark_session_active && link->free_impl;
|
||||
}
|
||||
|
||||
bool
|
||||
llarp_link_session_initialized(struct llarp_link_session* s)
|
||||
{
|
||||
return s && s->impl && s->sendto && s->timeout && s->close
|
||||
&& s->get_remote_router && s->established && s->get_parent;
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
#include "encoder.hpp"
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
/// encode Link Introduce Message onto a buffer
|
||||
/// if router is nullptr then the LIM's r member is omitted.
|
||||
bool
|
||||
EncodeLIM(llarp_buffer_t* buff, llarp_rc* router)
|
||||
{
|
||||
if(!bencode_start_dict(buff))
|
||||
return false;
|
||||
|
||||
// message type
|
||||
if(!bencode_write_bytestring(buff, "a", 1))
|
||||
return false;
|
||||
if(!bencode_write_bytestring(buff, "i", 1))
|
||||
return false;
|
||||
|
||||
// router contact
|
||||
if(router)
|
||||
{
|
||||
if(!bencode_write_bytestring(buff, "r", 1))
|
||||
return false;
|
||||
if(!llarp_rc_bencode(router, buff))
|
||||
return false;
|
||||
}
|
||||
|
||||
// version
|
||||
if(!bencode_write_version_entry(buff))
|
||||
return false;
|
||||
|
||||
return bencode_end(buff);
|
||||
}
|
||||
} // namespace llarp
|
|
@ -10,32 +10,7 @@ namespace llarp
|
|||
/// encode Link Introduce Message onto a buffer
|
||||
/// if router is nullptr then the LIM's r member is omitted.
|
||||
bool
|
||||
EncodeLIM(llarp_buffer_t* buff, llarp_rc* router)
|
||||
{
|
||||
if(!bencode_start_dict(buff))
|
||||
return false;
|
||||
|
||||
// message type
|
||||
if(!bencode_write_bytestring(buff, "a", 1))
|
||||
return false;
|
||||
if(!bencode_write_bytestring(buff, "i", 1))
|
||||
return false;
|
||||
|
||||
// router contact
|
||||
if(router)
|
||||
{
|
||||
if(!bencode_write_bytestring(buff, "r", 1))
|
||||
return false;
|
||||
if(!llarp_rc_bencode(router, buff))
|
||||
return false;
|
||||
}
|
||||
|
||||
// version
|
||||
if(!bencode_write_version_entry(buff))
|
||||
return false;
|
||||
|
||||
return bencode_end(buff);
|
||||
}
|
||||
}
|
||||
EncodeLIM(llarp_buffer_t* buff, llarp_rc* router);
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include <llarp/router_contact.h>
|
||||
#include <llarp/messages.hpp>
|
||||
#include "buffer.hpp"
|
||||
#include "llarp/iwp/session.hpp"
|
||||
#include "logger.hpp"
|
||||
#include "router.hpp"
|
||||
|
||||
|
@ -53,8 +54,8 @@ namespace llarp
|
|||
switch(*strbuf.cur)
|
||||
{
|
||||
case 'i':
|
||||
handler->msg = new LinkIntroMessage(
|
||||
handler->from->get_remote_router(handler->from));
|
||||
handler->msg =
|
||||
new LinkIntroMessage(handler->from->get_remote_router());
|
||||
break;
|
||||
case 'd':
|
||||
handler->msg = new RelayDownstreamMessage(handler->GetCurrentFrom());
|
||||
|
@ -90,7 +91,7 @@ namespace llarp
|
|||
RouterID
|
||||
InboundMessageParser::GetCurrentFrom()
|
||||
{
|
||||
auto rc = from->get_remote_router(from);
|
||||
auto rc = from->get_remote_router();
|
||||
return rc->pubkey;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,12 +10,10 @@ namespace llarp
|
|||
{
|
||||
_glog.minlevel = lvl;
|
||||
}
|
||||
}
|
||||
} // namespace llarp
|
||||
|
||||
extern "C" {
|
||||
void
|
||||
cSetLogLevel(LogLevel lvl)
|
||||
{
|
||||
llarp::SetLogLevel((llarp::LogLevel)lvl);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,14 +2,6 @@
|
|||
#include <llarp/mem.h>
|
||||
#include "logger.hpp"
|
||||
|
||||
struct llarp_logic
|
||||
{
|
||||
struct llarp_threadpool* thread;
|
||||
struct llarp_timer_context* timer;
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
|
||||
struct llarp_logic*
|
||||
llarp_init_logic()
|
||||
{
|
||||
|
@ -103,4 +95,3 @@ llarp_logic_remove_call(struct llarp_logic* logic, uint32_t id)
|
|||
{
|
||||
llarp_timer_remove_job(logic->timer, id);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,9 +14,7 @@ namespace llarp
|
|||
++p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
} // namespace llarp
|
||||
|
||||
void
|
||||
llarp_mem_slab(struct llarp_alloc *mem, uint32_t *buf, size_t sz)
|
||||
|
@ -37,4 +35,3 @@ llarp_eq(const void *a, const void *b, size_t sz)
|
|||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,11 +35,9 @@ namespace llarp
|
|||
|
||||
} // namespace llarp
|
||||
|
||||
extern "C" {
|
||||
void
|
||||
llarp_mem_stdlib(struct llarp_alloc *mem)
|
||||
{
|
||||
mem->alloc = llarp::std_malloc;
|
||||
mem->free = llarp::std_free;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,6 @@ operator<(const in6_addr& a, const in6_addr& b)
|
|||
return memcmp(&a, &b, sizeof(in6_addr)) < 0;
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
bool
|
||||
llarp_getifaddr(const char* ifname, int af, struct sockaddr* addr)
|
||||
{
|
||||
|
@ -77,4 +76,3 @@ llarp_getifaddr(const char* ifname, int af, struct sockaddr* addr)
|
|||
freeifaddrs(ifa);
|
||||
return found;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -318,7 +318,6 @@ nodedb_async_load_rc(void *user)
|
|||
llarp_logic_queue_job(job->logic, {job, &nodedb_inform_load_rc});
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
struct llarp_nodedb *
|
||||
llarp_nodedb_new(struct llarp_crypto *crypto)
|
||||
{
|
||||
|
@ -460,5 +459,3 @@ llarp_nodedb_select_random_hop(struct llarp_nodedb *n, struct llarp_rc *prev,
|
|||
llarp_rc_copy(result, &itr->second);
|
||||
}
|
||||
}
|
||||
|
||||
} // end extern
|
||||
|
|
|
@ -194,7 +194,6 @@ llarp_pathbuilder_context::BuildOne()
|
|||
llarp_pathbuilder_build_path(job);
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
struct llarp_pathbuilder_context*
|
||||
llarp_pathbuilder_context_new(struct llarp_router* router,
|
||||
struct llarp_dht_context* dht)
|
||||
|
@ -222,4 +221,3 @@ llarp_pathbuilder_build_path(struct llarp_pathbuild_job* job)
|
|||
llarp_logic_queue_job(job->router->logic,
|
||||
{job, &llarp::pathbuilder_start_build});
|
||||
}
|
||||
} // end extern c
|
||||
|
|
|
@ -82,4 +82,4 @@ namespace llarp
|
|||
lram->decrypt->AsyncDecrypt(router->tp, &lram->frames[0], lram);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} // namespace llarp
|
|
@ -1,10 +1,11 @@
|
|||
#include "router.hpp"
|
||||
#include <llarp/iwp.h>
|
||||
#include <llarp/link.h>
|
||||
#include <llarp/proto.h>
|
||||
#include <llarp/router.h>
|
||||
#include <llarp/link_message.hpp>
|
||||
#include <llarp/messages/discard.hpp>
|
||||
#include "llarp/iwp/establish_job.hpp"
|
||||
#include "llarp/iwp/server.hpp"
|
||||
#include "llarp/iwp/session.hpp"
|
||||
|
||||
#include "buffer.hpp"
|
||||
#include "encode.hpp"
|
||||
|
@ -267,14 +268,12 @@ llarp_router::Close()
|
|||
{
|
||||
for(auto link : inboundLinks)
|
||||
{
|
||||
link->stop_link(link);
|
||||
link->free_impl(link);
|
||||
link->stop_link();
|
||||
delete link;
|
||||
}
|
||||
inboundLinks.clear();
|
||||
|
||||
outboundLink->stop_link(outboundLink);
|
||||
outboundLink->free_impl(outboundLink);
|
||||
outboundLink->stop_link();
|
||||
delete outboundLink;
|
||||
outboundLink = nullptr;
|
||||
}
|
||||
|
@ -290,7 +289,7 @@ llarp_router::connect_job_retry(void *user, uint64_t orig, uint64_t left)
|
|||
if(job->link)
|
||||
{
|
||||
llarp::LogInfo("trying to establish session again with ", remote);
|
||||
job->link->try_establish(job->link, job);
|
||||
job->link->try_establish(job);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -324,7 +323,7 @@ llarp_router::on_verify_server_rc(llarp_async_verify_rc *job)
|
|||
// was an outbound attempt
|
||||
auto session = ctx->establish_job->session;
|
||||
if(session)
|
||||
session->close(session);
|
||||
session->close();
|
||||
}
|
||||
llarp_rc_free(&job->rc);
|
||||
router->pendingEstablishJobs.erase(pk);
|
||||
|
@ -351,7 +350,7 @@ llarp_router::on_verify_server_rc(llarp_async_verify_rc *job)
|
|||
if(ctx->establish_job)
|
||||
{
|
||||
auto session = ctx->establish_job->session;
|
||||
router->FlushOutboundFor(pk, session->get_parent(session));
|
||||
router->FlushOutboundFor(pk, session->get_parent());
|
||||
// this frees the job
|
||||
router->pendingEstablishJobs.erase(pk);
|
||||
}
|
||||
|
@ -401,7 +400,7 @@ llarp_router::Tick()
|
|||
iter.visit = &send_padded_message;
|
||||
if(sendPadding)
|
||||
{
|
||||
outboundLink->iter_sessions(outboundLink, iter);
|
||||
outboundLink->iter_sessions(iter);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -411,7 +410,7 @@ llarp_router::send_padded_message(llarp_link_session_iter *itr,
|
|||
{
|
||||
llarp_router *self = static_cast< llarp_router * >(itr->user);
|
||||
llarp::RouterID remote;
|
||||
remote = &peer->get_remote_router(peer)->pubkey[0];
|
||||
remote = &peer->get_remote_router()->pubkey[0];
|
||||
llarp::DiscardMessage msg(2000);
|
||||
|
||||
llarp_buffer_t buf =
|
||||
|
@ -425,7 +424,7 @@ llarp_router::send_padded_message(llarp_link_session_iter *itr,
|
|||
|
||||
for(size_t idx = 0; idx < 5; ++idx)
|
||||
{
|
||||
peer->sendto(peer, buf);
|
||||
peer->sendto(buf);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -546,7 +545,7 @@ llarp_router::on_try_connect_result(llarp_link_establish_job *job)
|
|||
{
|
||||
// llarp::LogDebug("try_connect got session");
|
||||
auto session = job->session;
|
||||
router->async_verify_RC(session->get_remote_router(session), false, job);
|
||||
router->async_verify_RC(session->get_remote_router(), false, job);
|
||||
return;
|
||||
}
|
||||
// llarp::LogDebug("try_connect no session");
|
||||
|
@ -634,7 +633,7 @@ llarp_router::Run()
|
|||
for(auto link : inboundLinks)
|
||||
{
|
||||
llarp_ai addr;
|
||||
link->get_our_address(link, &addr);
|
||||
link->get_our_address(&addr);
|
||||
llarp::Addr a(addr);
|
||||
if(this->publicOverride && a.sameAddr(publicAddr))
|
||||
{
|
||||
|
@ -686,7 +685,7 @@ llarp_router::Run()
|
|||
}
|
||||
*/
|
||||
}
|
||||
link->get_our_address(link, &this->addrInfo);
|
||||
link->get_our_address(&this->addrInfo);
|
||||
// override ip and port
|
||||
this->addrInfo.ip = *publicAddr.addr6();
|
||||
this->addrInfo.port = publicAddr.port();
|
||||
|
@ -715,7 +714,7 @@ llarp_router::Run()
|
|||
}
|
||||
|
||||
llarp::LogDebug("starting outbound link");
|
||||
if(!outboundLink->start_link(outboundLink, logic))
|
||||
if(!outboundLink->start_link(logic))
|
||||
{
|
||||
llarp::LogWarn("outbound link failed to start");
|
||||
}
|
||||
|
@ -725,7 +724,7 @@ llarp_router::Run()
|
|||
// start links
|
||||
for(auto link : inboundLinks)
|
||||
{
|
||||
if(link->start_link(link, logic))
|
||||
if(link->start_link(logic))
|
||||
{
|
||||
llarp::LogDebug("Link ", link->name(), " started");
|
||||
IBLinksStarted++;
|
||||
|
@ -781,8 +780,6 @@ llarp_router::InitOutboundLink()
|
|||
{
|
||||
if(outboundLink)
|
||||
return true;
|
||||
auto link = new llarp_link;
|
||||
llarp::Zero(link, sizeof(llarp_link));
|
||||
|
||||
llarp_iwp_args args = {
|
||||
.crypto = &crypto,
|
||||
|
@ -791,14 +788,17 @@ llarp_router::InitOutboundLink()
|
|||
.router = this,
|
||||
.keyfile = transport_keyfile.c_str(),
|
||||
};
|
||||
|
||||
auto link = new(std::nothrow) llarp_link(args);
|
||||
|
||||
auto afs = {AF_INET, AF_INET6};
|
||||
iwp_link_init(link, args);
|
||||
if(llarp_link_initialized(link))
|
||||
|
||||
if(link)
|
||||
{
|
||||
llarp::LogInfo("outbound link initialized");
|
||||
for(auto af : afs)
|
||||
{
|
||||
if(link->configure(link, netloop, "*", af, 0))
|
||||
if(link->configure(netloop, "*", af, 0))
|
||||
{
|
||||
outboundLink = link;
|
||||
llarp::LogInfo("outbound link ready");
|
||||
|
@ -817,7 +817,6 @@ llarp_router::HasPendingConnectJob(const llarp::RouterID &remote)
|
|||
return pendingEstablishJobs.find(remote) != pendingEstablishJobs.end();
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
struct llarp_router *
|
||||
llarp_init_router(struct llarp_threadpool *tp, struct llarp_ev_loop *netloop,
|
||||
struct llarp_logic *logic)
|
||||
|
@ -892,7 +891,7 @@ llarp_router_try_connect(struct llarp_router *router, struct llarp_rc *remote,
|
|||
// give router as user pointer
|
||||
job->user = router;
|
||||
// try establishing
|
||||
link->try_establish(link, job);
|
||||
link->try_establish(job);
|
||||
return true;
|
||||
}
|
||||
llarp::LogWarn("couldn't get first address for ", hexname);
|
||||
|
@ -1083,8 +1082,6 @@ llarp_findOrCreateIdentity(llarp_crypto *crypto, const char *fpath,
|
|||
return false;
|
||||
}
|
||||
|
||||
} // end extern C
|
||||
|
||||
// C++ ...
|
||||
bool
|
||||
llarp_findOrCreateEncryption(llarp_crypto *crypto, const char *fpath,
|
||||
|
@ -1145,9 +1142,6 @@ namespace llarp
|
|||
if(!StrEq(key, "*"))
|
||||
{
|
||||
llarp::LogInfo("interface specific binding activated");
|
||||
link = new llarp_link;
|
||||
llarp::Zero(link, sizeof(llarp_link));
|
||||
|
||||
llarp_iwp_args args = {
|
||||
.crypto = &self->crypto,
|
||||
.logic = self->logic,
|
||||
|
@ -1155,11 +1149,13 @@ namespace llarp
|
|||
.router = self,
|
||||
.keyfile = self->transport_keyfile.c_str(),
|
||||
};
|
||||
iwp_link_init(link, args);
|
||||
if(llarp_link_initialized(link))
|
||||
|
||||
link = new(std::nothrow) llarp_link(args);
|
||||
|
||||
if(link)
|
||||
{
|
||||
llarp::LogInfo("link ", key, " initialized");
|
||||
if(link->configure(link, self->netloop, key, af, proto))
|
||||
if(link->configure(self->netloop, key, af, proto))
|
||||
{
|
||||
self->AddInboundLink(link);
|
||||
return;
|
||||
|
@ -1171,7 +1167,7 @@ namespace llarp
|
|||
llarp::LogInfo("link ", key,
|
||||
" failed to configure IPv6, trying IPv4");
|
||||
af = AF_INET;
|
||||
if(link->configure(link, self->netloop, key, af, proto))
|
||||
if(link->configure(self->netloop, key, af, proto))
|
||||
{
|
||||
self->AddInboundLink(link);
|
||||
return;
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
#ifndef LLARP_ROUTER_HPP
|
||||
#define LLARP_ROUTER_HPP
|
||||
#include <llarp/dht.h>
|
||||
#include <llarp/link.h>
|
||||
#include <llarp/nodedb.h>
|
||||
#include <llarp/router.h>
|
||||
#include <llarp/router_contact.h>
|
||||
#include <llarp/path.hpp>
|
||||
|
||||
|
@ -15,27 +13,31 @@
|
|||
#include <llarp/dht.hpp>
|
||||
#include <llarp/link_message.hpp>
|
||||
#include <llarp/routing/handler.hpp>
|
||||
#include "llarp/iwp/establish_job.hpp"
|
||||
|
||||
#include "crypto.hpp"
|
||||
#include "fs.hpp"
|
||||
#include "mem.hpp"
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
struct try_connect_ctx
|
||||
{
|
||||
llarp_router *router = nullptr;
|
||||
llarp_ai addr;
|
||||
};
|
||||
/** 2^15 bytes */
|
||||
#define MAX_LINK_MSG_SIZE (32768)
|
||||
|
||||
// forward declare
|
||||
namespace path
|
||||
{
|
||||
struct TransitHop;
|
||||
}
|
||||
} // namespace llarp
|
||||
// TODO: unused. remove?
|
||||
// struct try_connect_ctx
|
||||
// {
|
||||
// llarp_router *router = nullptr;
|
||||
// llarp_ai addr;
|
||||
// };
|
||||
|
||||
// // forward declare
|
||||
// namespace path
|
||||
// {
|
||||
// struct TransitHop;
|
||||
// }
|
||||
|
||||
struct llarp_link;
|
||||
struct llarp_link_session_iter;
|
||||
|
||||
/// c++
|
||||
bool
|
||||
llarp_findOrCreateEncryption(llarp_crypto *crypto, const char *fpath,
|
||||
llarp::SecretKey *encryption);
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#include "buffer.hpp"
|
||||
#include "logger.hpp"
|
||||
|
||||
extern "C" {
|
||||
void
|
||||
llarp_rc_free(struct llarp_rc *rc)
|
||||
{
|
||||
|
@ -222,4 +221,3 @@ llarp_rc_bencode(const struct llarp_rc *rc, llarp_buffer_t *buff)
|
|||
return false;
|
||||
return bencode_end(buff);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -109,7 +109,6 @@ struct llarp_threadpool
|
|||
}
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
struct llarp_threadpool *
|
||||
llarp_init_threadpool(int workers, const char *name)
|
||||
{
|
||||
|
@ -188,4 +187,3 @@ llarp_free_threadpool(struct llarp_threadpool **pool)
|
|||
}
|
||||
*pool = nullptr;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@ namespace llarp
|
|||
}
|
||||
} // namespace llarp
|
||||
|
||||
extern "C" {
|
||||
llarp_time_t
|
||||
llarp_time_now_ms()
|
||||
{
|
||||
|
@ -27,4 +26,3 @@ llarp_time_now_sec()
|
|||
{
|
||||
return llarp::time_since_epoch< std::chrono::seconds, llarp_seconds_t >();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -132,8 +132,6 @@ struct llarp_timer_context
|
|||
}
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
|
||||
struct llarp_timer_context*
|
||||
llarp_init_timer()
|
||||
{
|
||||
|
@ -234,7 +232,6 @@ llarp_timer_run(struct llarp_timer_context* t, struct llarp_threadpool* pool)
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
|
@ -255,4 +252,4 @@ namespace llarp
|
|||
}
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
} // namespace llarp
|
||||
|
|
Loading…
Reference in New Issue