it does stuff :+DDDDD

pull/1/head
Jeff Becker 6 years ago
parent 44e34f81e8
commit a2d9dc1d93
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05

@ -2,6 +2,7 @@
#define LLARP_BENCODE_HPP
#include <llarp/bencode.h>
#include <llarp/logger.hpp>
namespace llarp
{
@ -35,15 +36,14 @@ namespace llarp
BEncodeMaybeReadDictEntry(const char* k, Item_t& item, bool& read,
llarp_buffer_t key, llarp_buffer_t* buf)
{
llarp_buffer_t strbuf;
if(llarp_buffer_eq(key, k))
{
if(!bencode_read_string(buf, &strbuf))
return false;
if(!item.BDecode(buf))
{
llarp::Warn("failed to decode key ", k);
return false;
}
read = true;
return true;
}
return true;
}
@ -58,7 +58,6 @@ namespace llarp
if(!bencode_read_integer(buf, &item))
return false;
read = item == expect;
return true;
}
return true;
}
@ -103,6 +102,6 @@ namespace llarp
return bencode_write_bytestring(buf, k, 1)
&& BEncodeWriteList(list.begin(), list.end(), buf);
}
}
} // namespace llarp
#endif

@ -201,8 +201,8 @@ namespace llarp
struct TXOwner
{
Key_t requester = {0};
uint64_t txid = 0;
Key_t requester;
uint64_t txid = 0;
bool
operator==(const TXOwner& other) const
@ -291,8 +291,8 @@ namespace llarp
uint64_t txid = 0;
uint64_t version = 0;
};
}
}
} // namespace dht
} // namespace llarp
struct llarp_dht_context
{

@ -11,27 +11,31 @@ namespace llarp
/// encrypted buffer base type
struct Encrypted
{
Encrypted() = default;
Encrypted(Encrypted&&) = delete;
Encrypted(const byte_t* buf, size_t sz);
Encrypted(size_t sz);
~Encrypted();
bool
BEncode(llarp_buffer_t* buf) const
{
return bencode_write_bytestring(buf, _data.data(), _data.size());
return bencode_write_bytestring(buf, _data, _sz);
}
void
Fill(byte_t fill)
{
std::fill(_data.begin(), _data.end(), fill);
size_t idx = 0;
while(idx < _sz)
_data[idx++] = fill;
}
void
Randomize()
{
if(_data.size())
randombytes(_data.data(), _data.size());
if(_data && _sz)
randombytes(_data, _sz);
}
bool
@ -42,8 +46,12 @@ namespace llarp
return false;
if(strbuf.sz == 0)
return false;
_data.resize(strbuf.sz);
memcpy(_data.data(), strbuf.base, _data.size());
if(_data)
delete[] _data;
_sz = strbuf.sz;
_data = new byte_t[_sz];
memcpy(_data, strbuf.base, _sz);
UpdateBuffer();
return true;
}
@ -56,24 +64,31 @@ namespace llarp
size_t
size()
{
return _data.size();
return _sz;
}
size_t
size() const
{
return _data.size();
return _sz;
}
byte_t*
data()
{
return _data.data();
return _data;
}
std::vector< byte_t > _data;
private:
protected:
void
UpdateBuffer()
{
m_Buffer.base = data();
m_Buffer.cur = data();
m_Buffer.sz = size();
}
byte_t* _data = nullptr;
size_t _sz = 0;
llarp_buffer_t m_Buffer;
};
} // namespace llarp

@ -12,7 +12,16 @@ namespace llarp
{
static constexpr size_t OverheadSize =
PUBKEYSIZE + TUNNONCESIZE + SHORTHASHSIZE;
EncryptedFrame() = default;
EncryptedFrame() : EncryptedFrame(256)
{
}
EncryptedFrame(const EncryptedFrame& other)
: EncryptedFrame(other._data, other._sz)
{
}
EncryptedFrame(byte_t* buf, size_t sz) : Encrypted(buf, sz)
{
}
@ -21,6 +30,17 @@ namespace llarp
{
}
EncryptedFrame&
operator=(const EncryptedFrame& other)
{
if(_data)
delete[] _data;
_sz = other._sz;
_data = new byte_t[_sz];
memcpy(_data, other._data, _sz);
return *this;
}
bool
DecryptInPlace(byte_t* seckey, llarp_crypto* crypto);
@ -87,7 +107,11 @@ namespace llarp
static_cast< AsyncFrameDecrypter< User >* >(user);
if(ctx->target->DecryptInPlace(ctx->seckey, ctx->crypto))
ctx->result(ctx->target->Buffer(), ctx->context);
{
auto buf = ctx->target->Buffer();
buf->cur = buf->base + EncryptedFrame::OverheadSize;
ctx->result(buf, ctx->context);
}
else
ctx->result(nullptr, ctx->context);
}

@ -19,8 +19,8 @@ namespace llarp
RouterID nextHop;
TunnelNonce tunnelNonce;
PathID_t pathid;
PoW *work = nullptr;
uint64_t version;
PoW *work = nullptr;
uint64_t version = 0;
bool
BDecode(llarp_buffer_t *buf);
@ -30,25 +30,14 @@ namespace llarp
~LR_CommitRecord();
bool
operator==(const LR_CommitRecord &other) const;
private:
static bool
OnKey(dict_reader *r, llarp_buffer_t *buf);
};
struct LR_AcceptRecord
{
RouterID upstream;
RouterID downstream;
PathID_t pathid;
uint64_t version = LLARP_PROTO_VERSION;
bool
DecodeKey(llarp_buffer_t key, llarp_buffer_t *buf);
bool
BEncode(llarp_buffer_t *buf) const;
};
struct LR_CommitMessage : public ILinkMessage
{
std::vector< EncryptedFrame > frames;

@ -155,117 +155,6 @@ namespace llarp
Upstream();
};
template < typename User >
struct AsyncPathKeyExchangeContext
{
Path* path = nullptr;
typedef void (*Handler)(AsyncPathKeyExchangeContext< User >*);
User* user = nullptr;
Handler result = nullptr;
size_t idx = 0;
llarp_threadpool* worker = nullptr;
llarp_logic* logic = nullptr;
llarp_crypto* crypto = nullptr;
LR_CommitMessage* LRCM = nullptr;
static void
HandleDone(void* u)
{
AsyncPathKeyExchangeContext< User >* ctx =
static_cast< AsyncPathKeyExchangeContext< User >* >(u);
ctx->result(ctx);
}
static void
GenerateNextKey(void* u)
{
AsyncPathKeyExchangeContext< User >* ctx =
static_cast< AsyncPathKeyExchangeContext< User >* >(u);
auto& hop = ctx->path->hops[ctx->idx];
// generate key
ctx->crypto->encryption_keygen(hop.commkey);
hop.nonce.Randomize();
// do key exchange
if(!ctx->crypto->dh_client(hop.shared, hop.router.enckey, hop.commkey,
hop.nonce))
{
llarp::Error("Failed to generate shared key for path build");
abort();
return;
}
// randomize hop's path id
hop.pathID.Randomize();
LR_CommitRecord record;
auto& frame = ctx->LRCM->frames[ctx->idx];
++ctx->idx;
if(ctx->idx < ctx->path->hops.size())
{
hop.upstream = ctx->path->hops[ctx->idx].router.pubkey;
}
else
{
hop.upstream = hop.router.pubkey;
}
auto buf = frame.Buffer();
buf->cur = buf->base + EncryptedFrame::OverheadSize;
// generate record
if(!record.BEncode(buf))
{
// failed to encode?
llarp::Error("Failed to generate Commit Record");
abort();
return;
}
// rewind
buf->cur = buf->base;
if(!frame.EncryptInPlace(hop.commkey, hop.router.enckey, ctx->crypto))
{
llarp::Error("Failed to encrypt LRCR");
abort();
return;
}
if(ctx->idx < ctx->path->hops.size())
{
// next hop
llarp_threadpool_queue_job(ctx->worker, {ctx, &GenerateNextKey});
}
else
{
// farthest hop
llarp_logic_queue_job(ctx->logic, {ctx, &HandleDone});
}
}
AsyncPathKeyExchangeContext(llarp_crypto* c) : crypto(c)
{
}
/// Generate all keys asynchronously and call hadler when done
void
AsyncGenerateKeys(Path* p, llarp_logic* l, llarp_threadpool* pool, User* u,
Handler func)
{
path = p;
logic = l;
user = u;
result = func;
worker = pool;
LRCM = new LR_CommitMessage;
for(size_t idx = 0; idx < MAXHOPS; ++idx)
{
LRCM->frames.emplace_back(256);
LRCM->frames.back().Randomize();
}
llarp_threadpool_queue_job(pool, {this, &GenerateNextKey});
}
};
enum PathBuildStatus
{
ePathBuildSuccess,

@ -14,7 +14,7 @@ namespace llarp
RouterID router;
uint64_t version = 0;
uint32_t extendedLifetime = 0;
byte_t nonce[32];
AlignedBuffer< 32 > nonce;
bool
BEncode(llarp_buffer_t* buf) const;
@ -24,6 +24,19 @@ namespace llarp
bool
IsValid(llarp_shorthash_func hashfunc, const RouterID& us) const;
bool
operator==(const PoW& other) const
{
return router == other.router && version == other.version
&& extendedLifetime == other.extendedLifetime && nonce == other.nonce;
}
bool
operator!=(const PoW& other) const
{
return !(*this == other);
}
};
} // namespace llarp

@ -5,15 +5,19 @@
namespace llarp
{
Encrypted::Encrypted(const byte_t* buf, size_t sz) : _data(sz)
Encrypted::Encrypted(const byte_t* buf, size_t sz) : _sz(sz)
{
_data = new byte_t[sz];
if(buf)
memcpy(data(), buf, sz);
else
llarp::Zero(data(), sz);
m_Buffer.base = data();
m_Buffer.cur = data();
m_Buffer.sz = size();
UpdateBuffer();
}
Encrypted::~Encrypted()
{
if(_data)
delete[] _data;
}
Encrypted::Encrypted(size_t sz) : Encrypted(nullptr, sz)

@ -64,10 +64,10 @@ namespace llarp
LR_CommitMessage* msg = new LR_CommitMessage;
while(frames.size())
{
msg->frames.push_back(frames.back());
frames.pop_back();
msg->frames.push_back(frames.front());
frames.pop_front();
}
return m_Router->SendToOrQueue(nextHop, {msg});
return m_Router->SendToOrQueue(nextHop, msg);
}
template < typename Map_t, typename Key_t, typename CheckValue_t >

@ -6,6 +6,115 @@
namespace llarp
{
template < typename User >
struct AsyncPathKeyExchangeContext
{
Path* path = nullptr;
typedef void (*Handler)(AsyncPathKeyExchangeContext< User >*);
User* user = nullptr;
Handler result = nullptr;
size_t idx = 0;
llarp_threadpool* worker = nullptr;
llarp_logic* logic = nullptr;
llarp_crypto* crypto = nullptr;
LR_CommitMessage* LRCM = nullptr;
static void
HandleDone(void* u)
{
AsyncPathKeyExchangeContext< User >* ctx =
static_cast< AsyncPathKeyExchangeContext< User >* >(u);
ctx->result(ctx);
}
static void
GenerateNextKey(void* u)
{
AsyncPathKeyExchangeContext< User >* ctx =
static_cast< AsyncPathKeyExchangeContext< User >* >(u);
auto& hop = ctx->path->hops[ctx->idx];
auto& frame = ctx->LRCM->frames[ctx->idx];
// generate key
ctx->crypto->encryption_keygen(hop.commkey);
hop.nonce.Randomize();
// do key exchange
if(!ctx->crypto->dh_client(hop.shared, hop.router.enckey, hop.commkey,
hop.nonce))
{
llarp::Error("Failed to generate shared key for path build");
abort();
return;
}
// randomize hop's path id
hop.pathID.Randomize();
LR_CommitRecord record;
++ctx->idx;
if(ctx->idx < ctx->path->hops.size())
{
hop.upstream = ctx->path->hops[ctx->idx].router.pubkey;
}
else
{
hop.upstream = hop.router.pubkey;
}
auto buf = frame.Buffer();
buf->cur = buf->base + EncryptedFrame::OverheadSize;
// generate record
if(!record.BEncode(buf))
{
// failed to encode?
llarp::Error("Failed to generate Commit Record");
return;
}
// use ephameral keypair for frame
SecretKey framekey;
ctx->crypto->encryption_keygen(framekey);
if(!frame.EncryptInPlace(framekey, hop.router.enckey, ctx->crypto))
{
llarp::Error("Failed to encrypt LRCR");
return;
}
if(ctx->idx < ctx->path->hops.size())
{
// next hop
llarp_threadpool_queue_job(ctx->worker, {ctx, &GenerateNextKey});
}
else
{
// farthest hop
llarp_logic_queue_job(ctx->logic, {ctx, &HandleDone});
}
}
AsyncPathKeyExchangeContext(llarp_crypto* c) : crypto(c)
{
}
/// Generate all keys asynchronously and call hadler when done
void
AsyncGenerateKeys(Path* p, llarp_logic* l, llarp_threadpool* pool, User* u,
Handler func)
{
path = p;
logic = l;
user = u;
result = func;
worker = pool;
LRCM = new LR_CommitMessage;
for(size_t idx = 0; idx < MAXHOPS; ++idx)
{
LRCM->frames.emplace_back();
LRCM->frames.back().Randomize();
}
llarp_threadpool_queue_job(pool, {this, &GenerateNextKey});
}
};
PathHopConfig::PathHopConfig()
{
llarp_rc_clear(&router);
@ -21,7 +130,7 @@ namespace llarp
AsyncPathKeyExchangeContext< llarp_pathbuild_job >* ctx)
{
auto remote = ctx->path->Upstream();
llarp::Debug("Generated LRCM to", remote);
llarp::Info("Generated LRCM to ", remote);
auto router = ctx->user->router;
if(!router->SendToOrQueue(remote, ctx->LRCM))
{
@ -65,27 +174,28 @@ llarp_pathbuilder_context::llarp_pathbuilder_context(
{
}
extern "C" {
struct llarp_pathbuilder_context*
llarp_pathbuilder_context_new(struct llarp_router* router,
struct llarp_dht_context* dht)
extern "C"
{
return new llarp_pathbuilder_context(router, dht);
}
struct llarp_pathbuilder_context*
llarp_pathbuilder_context_new(struct llarp_router* router,
struct llarp_dht_context* dht)
{
return new llarp_pathbuilder_context(router, dht);
}
void
llarp_pathbuilder_context_free(struct llarp_pathbuilder_context* ctx)
{
delete ctx;
}
void
llarp_pathbuilder_context_free(struct llarp_pathbuilder_context* ctx)
{
delete ctx;
}
void
llarp_pathbuilder_build_path(struct llarp_pathbuild_job* job)
{
job->router = job->context->router;
if(job->selectHop == nullptr)
job->selectHop = &llarp_nodedb_select_random_hop;
llarp_logic_queue_job(job->router->logic,
{job, &llarp::pathbuilder_start_build});
}
void
llarp_pathbuilder_build_path(struct llarp_pathbuild_job* job)
{
job->router = job->context->router;
if(job->selectHop == nullptr)
job->selectHop = &llarp_nodedb_select_random_hop;
llarp_logic_queue_job(job->router->logic,
{job, &llarp::pathbuilder_start_build});
}
}

@ -5,24 +5,6 @@
namespace llarp
{
bool
LR_AcceptRecord::BEncode(llarp_buffer_t* buf) const
{
if(!bencode_start_dict(buf))
return false;
if(!BEncodeWriteDictMsgType(buf, "c", "a"))
return false;
if(!BEncodeWriteDictEntry("p", pathid, buf))
return false;
if(!BEncodeWriteDictEntry("r", downstream, buf))
return false;
if(!BEncodeWriteDictEntry("t", upstream, buf))
return false;
if(!BEncodeWriteDictInt(buf, "v", LLARP_PROTO_VERSION))
return false;
return bencode_end(buf);
}
LR_CommitMessage::~LR_CommitMessage()
{
}
@ -121,7 +103,8 @@ namespace llarp
return false;
if(!BEncodeMaybeReadDictEntry("i", self->nextHop, read, *key, r->buffer))
return false;
if(BEncodeMaybeReadDictEntry("n", self->tunnelNonce, read, *key, r->buffer))
if(!BEncodeMaybeReadDictEntry("n", self->tunnelNonce, read, *key,
r->buffer))
return false;
if(!BEncodeMaybeReadDictEntry("p", self->pathid, read, *key, r->buffer))
return false;
@ -132,7 +115,10 @@ namespace llarp
{
// check for duplicate
if(self->work)
{
llarp::Warn("duplicate POW in LRCR");
return false;
}
self->work = new PoW;
return self->work->BDecode(r->buffer);
@ -149,6 +135,18 @@ namespace llarp
return bencode_read_dict(buf, &r);
}
bool
LR_CommitRecord::operator==(const LR_CommitRecord& other) const
{
if(work && other.work)
{
if(*work != *other.work)
return false;
}
return nextHop == other.nextHop && commkey == other.commkey
&& pathid == other.pathid;
}
struct LRCMFrameDecrypt
{
typedef AsyncFrameDecrypter< LRCMFrameDecrypt > Decrypter;
@ -165,7 +163,7 @@ namespace llarp
: decrypter(dec), context(ctx)
{
for(const auto& f : commit->frames)
frames.push_front(f);
frames.push_back(f);
hop.info.downstream = commit->remote;
}
@ -198,6 +196,7 @@ namespace llarp
delete self;
return;
}
buf->cur = buf->base + EncryptedFrame::OverheadSize;
llarp::Debug("decrypted LRCM from ", info.downstream);
// successful decrypt
if(!self->record.BDecode(buf))
@ -243,32 +242,9 @@ namespace llarp
self->frames.pop_front();
// put our response on the end
self->frames.emplace_back(sz);
auto& reply = self->frames.back();
auto replybuf = reply.Buffer();
LR_AcceptRecord replyrecord;
replyrecord.upstream = info.upstream;
replyrecord.downstream = info.downstream;
replyrecord.pathid = info.pathID;
if(!replyrecord.BEncode(replybuf))
{
llarp::Error("failed to encode reply to LRCM, buffer too small?");
delete self;
return;
}
// randomize leftover data inside reply
auto left = llarp_buffer_size_left(*replybuf);
if(left)
self->context->Crypto()->randbytes(replybuf->cur, left);
// random junk for now
self->frames.back().Randomize();
// encrypt in place since we are in the worker thread
if(!reply.EncryptInPlace(self->context->EncryptionSecretKey(),
self->record.commkey, self->context->Crypto()))
{
// failed to encrypt wtf?
llarp::Error("Failed to encrypt reply to LRCM");
delete self;
return;
}
if(self->context->HopIsUs(info.upstream))
{
// we are the farthest hop

@ -220,6 +220,8 @@ llarp_router::EnsureEncryptionKey()
return false;
}
f.read((char *)encryption.data(), encryption.size());
llarp::PubKey onionenckey = llarp::seckey_topublic(encryption);
llarp::Info("encryption key loaded ", onionenckey);
return true;
}
@ -652,7 +654,8 @@ llarp_router::Run()
llarp_logic_call_later(logic, {delay, this, &ConnectAll});
}
else
{ // delayed connect all for clients
{
// delayed connect all for clients
auto delay = ((rand() % 10) * 500) + 1000;
llarp_logic_call_later(logic, {delay, this, &ConnectAll});
}
@ -725,209 +728,210 @@ 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)
extern "C"
{
llarp_router *router = new llarp_router();
if(router)
struct llarp_router *
llarp_init_router(struct llarp_threadpool *tp, struct llarp_ev_loop *netloop,
struct llarp_logic *logic)
{
router->netloop = netloop;
router->tp = tp;
router->logic = logic;
// TODO: make disk io threadpool count configurable
llarp_router *router = new llarp_router();
if(router)
{
router->netloop = netloop;
router->tp = tp;
router->logic = logic;
// TODO: make disk io threadpool count configurable
#ifdef TESTNET
router->disk = tp;
router->disk = tp;
#else
router->disk = llarp_init_threadpool(1, "llarp-diskio");
router->disk = llarp_init_threadpool(1, "llarp-diskio");
#endif
llarp_crypto_libsodium_init(&router->crypto);
llarp_crypto_libsodium_init(&router->crypto);
}
return router;
}
return router;
}
bool
llarp_configure_router(struct llarp_router *router, struct llarp_config *conf)
{
llarp_config_iterator iter;
iter.user = router;
iter.visit = llarp::router_iter_config;
llarp_config_iter(conf, &iter);
if(!router->InitOutboundLink())
return false;
if(!router->Ready())
bool
llarp_configure_router(struct llarp_router *router, struct llarp_config *conf)
{
return false;
llarp_config_iterator iter;
iter.user = router;
iter.visit = llarp::router_iter_config;
llarp_config_iter(conf, &iter);
if(!router->InitOutboundLink())
return false;
if(!router->Ready())
{
return false;
}
return router->EnsureIdentity();
}
return router->EnsureIdentity();
}
void
llarp_run_router(struct llarp_router *router, struct llarp_nodedb *nodedb)
{
router->nodedb = nodedb;
router->Run();
}
void
llarp_run_router(struct llarp_router *router, struct llarp_nodedb *nodedb)
{
router->nodedb = nodedb;
router->Run();
}
bool
llarp_router_try_connect(struct llarp_router *router, struct llarp_rc *remote,
uint16_t numretries)
{
// do we already have a pending job for this remote?
if(router->HasPendingConnectJob(remote->pubkey))
return false;
// try first address only
llarp_ai addr;
if(llarp_ai_list_index(remote->addrs, 0, &addr))
bool
llarp_router_try_connect(struct llarp_router *router, struct llarp_rc *remote,
uint16_t numretries)
{
auto link = router->outboundLink;
auto itr = router->pendingEstablishJobs.emplace(
std::make_pair(remote->pubkey, llarp_link_establish_job{}));
auto job = &itr.first->second;
llarp_ai_copy(&job->ai, &addr);
memcpy(job->pubkey, remote->pubkey, PUBKEYSIZE);
job->retries = numretries;
job->timeout = 10000;
job->result = &llarp_router::on_try_connect_result;
// give router as user pointer
job->user = router;
// try establishing
link->try_establish(link, job);
return true;
// do we already have a pending job for this remote?
if(router->HasPendingConnectJob(remote->pubkey))
return false;
// try first address only
llarp_ai addr;
if(llarp_ai_list_index(remote->addrs, 0, &addr))
{
auto link = router->outboundLink;
auto itr = router->pendingEstablishJobs.emplace(
std::make_pair(remote->pubkey, llarp_link_establish_job{}));
auto job = &itr.first->second;
llarp_ai_copy(&job->ai, &addr);
memcpy(job->pubkey, remote->pubkey, PUBKEYSIZE);
job->retries = numretries;
job->timeout = 10000;
job->result = &llarp_router::on_try_connect_result;
// give router as user pointer
job->user = router;
// try establishing
link->try_establish(link, job);
return true;
}
return false;
}
return false;
}
void
llarp_rc_clear(struct llarp_rc *rc)
{
// zero out router contact
llarp::Zero(rc, sizeof(llarp_rc));
}
void
llarp_rc_clear(struct llarp_rc *rc)
{
// zero out router contact
llarp::Zero(rc, sizeof(llarp_rc));
}
bool
llarp_rc_addr_list_iter(struct llarp_ai_list_iter *iter, struct llarp_ai *ai)
{
struct llarp_rc *rc = (llarp_rc *)iter->user;
llarp_ai_list_pushback(rc->addrs, ai);
return true;
}
bool
llarp_rc_addr_list_iter(struct llarp_ai_list_iter *iter, struct llarp_ai *ai)
{
struct llarp_rc *rc = (llarp_rc *)iter->user;
llarp_ai_list_pushback(rc->addrs, ai);
return true;
}
void
llarp_rc_set_addrs(struct llarp_rc *rc, struct llarp_alloc *mem,
struct llarp_ai_list *addr)
{
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;
llarp_ai_list_iterate(addr, &ai_itr);
}
void
llarp_rc_set_addrs(struct llarp_rc *rc, struct llarp_alloc *mem,
struct llarp_ai_list *addr)
{
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;
llarp_ai_list_iterate(addr, &ai_itr);
}
void
llarp_rc_set_pubkey(struct llarp_rc *rc, const uint8_t *pubkey)
{
// set public key
memcpy(rc->pubkey, pubkey, 32);
}
void
llarp_rc_set_pubkey(struct llarp_rc *rc, const uint8_t *pubkey)
{
// set public key
memcpy(rc->pubkey, pubkey, 32);
}
bool
llarp_findOrCreateIdentity(llarp_crypto *crypto, const char *fpath,
byte_t *secretkey)
{
llarp::Debug("find or create ", fpath);
fs::path path(fpath);
std::error_code ec;
if(!fs::exists(path, ec))
bool
llarp_findOrCreateIdentity(llarp_crypto *crypto, const char *fpath,
byte_t *secretkey)
{
llarp::Info("regenerated identity key");
crypto->identity_keygen(secretkey);
std::ofstream f(path, std::ios::binary);
llarp::Debug("find or create ", fpath);
fs::path path(fpath);
std::error_code ec;
if(!fs::exists(path, ec))
{
llarp::Info("regenerated identity key");
crypto->identity_keygen(secretkey);
std::ofstream f(path, std::ios::binary);
if(f.is_open())
{
f.write((char *)secretkey, SECKEYSIZE);
}
}
std::ifstream f(path, std::ios::binary);
if(f.is_open())
{
f.write((char *)secretkey, SECKEYSIZE);
f.read((char *)secretkey, SECKEYSIZE);
return true;
}
llarp::Info("failed to get identity key");
return false;
}
std::ifstream f(path, std::ios::binary);
if(f.is_open())
bool
llarp_rc_write(struct llarp_rc *rc, const char *fpath)
{
f.read((char *)secretkey, SECKEYSIZE);
return true;
}
llarp::Info("failed to get identity key");
return false;
}
fs::path our_rc_file(fpath);
byte_t tmp[MAX_RC_SIZE];
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
bool
llarp_rc_write(struct llarp_rc *rc, const char *fpath)
{
fs::path our_rc_file(fpath);
byte_t tmp[MAX_RC_SIZE];
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
if(llarp_rc_bencode(rc, &buf))
{
std::ofstream f(our_rc_file, std::ios::binary);
if(f.is_open())
{
f.write((char *)buf.base, buf.cur - buf.base);
return true;
}
}
return false;
}
if(llarp_rc_bencode(rc, &buf))
void
llarp_rc_sign(llarp_crypto *crypto, const byte_t *seckey, struct llarp_rc *rc)
{
std::ofstream f(our_rc_file, std::ios::binary);
if(f.is_open())
byte_t buf[MAX_RC_SIZE];
auto signbuf = llarp::StackBuffer< decltype(buf) >(buf);
// zero out previous signature
llarp::Zero(rc->signature, sizeof(rc->signature));
// encode
if(llarp_rc_bencode(rc, &signbuf))
{
f.write((char *)buf.base, buf.cur - buf.base);
return true;
// sign
signbuf.sz = signbuf.cur - signbuf.base;
crypto->sign(rc->signature, seckey, signbuf);
}
}
return false;
}
void
llarp_rc_sign(llarp_crypto *crypto, const byte_t *seckey, struct llarp_rc *rc)
{
byte_t buf[MAX_RC_SIZE];
auto signbuf = llarp::StackBuffer< decltype(buf) >(buf);
// zero out previous signature
llarp::Zero(rc->signature, sizeof(rc->signature));
// encode
if(llarp_rc_bencode(rc, &signbuf))
void
llarp_stop_router(struct llarp_router *router)
{
// sign
signbuf.sz = signbuf.cur - signbuf.base;
crypto->sign(rc->signature, seckey, signbuf);
if(router)
router->Close();
}
}
void
llarp_stop_router(struct llarp_router *router)
{
if(router)
router->Close();
}
void
llarp_router_iterate_links(struct llarp_router *router,
struct llarp_router_link_iter i)
{
for(auto link : router->inboundLinks)
if(!i.visit(&i, router, link))
return;
i.visit(&i, router, router->outboundLink);
}
void
llarp_router_iterate_links(struct llarp_router *router,
struct llarp_router_link_iter i)
{
for(auto link : router->inboundLinks)
if(!i.visit(&i, router, link))
return;
i.visit(&i, router, router->outboundLink);
}
void
llarp_free_router(struct llarp_router **router)
{
if(*router)
void
llarp_free_router(struct llarp_router **router)
{
delete *router;
if(*router)
{
delete *router;
}
*router = nullptr;
}
*router = nullptr;
}
void
llarp_router_override_path_selection(struct llarp_router *router,
llarp_pathbuilder_select_hop_func func)
{
if(func)
router->selectHopFunc = func;
}
void
llarp_router_override_path_selection(struct llarp_router *router,
llarp_pathbuilder_select_hop_func func)
{
if(func)
router->selectHopFunc = func;
}
}
namespace llarp

@ -6,7 +6,6 @@
#include "logger.hpp"
extern "C" {
void
llarp_rc_free(struct llarp_rc *rc)
{
@ -157,7 +156,7 @@ llarp_rc_verify_sig(struct llarp_crypto *crypto, struct llarp_rc *rc)
result = crypto->verify(rc->pubkey, buf, sig);
}
else
llarp::Warn(__FILE__, "RC encode failed");
llarp::Warn("RC encode failed");
// restore sig
memcpy(rc->signature, sig, SIGSIZE);
return result;

@ -6,7 +6,7 @@
using EncryptedFrame = llarp::EncryptedFrame;
using SecretKey = llarp::SecretKey;
using PubKey = llarp::PubKey;
using LRAR = llarp::LR_AcceptRecord;
using LRCR = llarp::LR_CommitRecord;
class FrameTest : public ::testing::Test
{
@ -40,9 +40,9 @@ TEST_F(FrameTest, TestFrameCrypto)
{
EncryptedFrame f(256);
f.Fill(0);
LRAR record;
record.upstream.Fill(1);
record.downstream.Fill(2);
LRCR record;
record.nextHop.Fill(1);
record.tunnelNonce.Fill(2);
record.pathid.Fill(3);
auto buf = f.Buffer();
@ -50,8 +50,14 @@ TEST_F(FrameTest, TestFrameCrypto)
ASSERT_TRUE(record.BEncode(buf));
buf->cur = buf->base;
// encrypt alice to bob
// rewind buffer
buf->cur = buf->base + EncryptedFrame::OverheadSize;
// encrypt to alice
ASSERT_TRUE(f.EncryptInPlace(alice, llarp::seckey_topublic(bob), &crypto));
// decrypt from alice
ASSERT_TRUE(f.DecryptInPlace(bob, &crypto));
LRCR otherRecord;
ASSERT_TRUE(otherRecord.BDecode(buf));
ASSERT_TRUE(otherRecord == record);
};
Loading…
Cancel
Save