mirror of https://github.com/oxen-io/lokinet
parent
c2ef57d9a2
commit
93f0e03958
|
@ -27,12 +27,10 @@ set(LIB_SRC
|
|||
llarp/iwp_link.cpp
|
||||
llarp/link.c
|
||||
llarp/link_intro.cpp
|
||||
llarp/link_relay_down.cpp
|
||||
llarp/link_relay_up.cpp
|
||||
llarp/link_message.cpp
|
||||
llarp/logic.c
|
||||
llarp/mem.cpp
|
||||
llarp/mem_std.cpp
|
||||
llarp/muxer.cpp
|
||||
llarp/net.cpp
|
||||
llarp/nodedb.cpp
|
||||
llarp/router_contact.c
|
||||
|
|
|
@ -16,7 +16,6 @@ progress()
|
|||
|
||||
struct llarp_main
|
||||
{
|
||||
struct llarp_alloc mem;
|
||||
struct llarp_crypto crypto;
|
||||
struct llarp_router *router = nullptr;
|
||||
struct llarp_threadpool *worker = nullptr;
|
||||
|
@ -182,8 +181,6 @@ main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
sllarp = new llarp_main;
|
||||
llarp_mem_stdlib(&sllarp->mem);
|
||||
auto mem = &sllarp->mem;
|
||||
// llarp_new_config(&sllarp->config);
|
||||
// llarp_ev_loop_alloc(&sllarp->mainloop);
|
||||
llarp_crypto_libsodium_init(&sllarp->crypto);
|
||||
|
@ -197,8 +194,8 @@ main(int argc, char *argv[])
|
|||
llarp_rc_clear(&tmp);
|
||||
// if we zero it out then
|
||||
// allocate fresh pointers that the bencoder can expect to be ready
|
||||
tmp.addrs = llarp_ai_list_new(mem);
|
||||
tmp.exits = llarp_xi_list_new(mem);
|
||||
tmp.addrs = llarp_ai_list_new();
|
||||
tmp.exits = llarp_xi_list_new();
|
||||
// set updated timestamp
|
||||
tmp.last_updated = llarp_time_now_ms();
|
||||
// load longterm identity
|
||||
|
@ -242,7 +239,7 @@ main(int argc, char *argv[])
|
|||
buf.sz = sizeof(tmpc);
|
||||
f.read((char *)tmpc, sizeof(MAX_RC_SIZE));
|
||||
// printf("contents[%s]\n", tmpc);
|
||||
if(!llarp_rc_bdecode(mem, &tmp, &buf))
|
||||
if(!llarp_rc_bdecode(&tmp, &buf))
|
||||
{
|
||||
printf("Can't decode\n");
|
||||
return 0;
|
||||
|
|
|
@ -39,7 +39,7 @@ struct llarp_ai_list;
|
|||
|
||||
/// list of address information initialization
|
||||
struct llarp_ai_list *
|
||||
llarp_ai_list_new(struct llarp_alloc *mem);
|
||||
llarp_ai_list_new();
|
||||
|
||||
/// list of address information destruction
|
||||
void
|
||||
|
|
|
@ -20,8 +20,8 @@ struct llarp_async_iwp;
|
|||
|
||||
/// allocator
|
||||
struct llarp_async_iwp *
|
||||
llarp_async_iwp_new(struct llarp_alloc *mem, struct llarp_crypto *crypto,
|
||||
struct llarp_logic *logic, struct llarp_threadpool *worker);
|
||||
llarp_async_iwp_new(struct llarp_crypto *crypto, struct llarp_logic *logic,
|
||||
struct llarp_threadpool *worker);
|
||||
|
||||
/// deallocator
|
||||
void
|
||||
|
|
|
@ -30,7 +30,7 @@ llarp_xi_bencode(struct llarp_xi *xi, llarp_buffer_t *buf);
|
|||
struct llarp_xi_list;
|
||||
|
||||
struct llarp_xi_list *
|
||||
llarp_xi_list_new(struct llarp_alloc *mem);
|
||||
llarp_xi_list_new();
|
||||
|
||||
void
|
||||
llarp_xi_list_free(struct llarp_xi_list *l);
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
#ifndef LLARP_FRAME_HANDLER_HPP
|
||||
#define LLARP_FRAME_HANDLER_HPP
|
||||
#include <llarp/mem.h>
|
||||
#include <vector>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
struct FrameHandler
|
||||
{
|
||||
bool
|
||||
Process(const std::vector< byte_t >& buffer);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,14 +0,0 @@
|
|||
#ifndef LLARP_IBFQ_H_
|
||||
#define LLARP_IBFQ_H_
|
||||
#include <llarp/buffer.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,34 +0,0 @@
|
|||
#ifndef LLARP_IBMQ_H_
|
||||
#define LLARP_IBMQ_H_
|
||||
#include <llarp/buffer.h>
|
||||
#include <llarp/msg_handler.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct llarp_mq;
|
||||
|
||||
struct llarp_mq *
|
||||
llarp_init_mq();
|
||||
void
|
||||
llarp_free_mq(struct llarp_mq **queue);
|
||||
/**
|
||||
offer a full message to the inbound message queue
|
||||
return true if successfully added
|
||||
return false if the queue is full
|
||||
*/
|
||||
bool
|
||||
llarp_mq_offer(struct llarp_mq *queue, llarp_buffer_t msg);
|
||||
size_t
|
||||
llarp_mq_peek(struct llarp_mq *queue);
|
||||
/** return true if we have more messages to process */
|
||||
bool
|
||||
llarp_mq_process(struct llarp_mq *queue, struct llarp_msg_muxer *muxer);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -2,7 +2,6 @@
|
|||
#define LLARP_IWP_H_
|
||||
#include <llarp/crypto.h>
|
||||
#include <llarp/link.h>
|
||||
#include <llarp/msg_handler.h>
|
||||
#include <llarp/router_identity.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -11,16 +10,15 @@ extern "C" {
|
|||
|
||||
struct llarp_iwp_args
|
||||
{
|
||||
struct llarp_alloc* mem;
|
||||
struct llarp_crypto* crypto;
|
||||
struct llarp_logic* logic;
|
||||
struct llarp_threadpool* cryptoworker;
|
||||
struct llarp_router* router;
|
||||
const char* keyfile;
|
||||
};
|
||||
|
||||
void
|
||||
iwp_link_init(struct llarp_link* link, struct llarp_iwp_args args,
|
||||
struct llarp_msg_muxer* muxer);
|
||||
iwp_link_init(struct llarp_link* link, struct llarp_iwp_args args);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#include <llarp/ev.h>
|
||||
#include <llarp/logic.h>
|
||||
#include <llarp/mem.h>
|
||||
#include <llarp/msg_handler.h>
|
||||
#include <llarp/obmd.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
|
@ -61,9 +60,13 @@ struct llarp_link_ev_listener
|
|||
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 *);
|
||||
/*
|
||||
|
@ -99,6 +102,10 @@ struct llarp_link_session
|
|||
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 router contact of remote router */
|
||||
struct llarp_rc *(*get_remote_router)(struct llarp_link_session *);
|
||||
};
|
||||
|
||||
bool
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
#ifndef LLARP_LINK_MESSAGE_HPP
|
||||
#define LLARP_LINK_MESSAGE_HPP
|
||||
|
||||
#include <llarp/bencode.h>
|
||||
#include <llarp/link.h>
|
||||
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
typedef std::vector< byte_t > OutboundMessage;
|
||||
|
||||
struct InboundMessageHandler
|
||||
{
|
||||
InboundMessageHandler(llarp_router* router);
|
||||
dict_reader reader;
|
||||
|
||||
static bool
|
||||
OnKey(dict_reader* r, llarp_buffer_t* buf);
|
||||
|
||||
bool
|
||||
ProcessFrom(llarp_link_session* from, llarp_buffer_t buf);
|
||||
|
||||
bool
|
||||
FlushReplies();
|
||||
|
||||
private:
|
||||
char msgtype;
|
||||
bool firstkey;
|
||||
uint64_t proto;
|
||||
llarp_router* router;
|
||||
llarp_link_session* from;
|
||||
std::queue< OutboundMessage > sendq;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,60 +0,0 @@
|
|||
#ifndef LLARP_MSG_HANDLER_H_
|
||||
#define LLARP_MSG_HANDLER_H_
|
||||
#include <llarp/buffer.h>
|
||||
#include <llarp/dht.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* foward declare */
|
||||
struct llarp_msg_muxer;
|
||||
struct llarp_link_session;
|
||||
struct llarp_router;
|
||||
|
||||
struct llarp_frame_handler
|
||||
{
|
||||
/**
|
||||
* participating paths
|
||||
*/
|
||||
struct llarp_path_context *paths;
|
||||
|
||||
/**
|
||||
* parent muxer
|
||||
*/
|
||||
struct llarp_msg_muxer *parent;
|
||||
|
||||
/**
|
||||
handle fully formed frame from link session
|
||||
*/
|
||||
bool (*process)(struct llarp_frame_handler *, struct llarp_link_session *,
|
||||
llarp_buffer_t);
|
||||
};
|
||||
|
||||
struct llarp_msg_handler
|
||||
{
|
||||
struct llarp_path_context *paths;
|
||||
struct llarp_dht_context *dht;
|
||||
bool (*process)(struct llarp_msg_handler *, llarp_buffer_t);
|
||||
};
|
||||
|
||||
struct llarp_msg_muxer
|
||||
{
|
||||
/** get a message handler for a link level message given msg.a */
|
||||
struct llarp_frame_handler *(*link_handler_for)(struct llarp_router *,
|
||||
const char);
|
||||
/** get a message handler for a routing layer message given msg.A */
|
||||
struct llarp_msg_handler *(*routing_handler_for)(struct llarp_router *,
|
||||
const char);
|
||||
};
|
||||
|
||||
/** fill function pointers with default values */
|
||||
void
|
||||
llarp_msg_muxer_init(struct llarp_msg_muxer *muxer);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,5 +1,8 @@
|
|||
#ifndef LLARP_PATH_H
|
||||
#define LLARP_PATH_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <llarp/types.h>
|
||||
|
||||
|
@ -10,9 +13,15 @@ struct llarp_transit_hop
|
|||
llarp_path_id_t id;
|
||||
llarp_sharedkey_t symkey;
|
||||
llarp_pubkey_t nextHop;
|
||||
llarp_pubkey_t prevHop;
|
||||
uint64_t started;
|
||||
uint64_t lifetime;
|
||||
llarp_version_t version;
|
||||
llarp_proto_version_t version;
|
||||
};
|
||||
|
||||
struct llarp_path_context;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -2,10 +2,8 @@
|
|||
#define LLARP_ROUTER_H_
|
||||
#include <llarp/config.h>
|
||||
#include <llarp/ev.h>
|
||||
#include <llarp/ibmq.h>
|
||||
#include <llarp/link.h>
|
||||
#include <llarp/logic.h>
|
||||
#include <llarp/obmd.h>
|
||||
#include <llarp/router_contact.h>
|
||||
#include <llarp/threadpool.h>
|
||||
|
||||
|
@ -37,13 +35,6 @@ llarp_run_router(struct llarp_router *router);
|
|||
void
|
||||
llarp_stop_router(struct llarp_router *router);
|
||||
|
||||
/** get router's inbound link level frame queue */
|
||||
struct llarp_link_queue *
|
||||
llarp_router_link_queue(struct llarp_router *router);
|
||||
/** get router's outbound link level frame dispatcher */
|
||||
struct llarp_link_dispatcher *
|
||||
llarp_router_link_dispatcher(struct llarp_router *router);
|
||||
|
||||
struct llarp_router_link_iter
|
||||
{
|
||||
void *user;
|
||||
|
|
|
@ -19,8 +19,7 @@ struct llarp_rc
|
|||
};
|
||||
|
||||
bool
|
||||
llarp_rc_bdecode(struct llarp_alloc *mem, struct llarp_rc *rc,
|
||||
llarp_buffer_t *buf);
|
||||
llarp_rc_bdecode(struct llarp_rc *rc, llarp_buffer_t *buf);
|
||||
bool
|
||||
llarp_rc_bencode(struct llarp_rc *rc, llarp_buffer_t *buf);
|
||||
|
||||
|
|
|
@ -7,12 +7,7 @@
|
|||
|
||||
struct llarp_ai_list
|
||||
{
|
||||
llarp_alloc *mem;
|
||||
std::vector< llarp_ai > list;
|
||||
|
||||
llarp_ai_list(llarp_alloc *m) : mem(m)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
static bool
|
||||
|
@ -194,9 +189,9 @@ llarp_ai_list_bencode(struct llarp_ai_list *l, llarp_buffer_t *buff)
|
|||
}
|
||||
|
||||
struct llarp_ai_list *
|
||||
llarp_ai_list_new(struct llarp_alloc *mem)
|
||||
llarp_ai_list_new()
|
||||
{
|
||||
return new llarp_ai_list(mem);
|
||||
return new llarp_ai_list;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
struct llarp_async_iwp
|
||||
{
|
||||
struct llarp_alloc *mem;
|
||||
struct llarp_crypto *crypto;
|
||||
struct llarp_logic *logic;
|
||||
struct llarp_threadpool *worker;
|
||||
|
@ -67,7 +66,6 @@ namespace iwp
|
|||
buf.cur = buf.base;
|
||||
buf.sz = intro->sz - 32;
|
||||
crypto->hmac(intro->buf, buf, sharedkey);
|
||||
llarp::dumphex< llarp_hmac_t >(intro->buf);
|
||||
// inform result
|
||||
llarp_logic_queue_job(intro->iwp->logic, {intro, &inform_intro});
|
||||
}
|
||||
|
@ -300,6 +298,9 @@ namespace iwp
|
|||
// T = HS(token + n)
|
||||
memcpy(tmp, token, 32);
|
||||
memcpy(tmp + 32, N, 32);
|
||||
buf.base = tmp;
|
||||
buf.cur = buf.base;
|
||||
buf.sz = sizeof(tmp);
|
||||
shorthash(T, buf);
|
||||
// K = TKE(a.k, b.k, T)
|
||||
dh(K, a_K, b_sK, T);
|
||||
|
@ -335,15 +336,18 @@ namespace iwp
|
|||
llarp_sharedkey_t digest;
|
||||
|
||||
llarp_buffer_t buf;
|
||||
buf.base = body;
|
||||
buf.base = nonce;
|
||||
buf.cur = buf.base;
|
||||
buf.sz = frame->sz - 64;
|
||||
buf.sz = frame->sz - 32;
|
||||
|
||||
// h = MDS(n + x, S)
|
||||
crypto->hmac(digest, buf, frame->sessionkey);
|
||||
// check hmac
|
||||
frame->success = memcmp(digest, hmac, 32) == 0;
|
||||
// x = SE(S, p, n[0:24])
|
||||
buf.base = body;
|
||||
buf.cur = buf.base;
|
||||
buf.sz = frame->sz - 64;
|
||||
crypto->xchacha20(buf, frame->sessionkey, nonce);
|
||||
// inform result
|
||||
llarp_logic_queue_job(frame->iwp->logic, {user, &inform_frame_done});
|
||||
|
@ -368,6 +372,9 @@ namespace iwp
|
|||
// x = SE(S, p, n[0:24])
|
||||
crypto->xchacha20(buf, frame->sessionkey, nonce);
|
||||
// h = MDS(n + x, S)
|
||||
buf.base = nonce;
|
||||
buf.cur = buf.base;
|
||||
buf.sz = frame->sz - 32;
|
||||
crypto->hmac(hmac, buf, frame->sessionkey);
|
||||
// inform result
|
||||
llarp_logic_queue_job(frame->iwp->logic, {user, &inform_frame_done});
|
||||
|
@ -450,13 +457,12 @@ iwp_call_async_verify_session_start(struct llarp_async_iwp *iwp,
|
|||
}
|
||||
|
||||
struct llarp_async_iwp *
|
||||
llarp_async_iwp_new(struct llarp_alloc *mem, struct llarp_crypto *crypto,
|
||||
struct llarp_logic *logic, struct llarp_threadpool *worker)
|
||||
llarp_async_iwp_new(struct llarp_crypto *crypto, struct llarp_logic *logic,
|
||||
struct llarp_threadpool *worker)
|
||||
{
|
||||
llarp_async_iwp *iwp = new llarp_async_iwp;
|
||||
if(iwp)
|
||||
{
|
||||
iwp->mem = mem;
|
||||
iwp->crypto = crypto;
|
||||
iwp->logic = logic;
|
||||
iwp->worker = worker;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#include <llarp/iwp.h>
|
||||
#include <llarp/net.h>
|
||||
#include <llarp/time.h>
|
||||
#include <llarp/frame_handler.hpp>
|
||||
#include "link/encoder.hpp"
|
||||
|
||||
#include <sodium/crypto_sign_ed25519.h>
|
||||
|
||||
|
@ -16,24 +16,18 @@
|
|||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include "buffer.hpp"
|
||||
#include "crypto.hpp"
|
||||
#include "fs.hpp"
|
||||
#include "mem.hpp"
|
||||
#include "net.hpp"
|
||||
#include "router.hpp"
|
||||
|
||||
namespace iwp
|
||||
{
|
||||
// session activity timeout is 10s
|
||||
constexpr llarp_time_t SESSION_TIMEOUT = 10000;
|
||||
|
||||
enum header_flag
|
||||
{
|
||||
eSessionInvalidated = (1 << 0),
|
||||
eHighPacketDrop = (1 << 1),
|
||||
eHighMTUDetected = (1 << 2),
|
||||
eProtoUpgrade = (1 << 3)
|
||||
};
|
||||
|
||||
enum msgtype
|
||||
{
|
||||
eALIV = 0x00,
|
||||
|
@ -42,6 +36,16 @@ namespace iwp
|
|||
eFRAG = 0x03
|
||||
};
|
||||
|
||||
typedef std::vector< byte_t > sendbuf_t;
|
||||
|
||||
enum header_flag
|
||||
{
|
||||
eSessionInvalidated = (1 << 0),
|
||||
eHighPacketDrop = (1 << 1),
|
||||
eHighMTUDetected = (1 << 2),
|
||||
eProtoUpgrade = (1 << 3)
|
||||
};
|
||||
|
||||
/** plaintext frame header */
|
||||
struct frame_header
|
||||
{
|
||||
|
@ -72,16 +76,15 @@ namespace iwp
|
|||
uint16_t
|
||||
size() const
|
||||
{
|
||||
uint16_t sz = (ptr[3] | 0x00ff) << 8;
|
||||
sz |= (ptr[2] & 0x00ff);
|
||||
uint16_t sz;
|
||||
memcpy(&sz, ptr + 2, 2);
|
||||
return sz;
|
||||
}
|
||||
|
||||
void
|
||||
setsize(uint16_t sz)
|
||||
{
|
||||
ptr[3] = (sz | 0xff00) >> 8;
|
||||
ptr[2] = (sz | 0x00ff);
|
||||
memcpy(ptr + 2, &sz, 2);
|
||||
}
|
||||
|
||||
uint8_t
|
||||
|
@ -97,6 +100,19 @@ namespace iwp
|
|||
}
|
||||
};
|
||||
|
||||
byte_t *
|
||||
init_sendbuf(sendbuf_t &buf, msgtype t, uint16_t sz, uint8_t flags)
|
||||
{
|
||||
buf.resize(6 + sz);
|
||||
frame_header hdr(buf.data());
|
||||
hdr.version() = 0;
|
||||
hdr.msgtype() = t;
|
||||
hdr.setsize(sz);
|
||||
buf[4] = 0;
|
||||
buf[5] = flags;
|
||||
return hdr.data();
|
||||
}
|
||||
|
||||
/** xmit header */
|
||||
struct xmit
|
||||
{
|
||||
|
@ -196,7 +212,7 @@ namespace iwp
|
|||
xmit msginfo;
|
||||
std::bitset< 16 > status;
|
||||
|
||||
std::map< uint16_t, fragment_t > frags;
|
||||
std::map< uint8_t, fragment_t > frags;
|
||||
fragment_t lastfrag;
|
||||
|
||||
transit_message()
|
||||
|
@ -213,11 +229,78 @@ namespace iwp
|
|||
{
|
||||
}
|
||||
|
||||
void
|
||||
ack(uint32_t bitmask)
|
||||
{
|
||||
uint8_t idx = 0;
|
||||
while(idx < 16)
|
||||
{
|
||||
if(bitmask & (1 << idx))
|
||||
{
|
||||
status.set(idx);
|
||||
}
|
||||
++idx;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
completed() const
|
||||
{
|
||||
for(const auto &item : frags)
|
||||
{
|
||||
if(!status.test(item.first))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
void
|
||||
generate_xmit(T &queue)
|
||||
{
|
||||
queue.emplace();
|
||||
auto &xmitbuf = queue.back();
|
||||
auto body_ptr = init_sendbuf(xmitbuf, eXMIT,
|
||||
sizeof(msginfo.buffer) + lastfrag.size(), 0);
|
||||
memcpy(body_ptr, msginfo.buffer, sizeof(msginfo.buffer));
|
||||
body_ptr += sizeof(msginfo.buffer);
|
||||
memcpy(body_ptr, lastfrag.data(), lastfrag.size());
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
void
|
||||
retransmit_frags(T &queue)
|
||||
{
|
||||
auto msgid = msginfo.msgid();
|
||||
auto fragsize = msginfo.fragsize();
|
||||
for(auto &frag : frags)
|
||||
{
|
||||
if(status.test(frag.first))
|
||||
continue;
|
||||
queue.emplace();
|
||||
auto &fragbuf = queue.back();
|
||||
auto body_ptr = init_sendbuf(fragbuf, eFRAG, 9 + fragsize, 0);
|
||||
memcpy(body_ptr, &msgid, 8);
|
||||
body_ptr[8] = frag.first;
|
||||
memcpy(body_ptr + 9, frag.second.data(), fragsize);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
reassemble(std::vector< byte_t > &buffer)
|
||||
{
|
||||
// TODO: implement
|
||||
return false;
|
||||
auto total = msginfo.totalsize();
|
||||
printf("reassemble message of size %d\n", total);
|
||||
buffer.resize(total);
|
||||
auto fragsz = msginfo.fragsize();
|
||||
auto ptr = buffer.data();
|
||||
for(const auto &frag : frags)
|
||||
{
|
||||
memcpy(ptr, frag.second.data(), fragsz);
|
||||
ptr += fragsz;
|
||||
}
|
||||
memcpy(ptr, lastfrag.data(), lastfrag.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -225,7 +308,7 @@ namespace iwp
|
|||
uint16_t mtu = 1024)
|
||||
{
|
||||
status.reset();
|
||||
uint16_t fragid = 0;
|
||||
uint8_t fragid = 0;
|
||||
uint16_t fragsize = mtu;
|
||||
while((buf.cur - buf.base) > fragsize)
|
||||
{
|
||||
|
@ -234,12 +317,12 @@ namespace iwp
|
|||
buf.cur += fragsize;
|
||||
frags[fragid++] = frag;
|
||||
}
|
||||
uint16_t lastfrag = buf.cur - buf.base;
|
||||
uint16_t lastfrag = buf.sz - (buf.cur - buf.base);
|
||||
// set info for xmit
|
||||
msginfo.set_info(hash, id, mtu, frags.size(), lastfrag);
|
||||
msginfo.set_info(hash, id, fragsize, lastfrag, frags.size());
|
||||
// copy message hash
|
||||
memcpy(msginfo.buffer, hash, 32);
|
||||
put_lastfrag(buf.cur, buf.cur - buf.base);
|
||||
put_lastfrag(buf.cur, lastfrag);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -258,47 +341,58 @@ namespace iwp
|
|||
std::map< uint64_t, transit_message > rx;
|
||||
std::map< uint64_t, transit_message * > tx;
|
||||
|
||||
typedef std::vector< byte_t > sendbuf_t;
|
||||
std::queue< sendbuf_t > sendqueue;
|
||||
typedef std::queue< sendbuf_t > sendqueue_t;
|
||||
|
||||
llarp::FrameHandler *handler = nullptr;
|
||||
llarp_router *router = nullptr;
|
||||
llarp_link_session *parent = nullptr;
|
||||
|
||||
sendqueue_t sendqueue;
|
||||
|
||||
void
|
||||
inbound_frame_complete(uint64_t id)
|
||||
clear()
|
||||
{
|
||||
std::vector< byte_t > buf;
|
||||
if(rx[id].reassemble(buf) && handler)
|
||||
{
|
||||
if(handler->Process(buf))
|
||||
printf("processed frame %ld\n", id);
|
||||
else
|
||||
printf("failed to process frame %ld", id);
|
||||
}
|
||||
rx.erase(id);
|
||||
rx.clear();
|
||||
for(auto &item : tx)
|
||||
delete item.second;
|
||||
tx.clear();
|
||||
}
|
||||
|
||||
void
|
||||
init_sendbuf(sendbuf_t &buf, msgtype t, uint16_t sz, uint8_t flags)
|
||||
bool
|
||||
inbound_frame_complete(uint64_t id)
|
||||
{
|
||||
buf.resize(6 + sz);
|
||||
buf[0] = 0;
|
||||
buf[1] = t;
|
||||
buf[2] = sz & 0x00ff;
|
||||
buf[3] = (sz & 0xff00) >> 8;
|
||||
buf[4] = 0;
|
||||
buf[5] = flags;
|
||||
bool success = false;
|
||||
std::vector< byte_t > msg;
|
||||
if(rx[id].reassemble(msg))
|
||||
{
|
||||
printf("handle message of size: %ld\n", msg.size());
|
||||
auto buf = llarp::Buffer< decltype(msg) >(msg);
|
||||
success = router->HandleRecvLinkMessage(parent, buf);
|
||||
if(success)
|
||||
{
|
||||
alive();
|
||||
if(id == 0)
|
||||
parent->established(parent);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("failed to reassemble message %ld\n", id);
|
||||
}
|
||||
rx.erase(id);
|
||||
return success;
|
||||
}
|
||||
|
||||
void
|
||||
push_ackfor(uint64_t id, uint32_t bitmask)
|
||||
{
|
||||
sendbuf_t buf;
|
||||
sendqueue.emplace();
|
||||
auto &buf = sendqueue.back();
|
||||
// TODO: set flags to nonzero as needed
|
||||
init_sendbuf(buf, eACKS, 12, 0);
|
||||
// TODO: this assumes big endian
|
||||
memcpy(buf.data() + 6, &id, 8);
|
||||
memcpy(buf.data() + 14, &bitmask, 4);
|
||||
sendqueue.push(buf);
|
||||
printf("ACK for %ld %d\n", id, bitmask);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -307,7 +401,7 @@ namespace iwp
|
|||
if(hdr.size() > sz)
|
||||
{
|
||||
// overflow
|
||||
printf("invalid XMIT frame size\n");
|
||||
printf("invalid XMIT frame size %d > %ld\n", hdr.size(), sz);
|
||||
return false;
|
||||
}
|
||||
sz = hdr.size();
|
||||
|
@ -330,27 +424,26 @@ namespace iwp
|
|||
// check LSB set on flags
|
||||
if(x.flags() & 0x01)
|
||||
{
|
||||
if(x.numfrags() > 0)
|
||||
auto id = x.msgid();
|
||||
auto itr = rx.try_emplace(id, x);
|
||||
if(itr.second)
|
||||
{
|
||||
auto itr = rx.try_emplace(x.msgid(), x);
|
||||
if(itr.second)
|
||||
// inserted, put last fragment
|
||||
itr.first->second.put_lastfrag(hdr.data() + sizeof(x.buffer),
|
||||
x.lastfrag());
|
||||
alive();
|
||||
if(x.numfrags() == 0)
|
||||
{
|
||||
// inserted, put last fragment
|
||||
itr.first->second.put_lastfrag(hdr.data() + sizeof(x.buffer),
|
||||
x.lastfrag());
|
||||
return true;
|
||||
printf("short XMIT\n");
|
||||
push_ackfor(id, 0);
|
||||
return inbound_frame_complete(id);
|
||||
}
|
||||
else
|
||||
printf("duplicate XMIT msgid=%ld\n", x.msgid());
|
||||
printf("got XMIT with %d fragments\n", x.numfrags());
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// short XMIT , no fragments so just ack
|
||||
auto id = x.msgid();
|
||||
push_ackfor(
|
||||
id, 0); // TODO: should this be before or after handling frame?
|
||||
inbound_frame_complete(id);
|
||||
}
|
||||
printf("duplicate XMIT msgid=%ld\n", x.msgid());
|
||||
}
|
||||
else
|
||||
printf("XMIT flags LSB not set\n");
|
||||
|
@ -372,14 +465,62 @@ namespace iwp
|
|||
bool
|
||||
got_acks(frame_header &hdr, size_t sz)
|
||||
{
|
||||
return false;
|
||||
if(hdr.size() > sz)
|
||||
{
|
||||
printf("invalid ACKS frame size %d > %ld\n", hdr.size(), sz);
|
||||
return false;
|
||||
}
|
||||
sz = hdr.size();
|
||||
if(sz < 12)
|
||||
{
|
||||
printf("invalid ACKS frame size %ld < 12\n", sz);
|
||||
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())
|
||||
{
|
||||
printf("ACK for missing TX frame: %ld\n", msgid);
|
||||
return false;
|
||||
}
|
||||
|
||||
alive();
|
||||
|
||||
itr->second->ack(bitmask);
|
||||
|
||||
if(itr->second->completed())
|
||||
{
|
||||
printf("message %ld acknoleged\n", msgid);
|
||||
delete itr->second;
|
||||
tx.erase(itr);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("message %ld retransmit fragments\n", msgid);
|
||||
itr->second->retransmit_frags(sendqueue);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// queue new outbound message
|
||||
void
|
||||
queue_tx(uint64_t id, transit_message *msg)
|
||||
{
|
||||
tx.try_emplace(id, msg);
|
||||
auto itr = tx.try_emplace(id, msg);
|
||||
if(itr.second)
|
||||
{
|
||||
msg->generate_xmit(sendqueue);
|
||||
msg->retransmit_frags(sendqueue);
|
||||
}
|
||||
else // duplicate
|
||||
delete msg;
|
||||
}
|
||||
|
||||
// get next frame to encrypt and transmit
|
||||
|
@ -413,11 +554,11 @@ namespace iwp
|
|||
alive();
|
||||
return true;
|
||||
case eXMIT:
|
||||
return got_xmit(hdr, sz - 4);
|
||||
return got_xmit(hdr, sz - 6);
|
||||
case eACKS:
|
||||
return got_acks(hdr, sz - 4);
|
||||
return got_acks(hdr, sz - 6);
|
||||
case eFRAG:
|
||||
return got_frag(hdr, sz - 4);
|
||||
return got_frag(hdr, sz - 6);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -427,12 +568,16 @@ namespace iwp
|
|||
struct session
|
||||
{
|
||||
llarp_alloc *mem;
|
||||
llarp_msg_muxer *muxer;
|
||||
llarp_udp_io *udp;
|
||||
llarp_crypto *crypto;
|
||||
llarp_async_iwp *iwp;
|
||||
llarp_logic *logic;
|
||||
llarp_rc *our_router;
|
||||
|
||||
llarp_link_session *parent = nullptr;
|
||||
llarp_link *link = nullptr;
|
||||
|
||||
llarp_rc *our_router = nullptr;
|
||||
llarp_rc remote_router;
|
||||
|
||||
llarp_seckey_t eph_seckey;
|
||||
llarp_pubkey_t remote;
|
||||
|
@ -440,6 +585,8 @@ namespace iwp
|
|||
|
||||
llarp_link_establish_job *establish_job = nullptr;
|
||||
|
||||
uint32_t establish_job_id = 0;
|
||||
|
||||
llarp::Addr addr;
|
||||
iwp_async_intro intro;
|
||||
iwp_async_introack introack;
|
||||
|
@ -456,23 +603,18 @@ namespace iwp
|
|||
eIntroSent,
|
||||
eIntroAckSent,
|
||||
eIntroAckRecv,
|
||||
eSessionStartSent,
|
||||
eLIMSent,
|
||||
eEstablished,
|
||||
eTimeout
|
||||
};
|
||||
|
||||
State state;
|
||||
|
||||
session(llarp_alloc *m, llarp_msg_muxer *mux, llarp_udp_io *u,
|
||||
llarp_async_iwp *i, llarp_crypto *c, llarp_logic *l,
|
||||
const byte_t *seckey, const llarp::Addr &a)
|
||||
: mem(m)
|
||||
, muxer(mux)
|
||||
, udp(u)
|
||||
, crypto(c)
|
||||
, iwp(i)
|
||||
, logic(l)
|
||||
, addr(a)
|
||||
, state(eInitial)
|
||||
session(llarp_alloc *m, llarp_udp_io *u, llarp_async_iwp *i,
|
||||
llarp_crypto *c, llarp_logic *l, const byte_t *seckey,
|
||||
const llarp::Addr &a)
|
||||
: mem(m), udp(u), crypto(c), iwp(i), logic(l), addr(a), state(eInitial)
|
||||
{
|
||||
if(seckey)
|
||||
memcpy(eph_seckey, seckey, sizeof(llarp_seckey_t));
|
||||
|
@ -480,10 +622,21 @@ namespace iwp
|
|||
{
|
||||
c->encryption_keygen(eph_seckey);
|
||||
}
|
||||
|
||||
llarp::Zero(&remote_router, sizeof(llarp_rc));
|
||||
}
|
||||
|
||||
~session()
|
||||
{
|
||||
llarp_rc_free(&remote_router);
|
||||
frame.clear();
|
||||
}
|
||||
|
||||
static llarp_rc *
|
||||
get_remote_router(llarp_link_session *s)
|
||||
{
|
||||
session *self = static_cast< session * >(s->impl);
|
||||
return &self->remote_router;
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -513,6 +666,7 @@ namespace iwp
|
|||
while(frame.next_frame(buf))
|
||||
{
|
||||
encrypt_frame_async_send(buf.base, buf.sz);
|
||||
frame.pop_next_frame();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -534,6 +688,9 @@ namespace iwp
|
|||
// probably a session start
|
||||
on_session_start(buf, sz);
|
||||
return;
|
||||
|
||||
case eSessionStartSent:
|
||||
case eLIMSent:
|
||||
case eEstablished:
|
||||
// session is started
|
||||
decrypt_frame(buf, sz);
|
||||
|
@ -554,11 +711,43 @@ namespace iwp
|
|||
printf("session start verify fail\n");
|
||||
return;
|
||||
}
|
||||
printf("session start okay\n");
|
||||
printf("session start verified, sending LIM\n");
|
||||
self->send_LIM();
|
||||
}
|
||||
|
||||
// auto msg = new transit_message;
|
||||
void
|
||||
send_LIM()
|
||||
{
|
||||
llarp_shorthash_t 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;
|
||||
auto msg = new transit_message;
|
||||
// hash message buffer
|
||||
crypto->shorthash(digest, buf);
|
||||
// put message buffer
|
||||
auto id = frame.txids++;
|
||||
msg->put_message(buf, digest, id);
|
||||
// put into outbound send queue
|
||||
add_outbound_message(id, msg);
|
||||
EnterState(eLIMSent);
|
||||
}
|
||||
else
|
||||
printf("failed to encode LIM\n");
|
||||
}
|
||||
|
||||
// auto buffer = llarp::EncodeLIM< decltype(buf) >(buf, our_router);
|
||||
void
|
||||
session_established()
|
||||
{
|
||||
printf("session established\n");
|
||||
EnterState(eEstablished);
|
||||
llarp_logic_cancel_call(logic, establish_job_id);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -592,6 +781,12 @@ namespace iwp
|
|||
return static_cast< session * >(s->impl)->timedout(now);
|
||||
}
|
||||
|
||||
static void
|
||||
set_established(llarp_link_session *s)
|
||||
{
|
||||
static_cast< session * >(s->impl)->session_established();
|
||||
}
|
||||
|
||||
static void
|
||||
close(llarp_link_session *s)
|
||||
{
|
||||
|
@ -620,7 +815,7 @@ namespace iwp
|
|||
{
|
||||
session *link = static_cast< session * >(start->user);
|
||||
llarp_ev_udp_sendto(link->udp, link->addr, start->buf, start->sz);
|
||||
link->EnterState(eEstablished);
|
||||
link->EnterState(eSessionStartSent);
|
||||
printf("session start sent\n");
|
||||
}
|
||||
|
||||
|
@ -650,7 +845,12 @@ namespace iwp
|
|||
session *self = static_cast< session * >(frame->user);
|
||||
if(frame->success)
|
||||
{
|
||||
self->frame.process(frame->buf + 64, frame->sz - 64);
|
||||
if(self->frame.process(frame->buf + 64, frame->sz - 64))
|
||||
{
|
||||
self->pump();
|
||||
}
|
||||
else
|
||||
printf("invalid frame\n");
|
||||
}
|
||||
else
|
||||
printf("decrypt frame fail\n");
|
||||
|
@ -703,7 +903,7 @@ namespace iwp
|
|||
printf("encrypt frame of size %ld\n", sz);
|
||||
// 64 bytes frame overhead for nonce and hmac
|
||||
auto frame = alloc_frame(nullptr, sz + 64);
|
||||
memcpy(frame->buf + 64, buf, sz - 64);
|
||||
memcpy(frame->buf + 64, buf, sz);
|
||||
frame->hook = &handle_frame_encrypt;
|
||||
iwp_call_async_frame_encrypt(iwp, frame);
|
||||
}
|
||||
|
@ -832,6 +1032,29 @@ namespace iwp
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
handle_establish_timeout(void *user, uint64_t orig, uint64_t left)
|
||||
{
|
||||
session *self = static_cast< session * >(user);
|
||||
if(self->establish_job)
|
||||
{
|
||||
self->establish_job->link = self->link;
|
||||
if(left)
|
||||
{
|
||||
// timer cancelled
|
||||
self->establish_job->session = self->parent;
|
||||
}
|
||||
else
|
||||
{
|
||||
// timer timeout
|
||||
self->establish_job->session = nullptr;
|
||||
}
|
||||
self->establish_job->result(self->establish_job);
|
||||
delete self->establish_job;
|
||||
self->establish_job = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
introduce(uint8_t *pub)
|
||||
{
|
||||
|
@ -856,13 +1079,15 @@ namespace iwp
|
|||
intro.user = this;
|
||||
intro.hook = &handle_generated_intro;
|
||||
iwp_call_async_gen_intro(iwp, &intro);
|
||||
// start introduce timer
|
||||
establish_job_id = llarp_logic_call_later(
|
||||
logic, {5000, this, &handle_establish_timeout});
|
||||
}
|
||||
|
||||
void
|
||||
EnterState(State st)
|
||||
{
|
||||
if(state == eInitial)
|
||||
frame.alive();
|
||||
frame.alive();
|
||||
state = st;
|
||||
}
|
||||
};
|
||||
|
@ -872,12 +1097,13 @@ namespace iwp
|
|||
typedef std::mutex mtx_t;
|
||||
typedef std::lock_guard< mtx_t > lock_t;
|
||||
|
||||
llarp_router *router;
|
||||
llarp_alloc *mem;
|
||||
llarp_logic *logic;
|
||||
llarp_crypto *crypto;
|
||||
llarp_ev_loop *netloop;
|
||||
llarp_msg_muxer *muxer;
|
||||
llarp_async_iwp *iwp;
|
||||
llarp_link *link = nullptr;
|
||||
llarp_udp_io udp;
|
||||
llarp::Addr addr;
|
||||
char keyfile[255];
|
||||
|
@ -890,12 +1116,13 @@ namespace iwp
|
|||
|
||||
llarp_seckey_t seckey;
|
||||
|
||||
server(llarp_alloc *m, llarp_crypto *c, llarp_logic *l, llarp_threadpool *w)
|
||||
server(llarp_router *r, llarp_crypto *c, llarp_logic *l,
|
||||
llarp_threadpool *w)
|
||||
{
|
||||
mem = m;
|
||||
router = r;
|
||||
crypto = c;
|
||||
logic = l;
|
||||
iwp = llarp_async_iwp_new(mem, crypto, logic, w);
|
||||
iwp = llarp_async_iwp_new(crypto, logic, w);
|
||||
}
|
||||
|
||||
~server()
|
||||
|
@ -906,7 +1133,7 @@ namespace iwp
|
|||
session *
|
||||
create_session(const llarp::Addr &src, const byte_t *seckey)
|
||||
{
|
||||
return new session(mem, muxer, &udp, iwp, crypto, logic, seckey, src);
|
||||
return new session(mem, &udp, iwp, crypto, logic, seckey, src);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -924,10 +1151,17 @@ namespace iwp
|
|||
s.sendto = &session::sendto;
|
||||
s.timeout = &session::is_timedout;
|
||||
s.close = &session::close;
|
||||
s.get_remote_router = &session::get_remote_router;
|
||||
s.established = &session::set_established;
|
||||
{
|
||||
lock_t lock(m_sessions_Mutex);
|
||||
m_sessions[src] = s;
|
||||
impl->parent = &m_sessions[src];
|
||||
}
|
||||
impl->link = link;
|
||||
impl->frame.router = router;
|
||||
impl->frame.parent = impl->parent;
|
||||
impl->our_router = &router->rc;
|
||||
}
|
||||
|
||||
session *
|
||||
|
@ -1078,12 +1312,11 @@ namespace iwp
|
|||
};
|
||||
|
||||
server *
|
||||
link_alloc(struct llarp_alloc *mem, struct llarp_msg_muxer *muxer,
|
||||
const char *keyfile, struct llarp_crypto *crypto,
|
||||
struct llarp_logic *logic, struct llarp_threadpool *worker)
|
||||
link_alloc(struct llarp_router *router, const char *keyfile,
|
||||
struct llarp_crypto *crypto, struct llarp_logic *logic,
|
||||
struct llarp_threadpool *worker)
|
||||
{
|
||||
server *link = new server(mem, crypto, logic, worker);
|
||||
link->muxer = muxer;
|
||||
server *link = new server(router, crypto, logic, worker);
|
||||
llarp::Zero(link->keyfile, sizeof(link->keyfile));
|
||||
strncpy(link->keyfile, keyfile, sizeof(link->keyfile));
|
||||
return link;
|
||||
|
@ -1167,7 +1400,9 @@ namespace iwp
|
|||
bool
|
||||
link_start(struct llarp_link *l, struct llarp_logic *logic)
|
||||
{
|
||||
server *link = static_cast< server * >(l->impl);
|
||||
server *link = static_cast< server * >(l->impl);
|
||||
// give link implementations
|
||||
link->link = l;
|
||||
link->timeout_job_id = 0;
|
||||
link->logic = logic;
|
||||
// start cleanup timer
|
||||
|
@ -1236,10 +1471,9 @@ namespace iwp
|
|||
extern "C" {
|
||||
|
||||
void
|
||||
iwp_link_init(struct llarp_link *link, struct llarp_iwp_args args,
|
||||
struct llarp_msg_muxer *muxer)
|
||||
iwp_link_init(struct llarp_link *link, struct llarp_iwp_args args)
|
||||
{
|
||||
link->impl = iwp::link_alloc(args.mem, muxer, args.keyfile, args.crypto,
|
||||
link->impl = iwp::link_alloc(args.router, args.keyfile, args.crypto,
|
||||
args.logic, args.cryptoworker);
|
||||
link->name = iwp::link_name;
|
||||
link->get_our_address = iwp::link_get_addr;
|
||||
|
|
|
@ -12,5 +12,6 @@ llarp_link_initialized(struct llarp_link* link)
|
|||
bool
|
||||
llarp_link_session_initialized(struct llarp_link_session* s)
|
||||
{
|
||||
return s && s->impl && s->sendto && s->timeout && s->close;
|
||||
return s && s->impl && s->sendto && s->timeout && s->close
|
||||
&& s->get_remote_router && s->established;
|
||||
}
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
#ifndef LLARP_LINK_HANDLERS_HPP
|
||||
#define LLARP_LINK_HANDLERS_HPP
|
||||
#include <llarp/msg_handler.h>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace frame
|
||||
{
|
||||
bool
|
||||
process_intro(struct llarp_frame_handler* h, struct llarp_link_session* s,
|
||||
llarp_buffer_t msg);
|
||||
bool
|
||||
process_relay_commit(struct llarp_frame_handler* h,
|
||||
struct llarp_link_session* s, llarp_buffer_t msg);
|
||||
bool
|
||||
process_relay_down(struct llarp_frame_handler* h,
|
||||
struct llarp_link_session* s, llarp_buffer_t msg);
|
||||
bool
|
||||
process_relay_up(struct llarp_frame_handler* h,
|
||||
struct llarp_link_session* s, llarp_buffer_t msg);
|
||||
bool
|
||||
process_relay_accept(struct llarp_frame_handler* h,
|
||||
struct llarp_link_session* s, llarp_buffer_t msg);
|
||||
bool
|
||||
process_relay_status(struct llarp_frame_handler* h,
|
||||
struct llarp_link_session* s, llarp_buffer_t msg);
|
||||
bool
|
||||
process_relay_exit(struct llarp_frame_handler* h,
|
||||
struct llarp_link_session* s, llarp_buffer_t msg);
|
||||
} // namespace frame
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
|
@ -1,14 +0,0 @@
|
|||
#include "link_handlers.hpp"
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace frame
|
||||
{
|
||||
bool
|
||||
process_intro(struct llarp_frame_handler* h, struct llarp_link_session* s,
|
||||
llarp_buffer_t msg)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
} // namespace frame
|
||||
} // namespace llarp
|
|
@ -0,0 +1,114 @@
|
|||
#include <llarp/router_contact.h>
|
||||
#include <llarp/link_message.hpp>
|
||||
#include "buffer.hpp"
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
InboundMessageHandler::InboundMessageHandler(llarp_router* _router)
|
||||
: router(_router)
|
||||
{
|
||||
reader.user = this;
|
||||
reader.on_key = &OnKey;
|
||||
}
|
||||
|
||||
bool
|
||||
InboundMessageHandler::OnKey(dict_reader* r, llarp_buffer_t* key)
|
||||
{
|
||||
InboundMessageHandler* handler =
|
||||
static_cast< InboundMessageHandler* >(r->user);
|
||||
llarp_buffer_t strbuf;
|
||||
|
||||
// we are reading the first key
|
||||
if(handler->firstkey)
|
||||
{
|
||||
// check for empty dict
|
||||
if(!key)
|
||||
return false;
|
||||
// we are expecting the first key to be 'a'
|
||||
if(!llarp_buffer_eq(*key, "a"))
|
||||
{
|
||||
printf("message does not have message type\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!bdecode_read_string(r->buffer, &strbuf))
|
||||
{
|
||||
printf("could not value of message type");
|
||||
return false;
|
||||
}
|
||||
// bad key size
|
||||
if(strbuf.sz != 1)
|
||||
{
|
||||
printf("bad mesage type size: %ld\n", strbuf.sz);
|
||||
return false;
|
||||
}
|
||||
handler->msgtype = *strbuf.cur;
|
||||
handler->firstkey = false;
|
||||
return true;
|
||||
}
|
||||
// check for not the last element
|
||||
if(!key)
|
||||
return true;
|
||||
|
||||
switch(handler->msgtype)
|
||||
{
|
||||
// LIM
|
||||
case 'i':
|
||||
if(llarp_buffer_eq(*key, "r"))
|
||||
{
|
||||
if(!llarp_rc_bdecode(handler->from->get_remote_router(handler->from),
|
||||
r->buffer))
|
||||
{
|
||||
printf("failed to decode RC\n");
|
||||
return false;
|
||||
}
|
||||
printf("decoded rc\n");
|
||||
return true;
|
||||
}
|
||||
else if(llarp_buffer_eq(*key, "v"))
|
||||
{
|
||||
if(!bdecode_read_integer(r->buffer, &handler->proto))
|
||||
return false;
|
||||
if(handler->proto != LLARP_PROTO_VERSION)
|
||||
{
|
||||
printf("llarp protocol version missmatch\n");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("invalid LIM key: %c\n", *key->cur);
|
||||
return false;
|
||||
}
|
||||
default:
|
||||
printf("unknown link message type: %c\n", handler->msgtype);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
InboundMessageHandler::ProcessFrom(llarp_link_session* src,
|
||||
llarp_buffer_t buf)
|
||||
{
|
||||
from = src;
|
||||
msgtype = 0;
|
||||
firstkey = true;
|
||||
return bdecode_read_dict(&buf, &reader);
|
||||
}
|
||||
|
||||
bool
|
||||
InboundMessageHandler::FlushReplies()
|
||||
{
|
||||
printf("sending replies\n");
|
||||
bool success = true;
|
||||
while(sendq.size())
|
||||
{
|
||||
auto& msg = sendq.front();
|
||||
auto buf = llarp::Buffer< decltype(msg) >(msg);
|
||||
success &= from->sendto(from, buf);
|
||||
sendq.pop();
|
||||
}
|
||||
return success;
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
#include "link_handlers.hpp"
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace frame
|
||||
{
|
||||
bool
|
||||
process_relay_down(struct llarp_frame_handler* h,
|
||||
struct llarp_link_session* s, llarp_buffer_t msg)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
} // namespace frame
|
||||
} // namespace llarp
|
|
@ -1,14 +0,0 @@
|
|||
#include "link_handlers.hpp"
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace frame
|
||||
{
|
||||
bool
|
||||
process_relay_up(struct llarp_frame_handler* h,
|
||||
struct llarp_link_session* s, llarp_buffer_t msg)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
} // namespace frame
|
||||
} // namespace llarp
|
|
@ -1,5 +1,6 @@
|
|||
#ifndef LLARP_MEM_HPP
|
||||
#define LLARP_MEM_HPP
|
||||
#include <llarp/buffer.h>
|
||||
#include <llarp/mem.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
@ -42,6 +43,20 @@ namespace llarp
|
|||
}
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
void
|
||||
dumphex_buffer(T buff)
|
||||
{
|
||||
size_t idx = 0;
|
||||
printf("buffer of size %ld\n", buff.sz);
|
||||
while(idx < buff.sz)
|
||||
{
|
||||
printf("%.2x ", buff.base[idx++]);
|
||||
if(idx % 8 == 0)
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
#include <llarp/msg_handler.h>
|
||||
#include "router.hpp"
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
static struct llarp_frame_handler*
|
||||
find_frame_handler(struct llarp_router* r, const char ch)
|
||||
{
|
||||
auto itr = r->frame_handlers.find(ch);
|
||||
if(itr != r->frame_handlers.end())
|
||||
{
|
||||
auto handler = &itr->second;
|
||||
handler->paths = r->paths;
|
||||
handler->parent = &r->muxer;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static struct llarp_msg_handler*
|
||||
find_msg_handler(struct llarp_router* r, const char ch)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
} // namespace llarp
|
||||
|
||||
extern "C" {
|
||||
void
|
||||
llarp_msg_muxer_init(struct llarp_msg_muxer* muxer)
|
||||
{
|
||||
muxer->link_handler_for = &llarp::find_frame_handler;
|
||||
muxer->routing_handler_for = &llarp::find_msg_handler;
|
||||
}
|
||||
}
|
|
@ -66,7 +66,7 @@ struct llarp_nodedb
|
|||
fclose(f);
|
||||
llarp_rc *rc = llarp::Alloc< llarp_rc >(mem);
|
||||
llarp::Zero(rc, sizeof(llarp_rc));
|
||||
if(llarp_rc_bdecode(mem, rc, &buff))
|
||||
if(llarp_rc_bdecode(rc, &buff))
|
||||
{
|
||||
if(llarp_rc_verify_sig(crypto, rc))
|
||||
{
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#include "router.hpp"
|
||||
#include <llarp/dtls.h>
|
||||
#include <llarp/ibfq.h>
|
||||
#include <llarp/iwp.h>
|
||||
#include <llarp/link.h>
|
||||
#include <llarp/proto.h>
|
||||
#include <llarp/router.h>
|
||||
#include <llarp/link_message.hpp>
|
||||
|
||||
#include "buffer.hpp"
|
||||
#include "net.hpp"
|
||||
#include "str.hpp"
|
||||
|
@ -18,10 +18,10 @@ namespace llarp
|
|||
const char *key, const char *val);
|
||||
} // namespace llarp
|
||||
|
||||
llarp_router::llarp_router(struct llarp_alloc *m) : ready(false), mem(m)
|
||||
llarp_router::llarp_router(struct llarp_alloc *m)
|
||||
: ready(false), mem(m), inbound_msg_handler(this)
|
||||
{
|
||||
llarp_rc_clear(&rc);
|
||||
llarp_msg_muxer_init(&muxer);
|
||||
}
|
||||
|
||||
llarp_router::~llarp_router()
|
||||
|
@ -29,6 +29,18 @@ llarp_router::~llarp_router()
|
|||
llarp_rc_free(&rc);
|
||||
}
|
||||
|
||||
bool
|
||||
llarp_router::HandleRecvLinkMessage(llarp_link_session *session,
|
||||
llarp_buffer_t buf)
|
||||
{
|
||||
if(inbound_msg_handler.ProcessFrom(session, buf))
|
||||
{
|
||||
return inbound_msg_handler.FlushReplies();
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
llarp_router::try_connect(fs::path rcfile)
|
||||
{
|
||||
|
@ -57,7 +69,7 @@ llarp_router::try_connect(fs::path rcfile)
|
|||
return;
|
||||
}
|
||||
}
|
||||
if(llarp_rc_bdecode(mem, &remote, &buf))
|
||||
if(llarp_rc_bdecode(&remote, &buf))
|
||||
{
|
||||
if(llarp_rc_verify_sig(&crypto, &remote))
|
||||
{
|
||||
|
@ -142,7 +154,6 @@ llarp_router::on_try_connect_result(llarp_link_establish_job *job)
|
|||
printf("session made\n");
|
||||
else
|
||||
printf("session not made\n");
|
||||
delete job;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -151,7 +162,7 @@ llarp_router::Run()
|
|||
// zero out router contact
|
||||
llarp::Zero(&rc, sizeof(llarp_rc));
|
||||
// fill our address list
|
||||
rc.addrs = llarp_ai_list_new(mem);
|
||||
rc.addrs = llarp_ai_list_new();
|
||||
for(auto link : links)
|
||||
{
|
||||
llarp_ai addr;
|
||||
|
@ -224,7 +235,6 @@ llarp_init_router(struct llarp_alloc *mem, struct llarp_threadpool *tp,
|
|||
router->tp = tp;
|
||||
router->logic = logic;
|
||||
llarp_crypto_libsodium_init(&router->crypto);
|
||||
llarp_msg_muxer_init(&router->muxer);
|
||||
}
|
||||
return router;
|
||||
}
|
||||
|
@ -286,7 +296,7 @@ void
|
|||
llarp_rc_set_addrs(struct llarp_rc *rc, struct llarp_alloc *mem,
|
||||
struct llarp_ai_list *addr)
|
||||
{
|
||||
rc->addrs = llarp_ai_list_new(mem);
|
||||
rc->addrs = llarp_ai_list_new();
|
||||
struct llarp_ai_list_iter ai_itr;
|
||||
ai_itr.user = rc;
|
||||
ai_itr.visit = &llarp_rc_addr_list_iter;
|
||||
|
@ -418,13 +428,13 @@ namespace llarp
|
|||
llarp::Zero(link, sizeof(llarp_link));
|
||||
|
||||
llarp_iwp_args args = {
|
||||
.mem = self->mem,
|
||||
.crypto = &self->crypto,
|
||||
.logic = self->logic,
|
||||
.cryptoworker = self->tp,
|
||||
.router = self,
|
||||
.keyfile = self->transport_keyfile.c_str(),
|
||||
};
|
||||
iwp_link_init(link, args, &self->muxer);
|
||||
iwp_link_init(link, args);
|
||||
if(llarp_link_initialized(link))
|
||||
{
|
||||
if(link->configure(link, self->netloop, key, af, proto))
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
#ifndef LLARP_ROUTER_HPP
|
||||
#define LLARP_ROUTER_HPP
|
||||
#include <llarp/link.h>
|
||||
#include <llarp/path.h>
|
||||
#include <llarp/router.h>
|
||||
#include <llarp/router_contact.h>
|
||||
#include <functional>
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
#include <llarp/link_message.hpp>
|
||||
|
||||
#include "fs.hpp"
|
||||
#include "mem.hpp"
|
||||
|
||||
|
@ -35,23 +38,27 @@ struct llarp_router
|
|||
// path to write our self signed rc to
|
||||
fs::path our_rc_file = "rc.signed";
|
||||
|
||||
// our router contact
|
||||
llarp_rc rc;
|
||||
|
||||
llarp_ev_loop *netloop;
|
||||
llarp_threadpool *tp;
|
||||
llarp_logic *logic;
|
||||
llarp_crypto crypto;
|
||||
llarp_msg_muxer muxer;
|
||||
llarp_path_context *paths;
|
||||
llarp_alloc *mem;
|
||||
llarp_seckey_t identity;
|
||||
|
||||
llarp::InboundMessageHandler inbound_msg_handler;
|
||||
|
||||
std::list< llarp_link * > links;
|
||||
std::map< char, llarp_frame_handler > frame_handlers;
|
||||
|
||||
llarp_router(llarp_alloc *mem);
|
||||
~llarp_router();
|
||||
|
||||
bool
|
||||
HandleRecvLinkMessage(struct llarp_link_session *from, llarp_buffer_t msg);
|
||||
|
||||
void
|
||||
AddLink(struct llarp_link *link);
|
||||
|
||||
|
|
|
@ -25,9 +25,7 @@ llarp_rc_decode_dict(struct dict_reader *r, llarp_buffer_t *key)
|
|||
{
|
||||
uint64_t v;
|
||||
llarp_buffer_t strbuf;
|
||||
struct llarp_rc_decoder *dec = r->user;
|
||||
struct llarp_alloc *mem = dec->mem;
|
||||
struct llarp_rc *rc = dec->rc;
|
||||
struct llarp_rc *rc = r->user;
|
||||
|
||||
if(!key)
|
||||
return true;
|
||||
|
@ -38,7 +36,7 @@ llarp_rc_decode_dict(struct dict_reader *r, llarp_buffer_t *key)
|
|||
{
|
||||
llarp_ai_list_free(rc->addrs);
|
||||
}
|
||||
rc->addrs = llarp_ai_list_new(mem);
|
||||
rc->addrs = llarp_ai_list_new();
|
||||
return llarp_ai_list_bdecode(rc->addrs, r->buffer);
|
||||
}
|
||||
|
||||
|
@ -72,7 +70,7 @@ llarp_rc_decode_dict(struct dict_reader *r, llarp_buffer_t *key)
|
|||
{
|
||||
llarp_xi_list_free(rc->exits);
|
||||
}
|
||||
rc->exits = llarp_xi_list_new(mem);
|
||||
rc->exits = llarp_xi_list_new();
|
||||
return llarp_xi_list_bdecode(rc->exits, r->buffer);
|
||||
}
|
||||
|
||||
|
@ -90,11 +88,9 @@ llarp_rc_decode_dict(struct dict_reader *r, llarp_buffer_t *key)
|
|||
}
|
||||
|
||||
bool
|
||||
llarp_rc_bdecode(struct llarp_alloc *mem, struct llarp_rc *rc,
|
||||
llarp_buffer_t *buff)
|
||||
llarp_rc_bdecode(struct llarp_rc *rc, llarp_buffer_t *buff)
|
||||
{
|
||||
struct llarp_rc_decoder decode = {.rc = rc, .mem = mem};
|
||||
struct dict_reader r = {.user = &decode, .on_key = &llarp_rc_decode_dict};
|
||||
struct dict_reader r = {.user = rc, .on_key = &llarp_rc_decode_dict};
|
||||
return bdecode_read_dict(buff, &r);
|
||||
}
|
||||
|
||||
|
@ -135,6 +131,7 @@ llarp_rc_bencode(struct llarp_rc *rc, llarp_buffer_t *buff)
|
|||
/* write dict begin */
|
||||
if(!bencode_start_dict(buff))
|
||||
return false;
|
||||
|
||||
if(rc->addrs)
|
||||
{
|
||||
/* write ai if they exist */
|
||||
|
|
|
@ -76,20 +76,13 @@ struct llarp_timer_context
|
|||
}
|
||||
|
||||
void
|
||||
cancel(uint32_t id, bool lockit = true)
|
||||
cancel(uint32_t id)
|
||||
{
|
||||
std::unique_lock< std::mutex >* lock = nullptr;
|
||||
if(lockit)
|
||||
lock = new std::unique_lock< std::mutex >(timersMutex);
|
||||
|
||||
auto itr = timers.find(id);
|
||||
if(itr != timers.end())
|
||||
{
|
||||
itr->second.exec();
|
||||
}
|
||||
|
||||
if(lock)
|
||||
delete lock;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -122,7 +115,7 @@ struct llarp_timer_context
|
|||
|
||||
for(auto id : ids)
|
||||
{
|
||||
cancel(id, false);
|
||||
cancel(id);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue