mirror of https://github.com/oxen-io/lokinet
Merge branch 'master' of https://github.com/majestrate/llarp
commit
d8329b9955
@ -0,0 +1,24 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Linux",
|
||||
"browse": {
|
||||
"path": [
|
||||
"${workspaceFolder}/llarp",
|
||||
"${workspaceFolder}/daemon",
|
||||
"${workspaceFolder}/include"
|
||||
],
|
||||
"limitSymbolsToIncludedHeaders": true
|
||||
},
|
||||
"includePath": [
|
||||
"${workspaceFolder}/include"
|
||||
],
|
||||
"defines": [],
|
||||
"compilerPath": "/usr/bin/clang",
|
||||
"cStandard": "c11",
|
||||
"cppStandard": "c++17",
|
||||
"intelliSenseMode": "clang-x64"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "(gdb) Launch",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "enter program name, for example ${workspaceFolder}/a.out",
|
||||
"args": [],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}",
|
||||
"environment": [],
|
||||
"externalConsole": true,
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
{
|
||||
"editor.formatOnSave": true
|
||||
}
|
@ -0,0 +1,101 @@
|
||||
#ifndef LLARP_BENCODE_HPP
|
||||
#define LLARP_BENCODE_HPP
|
||||
|
||||
#include <llarp/bencode.h>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
bool
|
||||
BEncodeWriteDictMsgType(llarp_buffer_t* buf, const char* k, const char* t)
|
||||
{
|
||||
return bencode_write_bytestring(buf, k, 1)
|
||||
&& bencode_write_bytestring(buf, t, 1);
|
||||
}
|
||||
|
||||
template < typename Obj_t >
|
||||
bool
|
||||
BEncodeWriteDictEntry(const char* k, const Obj_t& o, llarp_buffer_t* buf)
|
||||
{
|
||||
return bencode_write_bytestring(buf, k, 1) && o.BEncode(buf);
|
||||
}
|
||||
|
||||
template < typename Item_t >
|
||||
bool
|
||||
BEncodeRead(Item_t& item, llarp_buffer_t* buf);
|
||||
|
||||
template < typename Item_t >
|
||||
bool
|
||||
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))
|
||||
return false;
|
||||
read = true;
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template < typename Item_t >
|
||||
bool
|
||||
BEncodeMaybeReadVersion(const char* k, Item_t& item, uint64_t expect,
|
||||
bool& read, llarp_buffer_t key, llarp_buffer_t* buf)
|
||||
{
|
||||
if(llarp_buffer_eq(key, k))
|
||||
{
|
||||
if(!bencode_read_integer(buf, &item))
|
||||
return false;
|
||||
read = item == expect;
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template < typename Iter >
|
||||
bool
|
||||
BEncodeWriteList(Iter itr, Iter end, llarp_buffer_t* buf)
|
||||
{
|
||||
if(!bencode_start_list(buf))
|
||||
return false;
|
||||
while(itr != end)
|
||||
if(!itr->BEncode(buf))
|
||||
return false;
|
||||
else
|
||||
++itr;
|
||||
return bencode_end(buf);
|
||||
}
|
||||
|
||||
template < typename List_t >
|
||||
bool
|
||||
BEncodeReadList(List_t& result, llarp_buffer_t* buf)
|
||||
{
|
||||
if(*buf->cur != 'l') // ensure is a list
|
||||
return false;
|
||||
|
||||
buf->cur++;
|
||||
while(llarp_buffer_size_left(*buf) && *buf->cur != 'e')
|
||||
{
|
||||
if(!result.emplace(result.end())->BDecode(buf))
|
||||
return false;
|
||||
}
|
||||
if(*buf->cur != 'e') // make sure we're at a list end
|
||||
return false;
|
||||
buf->cur++;
|
||||
return true;
|
||||
}
|
||||
|
||||
template < typename List_t >
|
||||
bool
|
||||
BEncodeWriteDictList(const char* k, List_t& list, llarp_buffer_t* buf)
|
||||
{
|
||||
return bencode_write_bytestring(buf, k, 1)
|
||||
&& BEncodeWriteList(list.begin(), list.end(), buf);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,46 @@
|
||||
#ifndef LLARP_CRYPTO_HPP
|
||||
#define LLARP_CRYPTO_HPP
|
||||
|
||||
#include <llarp/crypto.h>
|
||||
#include <llarp/mem.h>
|
||||
#include <llarp/threadpool.h>
|
||||
#include <llarp/aligned.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
const byte_t*
|
||||
seckey_topublic(const byte_t* secret);
|
||||
|
||||
byte_t*
|
||||
seckey_topublic(byte_t* secret);
|
||||
|
||||
typedef AlignedBuffer< 32 > SharedSecret;
|
||||
typedef AlignedBuffer< 32 > KeyExchangeNonce;
|
||||
|
||||
typedef AlignedBuffer< PUBKEYSIZE > PubKey;
|
||||
|
||||
struct PubKeyHash
|
||||
{
|
||||
std::size_t
|
||||
operator()(PubKey const& a) const noexcept
|
||||
{
|
||||
size_t sz = 0;
|
||||
memcpy(&sz, a.data(), sizeof(size_t));
|
||||
return sz;
|
||||
}
|
||||
};
|
||||
|
||||
typedef AlignedBuffer< SECKEYSIZE > SecretKey;
|
||||
|
||||
typedef AlignedBuffer< SHORTHASHSIZE > ShortHash;
|
||||
|
||||
typedef AlignedBuffer< SIGSIZE > Signature;
|
||||
|
||||
typedef AlignedBuffer< TUNNONCESIZE > TunnelNonce;
|
||||
|
||||
typedef AlignedBuffer< 24 > SymmNonce;
|
||||
|
||||
typedef AlignedBuffer< 32 > SymmKey;
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,61 @@
|
||||
#ifndef LLARP_ENCCRYPTED_HPP
|
||||
#define LLARP_ENCCRYPTED_HPP
|
||||
|
||||
#include <llarp/bencode.h>
|
||||
#include <llarp/buffer.h>
|
||||
#include <sodium.h>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
/// encrypted buffer base type
|
||||
struct Encrypted
|
||||
{
|
||||
Encrypted() = default;
|
||||
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, size);
|
||||
}
|
||||
|
||||
void
|
||||
Randomize()
|
||||
{
|
||||
if(data)
|
||||
randombytes(data, size);
|
||||
}
|
||||
|
||||
bool
|
||||
BDecode(llarp_buffer_t* buf)
|
||||
{
|
||||
llarp_buffer_t strbuf;
|
||||
if(!bencode_read_string(buf, &strbuf))
|
||||
return false;
|
||||
if(strbuf.sz == 0)
|
||||
return false;
|
||||
if(data)
|
||||
delete[] data;
|
||||
size = strbuf.sz;
|
||||
data = new byte_t[size];
|
||||
memcpy(data, strbuf.base, size);
|
||||
return true;
|
||||
}
|
||||
|
||||
llarp_buffer_t*
|
||||
Buffer()
|
||||
{
|
||||
return &m_Buffer;
|
||||
}
|
||||
|
||||
byte_t* data = nullptr;
|
||||
size_t size = 0;
|
||||
|
||||
private:
|
||||
llarp_buffer_t m_Buffer;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,14 @@
|
||||
#ifndef LLARP_ENCRYPTED_ACK_HPP
|
||||
#define LLARP_ENCRYPTED_ACK_HPP
|
||||
#include <llarp/encrypted.hpp>
|
||||
namespace llarp
|
||||
{
|
||||
struct EncryptedAck : public Encrypted
|
||||
{
|
||||
bool
|
||||
DecryptInPlace(const byte_t* symkey, const byte_t* nonce,
|
||||
llarp_crypto* crypto);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -1,12 +1,115 @@
|
||||
#ifndef LLARP_ENCRYPTED_FRAME_HPP
|
||||
#define LLARP_ENCRYPTED_FRAME_HPP
|
||||
|
||||
#include <llarp/crypto.h>
|
||||
#include <llarp/mem.h>
|
||||
#include <vector>
|
||||
#include <llarp/threadpool.h>
|
||||
#include <llarp/encrypted.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
typedef std::vector< byte_t > EncryptedFrame;
|
||||
struct EncryptedFrame : public Encrypted
|
||||
{
|
||||
static constexpr size_t OverheadSize =
|
||||
PUBKEYSIZE + TUNNONCESIZE + SHORTHASHSIZE;
|
||||
|
||||
EncryptedFrame() = default;
|
||||
EncryptedFrame(byte_t* buf, size_t sz) : Encrypted(buf, sz)
|
||||
{
|
||||
}
|
||||
EncryptedFrame(size_t sz) : Encrypted(sz + OverheadSize)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
DecryptInPlace(byte_t* seckey, llarp_crypto* crypto);
|
||||
|
||||
bool
|
||||
EncryptInPlace(byte_t* seckey, byte_t* other, llarp_crypto* crypto);
|
||||
};
|
||||
|
||||
/// TOOD: can only handle 1 frame at a time
|
||||
template < typename User >
|
||||
struct AsyncFrameEncrypter
|
||||
{
|
||||
typedef void (*EncryptHandler)(EncryptedFrame*, User*);
|
||||
|
||||
static void
|
||||
Encrypt(void* user)
|
||||
{
|
||||
AsyncFrameEncrypter< User >* ctx =
|
||||
static_cast< AsyncFrameEncrypter< User >* >(user);
|
||||
|
||||
if(ctx->frame->EncryptInPlace(ctx->seckey, ctx->otherKey, ctx->crypto))
|
||||
ctx->handler(ctx->frame, ctx->user);
|
||||
else
|
||||
{
|
||||
delete ctx->frame;
|
||||
ctx->handler(nullptr, ctx->user);
|
||||
}
|
||||
}
|
||||
|
||||
llarp_crypto* crypto;
|
||||
byte_t* secretkey;
|
||||
EncryptHandler handler;
|
||||
EncryptedFrame* frame;
|
||||
User* user;
|
||||
byte_t* otherKey;
|
||||
|
||||
AsyncFrameEncrypter(llarp_crypto* c, byte_t* seckey, EncryptHandler h)
|
||||
: crypto(c), secretkey(seckey), handler(h)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
AsyncEncrypt(llarp_threadpool* worker, llarp_buffer_t buf, byte_t* other,
|
||||
User* u)
|
||||
{
|
||||
// TODO: should we own otherKey?
|
||||
otherKey = other;
|
||||
frame = new EncryptedFrame(buf.sz);
|
||||
memcpy(frame->data + EncryptedFrame::OverheadSize, buf.base, buf.sz);
|
||||
user = u;
|
||||
llarp_threadpool_queue_job(worker, {this, &Encrypt});
|
||||
}
|
||||
};
|
||||
|
||||
/// TOOD: can only handle 1 frame at a time
|
||||
template < typename User >
|
||||
struct AsyncFrameDecrypter
|
||||
{
|
||||
typedef void (*DecryptHandler)(llarp_buffer_t*, User*);
|
||||
|
||||
static void
|
||||
Decrypt(void* user)
|
||||
{
|
||||
AsyncFrameDecrypter< User >* ctx =
|
||||
static_cast< AsyncFrameDecrypter< User >* >(user);
|
||||
|
||||
if(ctx->target->DecryptInPlace(ctx->seckey, ctx->crypto))
|
||||
ctx->result(ctx->target->Buffer(), ctx->context);
|
||||
else
|
||||
ctx->result(nullptr, ctx->context);
|
||||
}
|
||||
|
||||
AsyncFrameDecrypter(llarp_crypto* c, byte_t* secretkey, DecryptHandler h)
|
||||
: result(h), crypto(c), seckey(secretkey)
|
||||
{
|
||||
}
|
||||
|
||||
DecryptHandler result;
|
||||
User* context;
|
||||
llarp_crypto* crypto;
|
||||
byte_t* seckey;
|
||||
EncryptedFrame* target;
|
||||
void
|
||||
AsyncDecrypt(llarp_threadpool* worker, EncryptedFrame* frame, User* user)
|
||||
{
|
||||
target = frame;
|
||||
context = user;
|
||||
llarp_threadpool_queue_job(worker, {this, &Decrypt});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -0,0 +1,15 @@
|
||||
#ifndef LLARP_MESSAGES_HPP
|
||||
#define LLARP_MESSAGES_HPP
|
||||
|
||||
/**
|
||||
include shortcut for all link and routing messages
|
||||
*/
|
||||
|
||||
#include <llarp/messages/dht_immediate.hpp>
|
||||
#include <llarp/messages/discard.hpp>
|
||||
#include <llarp/messages/link_intro.hpp>
|
||||
#include <llarp/messages/relay.hpp>
|
||||
#include <llarp/messages/relay_ack.hpp>
|
||||
#include <llarp/messages/relay_commit.hpp>
|
||||
|
||||
#endif
|
@ -0,0 +1,38 @@
|
||||
#ifndef LLARP_MESSAGES_RELAY_HPP
|
||||
#define LLARP_MESSAGES_RELAY_HPP
|
||||
#include <llarp/link_message.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
struct RelayUpstreamMessage : public ILinkMessage
|
||||
{
|
||||
RelayUpstreamMessage(const RouterID& from);
|
||||
~RelayUpstreamMessage();
|
||||
|
||||
bool
|
||||
DecodeKey(llarp_buffer_t key, llarp_buffer_t* buf);
|
||||
|
||||
bool
|
||||
BEncode(llarp_buffer_t* buf) const;
|
||||
|
||||
bool
|
||||
HandleMessage(llarp_router* router) const;
|
||||
};
|
||||
|
||||
struct RelayDownstreamMessage : public ILinkMessage
|
||||
{
|
||||
RelayDownstreamMessage(const RouterID& from);
|
||||
~RelayDownstreamMessage();
|
||||
|
||||
bool
|
||||
DecodeKey(llarp_buffer_t key, llarp_buffer_t* buf);
|
||||
|
||||
bool
|
||||
BEncode(llarp_buffer_t* buf) const;
|
||||
|
||||
bool
|
||||
HandleMessage(llarp_router* router) const;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,46 @@
|
||||
#ifndef LLARP_MESSAGES_RELAY_ACK_HPP
|
||||
#define LLARP_MESSAGES_RELAY_ACK_HPP
|
||||
#include <llarp/crypto.hpp>
|
||||
#include <llarp/encrypted_frame.hpp>
|
||||
#include <llarp/link_message.hpp>
|
||||
#include <llarp/path_types.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
struct LR_AckRecord
|
||||
{
|
||||
PubKey pubkey;
|
||||
TunnelNonce nonce;
|
||||
PathID_t rxPathID;
|
||||
uint64_t version = 0;
|
||||
|
||||
bool
|
||||
BEncode(llarp_buffer_t* buf) const;
|
||||
|
||||
bool
|
||||
BDecode(llarp_buffer_t* buf);
|
||||
};
|
||||
|
||||
struct LR_AckMessage : public ILinkMessage
|
||||
{
|
||||
std::vector< EncryptedFrame > acks;
|
||||
EncryptedFrame lasthopFrame;
|
||||
PathID_t txPathID;
|
||||
uint64_t version = 0;
|
||||
|
||||
LR_AckMessage(const RouterID& from);
|
||||
|
||||
~LR_AckMessage();
|
||||
|
||||
bool
|
||||
DecodeKey(llarp_buffer_t key, llarp_buffer_t* buf);
|
||||
|
||||
bool
|
||||
BEncode(llarp_buffer_t* buf) const;
|
||||
|
||||
bool
|
||||
HandleMessage(llarp_router* router) const;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -1,36 +0,0 @@
|
||||
#ifndef LLARP_OBMD_H_
|
||||
#define LLARP_OBMD_H_
|
||||
#include <llarp/buffer.h>
|
||||
#include <llarp/crypto.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* forward decl */
|
||||
struct llarp_link;
|
||||
|
||||
/**
|
||||
* link layer outbound message sending muxer
|
||||
*/
|
||||
struct llarp_link_dispatcher;
|
||||
|
||||
struct llarp_link_dispatcher *
|
||||
llarp_init_link_dispatcher();
|
||||
void
|
||||
llarp_free_link_dispatcher(struct llarp_link_dispatcher **dispatcher);
|
||||
|
||||
void
|
||||
llarp_link_sendto(struct llarp_link_dispatcher *dispatcher,
|
||||
llarp_pubkey_t pubkey, llarp_buffer_t msg);
|
||||
|
||||
void
|
||||
llarp_link_register(struct llarp_link_dispatcher *dispatcher,
|
||||
struct llarp_link *link);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,27 +0,0 @@
|
||||
#ifndef LLARP_PATH_H
|
||||
#define LLARP_PATH_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <llarp/types.h>
|
||||
|
||||
typedef uint64_t llarp_path_id_t;
|
||||
|
||||
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_proto_version_t version;
|
||||
};
|
||||
|
||||
struct llarp_path_context;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
@ -0,0 +1,297 @@
|
||||
#ifndef LLARP_PATH_HPP
|
||||
#define LLARP_PATH_HPP
|
||||
#include <llarp/router.h>
|
||||
#include <llarp/time.h>
|
||||
#include <llarp/aligned.hpp>
|
||||
#include <llarp/crypto.hpp>
|
||||
#include <llarp/messages/relay_ack.hpp>
|
||||
#include <llarp/messages/relay_commit.hpp>
|
||||
#include <llarp/path_types.hpp>
|
||||
#include <llarp/router_id.hpp>
|
||||
|
||||
#include <mutex>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
struct TransitHopInfo
|
||||
{
|
||||
TransitHopInfo() = default;
|
||||
TransitHopInfo(const RouterID& down, const LR_CommitRecord& record);
|
||||
|
||||
PathID_t rxID;
|
||||
PathID_t txID;
|
||||
RouterID upstream;
|
||||
RouterID downstream;
|
||||
|
||||
friend std::ostream&
|
||||
operator<<(std::ostream& out, const TransitHopInfo& info)
|
||||
{
|
||||
out << "<Transit Hop rxid=" << info.rxID << " txid=" << info.txID;
|
||||
out << " upstream=" << info.upstream << " downstream=" << info.downstream;
|
||||
return out << ">";
|
||||
}
|
||||
|
||||
bool
|
||||
operator==(const TransitHopInfo& other) const
|
||||
{
|
||||
return rxID == other.rxID && txID == other.txID
|
||||
&& upstream == other.upstream && downstream == other.downstream;
|
||||
}
|
||||
|
||||
bool
|
||||
operator!=(const TransitHopInfo& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
struct Hash
|
||||
{
|
||||
std::size_t
|
||||
operator()(TransitHopInfo const& a) const
|
||||
{
|
||||
std::size_t idx0, idx1, idx2, idx3;
|
||||
memcpy(&idx0, a.upstream, sizeof(std::size_t));
|
||||
memcpy(&idx1, a.downstream, sizeof(std::size_t));
|
||||
memcpy(&idx2, a.rxID, sizeof(std::size_t));
|
||||
memcpy(&idx3, a.txID, sizeof(std::size_t));
|
||||
return idx0 ^ idx1 ^ idx2 ^ idx3;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
struct TransitHop
|
||||
{
|
||||
TransitHop() = default;
|
||||
|
||||
SharedSecret rxKey;
|
||||
SharedSecret txKey;
|
||||
llarp_time_t started;
|
||||
llarp_proto_version_t version;
|
||||
};
|
||||
|
||||
struct PathHopConfig
|
||||
{
|
||||
/// path id
|
||||
PathID_t txID;
|
||||
/// router identity key
|
||||
PubKey encryptionKey;
|
||||
/// shared secret at this hop
|
||||
SharedSecret shared;
|
||||
/// nonce for key exchange
|
||||
TunnelNonce nonce;
|
||||
};
|
||||
|
||||
struct Path
|
||||
{
|
||||
typedef std::vector< PathHopConfig > HopList;
|
||||
HopList hops;
|
||||
llarp_time_t buildStarted;
|
||||
};
|
||||
|
||||
template < typename User >
|
||||
struct AsyncPathKeyExchangeContext
|
||||
{
|
||||
Path path;
|
||||
typedef void (*Handler)(AsyncPathKeyExchangeContext*);
|
||||
User* user = nullptr;
|
||||
Handler result = nullptr;
|
||||
const byte_t* secretkey = nullptr;
|
||||
size_t idx = 0;
|
||||
llarp_threadpool* worker = nullptr;
|
||||
llarp_path_dh_func dh = nullptr;
|
||||
|
||||
static void
|
||||
GenerateNextKey(void* user)
|
||||
{
|
||||
AsyncPathKeyExchangeContext< User >* ctx =
|
||||
static_cast< AsyncPathKeyExchangeContext< User >* >(user);
|
||||
|
||||
auto& hop = ctx->path.hops[ctx->idx];
|
||||
ctx->dh(hop.shared, hop.encryptionKey, hop.nonce, ctx->secretkey);
|
||||
++ctx->idx;
|
||||
if(ctx->idx < ctx.path.hops.size())
|
||||
{
|
||||
llarp_threadpool_queue_job(ctx->worker, {ctx, &GenerateNextKey});
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx->Done();
|
||||
}
|
||||
}
|
||||
|
||||
AsyncPathKeyExchangeContext(const byte_t* secret, llarp_crypto* crypto)
|
||||
: secretkey(secret), dh(crypto->dh_client)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Done()
|
||||
{
|
||||
idx = 0;
|
||||
result(this);
|
||||
}
|
||||
|
||||
/// Generate all keys asynchronously and call hadler when done
|
||||
void
|
||||
AsyncGenerateKeys(llarp_threadpool* pool, User* u, Handler func) const
|
||||
{
|
||||
user = u;
|
||||
result = func;
|
||||
worker = pool;
|
||||
llarp_threadpool_queue_job(pool, {this, &GenerateNextKey});
|
||||
}
|
||||
};
|
||||
|
||||
enum PathBuildStatus
|
||||
{
|
||||
ePathBuildSuccess,
|
||||
ePathBuildTimeout,
|
||||
ePathBuildReject
|
||||
};
|
||||
|
||||
/// path selection algorithm
|
||||
struct IPathSelectionAlgorithm
|
||||
{
|
||||
virtual ~IPathSelectionAlgorithm(){};
|
||||
/// select full path given an empty hop list to end at target
|
||||
virtual bool
|
||||
SelectFullPathTo(Path::HopList& hops, const RouterID& target) = 0;
|
||||
|
||||
/// report to path builder the result of a path build
|
||||
/// can be used to "improve" path building algoirthm in the
|
||||
/// future
|
||||
virtual void
|
||||
ReportPathBuildStatus(const Path::HopList& hops, const RouterID& target,
|
||||
PathBuildStatus status){};
|
||||
};
|
||||
|
||||
class PathBuildJob
|
||||
{
|
||||
public:
|
||||
PathBuildJob(llarp_router* router, IPathSelectionAlgorithm* selector);
|
||||
~PathBuildJob();
|
||||
|
||||
void
|
||||
Start();
|
||||
|
||||
private:
|
||||
typedef AsyncPathKeyExchangeContext< PathBuildJob > KeyExchanger;
|
||||
|
||||
LR_CommitMessage*
|
||||
BuildLRCM();
|
||||
|
||||
static void
|
||||
KeysGenerated(KeyExchanger* ctx);
|
||||
|
||||
llarp_router* router;
|
||||
IPathSelectionAlgorithm* m_HopSelector;
|
||||
KeyExchanger m_KeyExchanger;
|
||||
};
|
||||
|
||||
/// a pool of paths for a hidden service
|
||||
struct PathPool
|
||||
{
|
||||
PathPool(llarp_router* router);
|
||||
~PathPool();
|
||||
|
||||
/// build a new path to a router by identity key
|
||||
PathBuildJob*
|
||||
BuildNewPathTo(const RouterID& router);
|
||||
};
|
||||
|
||||
struct PathContext
|
||||
{
|
||||
PathContext(llarp_router* router);
|
||||
~PathContext();
|
||||
|
||||
void
|
||||
AllowTransit();
|
||||
void
|
||||
RejectTransit();
|
||||
|
||||
bool
|
||||
HasTransitHop(const TransitHopInfo& info);
|
||||
|
||||
bool
|
||||
HandleRelayCommit(const LR_CommitMessage* msg);
|
||||
|
||||
bool
|
||||
HandleRelayAck(const LR_AckMessage* msg);
|
||||
|
||||
void
|
||||
PutPendingRelayCommit(const RouterID& router, const PathID_t& txid,
|
||||
const TransitHopInfo& info, const TransitHop& hop);
|
||||
|
||||
bool
|
||||
HasPendingRelayCommit(const RouterID& upstream, const PathID_t& txid);
|
||||
|
||||
bool
|
||||
ForwardLRCM(const RouterID& nextHop, std::deque< EncryptedFrame >& frames,
|
||||
std::deque< EncryptedAck >& acks, EncryptedFrame& lastFrame);
|
||||
|
||||
bool
|
||||
HopIsUs(const PubKey& k) const;
|
||||
|
||||
typedef std::unordered_map< TransitHopInfo, TransitHop,
|
||||
TransitHopInfo::Hash >
|
||||
TransitHopsMap_t;
|
||||
|
||||
typedef std::pair< std::mutex, TransitHopsMap_t > SyncTransitMap_t;
|
||||
|
||||
struct PendingPathKey
|
||||
{
|
||||
RouterID upstream;
|
||||
PathID_t txID;
|
||||
|
||||
PendingPathKey(const RouterID& up, const PathID_t& id)
|
||||
: upstream(up), txID(id)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
operator==(const PendingPathKey& other) const
|
||||
{
|
||||
return upstream == other.upstream && txID == other.txID;
|
||||
}
|
||||
|
||||
struct Hash
|
||||
{
|
||||
std::size_t
|
||||
operator()(PendingPathKey const& a) const
|
||||
{
|
||||
std::size_t idx0, idx1;
|
||||
memcpy(&idx0, a.upstream, sizeof(std::size_t));
|
||||
memcpy(&idx1, a.txID, sizeof(std::size_t));
|
||||
return idx0 ^ idx1;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
typedef std::pair< TransitHopInfo, TransitHop > PendingCommit_t;
|
||||
|
||||
typedef std::pair< std::mutex,
|
||||
std::unordered_map< PendingPathKey, PendingCommit_t,
|
||||
PendingPathKey::Hash > >
|
||||
SyncPendingCommitMap_t;
|
||||
|
||||
llarp_threadpool*
|
||||
Worker();
|
||||
|
||||
llarp_crypto*
|
||||
Crypto();
|
||||
|
||||
byte_t*
|
||||
EncryptionSecretKey();
|
||||
|
||||
private:
|
||||
llarp_router* m_Router;
|
||||
SyncTransitMap_t m_TransitPaths;
|
||||
SyncPendingCommitMap_t m_WaitingForAcks;
|
||||
|
||||
bool m_AllowTransit;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,11 @@
|
||||
#ifndef LLARP_PATH_TYPES_HPP
|
||||
#define LLARP_PATH_TYPES_HPP
|
||||
|
||||
#include <llarp/aligned.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
typedef AlignedBuffer< 16 > PathID_t;
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,11 @@
|
||||
#ifndef LLARP_ROUTER_ID_HPP
|
||||
#define LLARP_ROUTER_ID_HPP
|
||||
|
||||
#include <llarp/aligned.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
typedef AlignedBuffer< 32 > RouterID;
|
||||
}
|
||||
|
||||
#endif
|
@ -1,46 +0,0 @@
|
||||
#ifndef LLARP_ROUTER_IDENT_H
|
||||
#define LLARP_ROUTER_IDENT_H
|
||||
#include <llarp/address_info.h>
|
||||
#include <llarp/crypto.h>
|
||||
#include <llarp/exit_info.h>
|
||||
#include <llarp/router_contact.h>
|
||||
#include <stdbool.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* rotuer identity private info
|
||||
*/
|
||||
struct llarp_router_ident
|
||||
{
|
||||
struct llarp_crypto *crypto;
|
||||
llarp_seckey_t signkey;
|
||||
uint64_t updated;
|
||||
uint16_t version;
|
||||
struct llarp_ai_list *addrs;
|
||||
struct llarp_xi_list *exits;
|
||||
};
|
||||
|
||||
void
|
||||
llarp_router_ident_new(struct llarp_router_ident **ri,
|
||||
struct llarp_crypto *crypto);
|
||||
|
||||
void
|
||||
llarp_router_ident_append_ai(struct llarp_router_ident *ri,
|
||||
struct llarp_ai *ai);
|
||||
|
||||
bool
|
||||
llarp_router_ident_bdecode(struct llarp_router_ident *ri, llarp_buffer_t *buf);
|
||||
bool
|
||||
llarp_router_ident_bencode(struct llarp_router_ident *ri, llarp_buffer_t *buf);
|
||||
void
|
||||
llarp_router_ident_free(struct llarp_router_ident **ri);
|
||||
bool
|
||||
llarp_router_ident_generate_rc(struct llarp_router_ident *ri,
|
||||
struct llarp_rc **rc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
@ -0,0 +1,21 @@
|
||||
#ifndef LLARP_ROUTING_ENDPOINT_HPP
|
||||
#define LLARP_ROUTING_ENDPOINT_HPP
|
||||
|
||||
#include <llarp/aligned.hpp>
|
||||
#include <llarp/buffer.h>
|
||||
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
|
||||
typedef AlignedBuffer<32> RoutingEndpoint_t;
|
||||
|
||||
/// Interface for end to end crypto between endpoints
|
||||
struct IRoutingEndpoint
|
||||
{
|
||||
virtual ~IRoutingEndpoint() {};
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -1,23 +1 @@
|
||||
#ifndef LLARP_CRYPTO_HPP
|
||||
#define LLARP_CRYPTO_HPP
|
||||
|
||||
#include <llarp/crypto.h>
|
||||
#include <llarp/aligned.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
typedef AlignedBuffer< PUBKEYSIZE > pubkey;
|
||||
|
||||
struct pubkeyhash
|
||||
{
|
||||
std::size_t
|
||||
operator()(pubkey const& a) const noexcept
|
||||
{
|
||||
size_t sz = 0;
|
||||
memcpy(&sz, a.data(), sizeof(size_t));
|
||||
return sz;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
#include <llarp/crypto.hpp>
|
@ -0,0 +1,146 @@
|
||||
#include <llarp/crypto.hpp>
|
||||
#include <llarp/encrypted_frame.hpp>
|
||||
#include "logger.hpp"
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
Encrypted::Encrypted(const byte_t* buf, size_t sz)
|
||||
{
|
||||
size = sz;
|
||||
data = new byte_t[sz];
|
||||
if(buf)
|
||||
memcpy(data, buf, sz);
|
||||
m_Buffer.base = data;
|
||||
m_Buffer.cur = data;
|
||||
m_Buffer.sz = size;
|
||||
}
|
||||
|
||||
Encrypted::Encrypted(size_t sz) : Encrypted(nullptr, sz)
|
||||
{
|
||||
}
|
||||
|
||||
Encrypted::~Encrypted()
|
||||
{
|
||||
if(data)
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
bool
|
||||
EncryptedFrame::EncryptInPlace(byte_t* ourSecretKey, byte_t* otherPubkey,
|
||||
llarp_crypto* crypto)
|
||||
{
|
||||
// format of frame is
|
||||
// <32 bytes keyed hash of following data>
|
||||
// <32 bytes nonce>
|
||||
// <32 bytes pubkey>
|
||||
// <N bytes encrypted payload>
|
||||
//
|
||||
byte_t* hash = data;
|
||||
byte_t* nonce = hash + SHORTHASHSIZE;
|
||||
byte_t* pubkey = nonce + TUNNONCESIZE;
|
||||
byte_t* body = pubkey + PUBKEYSIZE;
|
||||
|
||||
SharedSecret shared;
|
||||
|
||||
auto DH = crypto->dh_client;
|
||||
auto Encrypt = crypto->xchacha20;
|
||||
auto MDS = crypto->hmac;
|
||||
|
||||
llarp_buffer_t buf;
|
||||
buf.base = body;
|
||||
buf.cur = buf.base;
|
||||
buf.sz = size - OverheadSize;
|
||||
|
||||
// set our pubkey
|
||||
memcpy(pubkey, llarp::seckey_topublic(ourSecretKey), PUBKEYSIZE);
|
||||
// randomize nonce
|
||||
crypto->randbytes(nonce, TUNNONCESIZE);
|
||||
|
||||
// derive shared key
|
||||
if(!DH(shared, otherPubkey, nonce, ourSecretKey))
|
||||
{
|
||||
llarp::Error("DH failed");
|
||||
return false;
|
||||
}
|
||||
// encrypt body
|
||||
if(!Encrypt(buf, shared, nonce))
|
||||
{
|
||||
llarp::Error("encrypt failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
// generate message auth
|
||||
buf.base = nonce;
|
||||
buf.cur = buf.base;
|
||||
buf.sz = size - SHORTHASHSIZE;
|
||||
|
||||
if(!MDS(hash, buf, shared))
|
||||
{
|
||||
llarp::Error("Failed to generate messgae auth");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
EncryptedFrame::DecryptInPlace(byte_t* ourSecretKey, llarp_crypto* crypto)
|
||||
{
|
||||
if(size <= OverheadSize)
|
||||
{
|
||||
llarp::Warn("encrypted frame too small, ", size, " <= ", OverheadSize);
|
||||
return false;
|
||||
}
|
||||
// format of frame is
|
||||
// <32 bytes keyed hash of following data>
|
||||
// <32 bytes nonce>
|
||||
// <32 bytes pubkey>
|
||||
// <N bytes encrypted payload>
|
||||
//
|
||||
byte_t* hash = data;
|
||||
byte_t* nonce = hash + SHORTHASHSIZE;
|
||||
byte_t* otherPubkey = nonce + TUNNONCESIZE;
|
||||
byte_t* body = otherPubkey + PUBKEYSIZE;
|
||||
|
||||
// use dh_server becuase we are not the creator of this message
|
||||
auto DH = crypto->dh_server;
|
||||
auto Decrypt = crypto->xchacha20;
|
||||
auto MDS = crypto->hmac;
|
||||
|
||||
llarp_buffer_t buf;
|
||||
buf.base = nonce;
|
||||
buf.cur = buf.base;
|
||||
buf.sz = size - SHORTHASHSIZE;
|
||||
|
||||
SharedSecret shared;
|
||||
ShortHash digest;
|
||||
|
||||
if(!DH(shared, otherPubkey, nonce, ourSecretKey))
|
||||
{
|
||||
llarp::Error("DH failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!MDS(digest, buf, shared))
|
||||
{
|
||||
llarp::Error("Digest failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(memcmp(digest, hash, digest.size()))
|
||||
{
|
||||
llarp::Error("message authentication failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
buf.base = body;
|
||||
buf.cur = body;
|
||||
buf.sz = size - OverheadSize;
|
||||
|
||||
if(!Decrypt(buf, shared, nonce))
|
||||
{
|
||||
llarp::Error("decrypt failed");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
@ -1,8 +1,21 @@
|
||||
#ifndef LLARP_FS_HPP
|
||||
#define LLARP_FS_HPP
|
||||
|
||||
#if(__cplusplus >= 201703L)
|
||||
#include <experimental/filesystem>
|
||||
|
||||
namespace fs = std::experimental::filesystem;
|
||||
#else
|
||||
|
||||
#error "fs support unimplemented"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace fs
|
||||
{
|
||||
static std::string Sep = "/";
|
||||
struct path
|
||||
{
|
||||
};
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
@ -0,0 +1,229 @@
|
||||
#include <deque>
|
||||
#include <llarp/encrypted_frame.hpp>
|
||||
#include <llarp/path.hpp>
|
||||
#include "router.hpp"
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
PathContext::PathContext(llarp_router* router)
|
||||
: m_Router(router), m_AllowTransit(false)
|
||||
{
|
||||
}
|
||||
|
||||
PathContext::~PathContext()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
PathContext::AllowTransit()
|
||||
{
|
||||
m_AllowTransit = true;
|
||||
}
|
||||
|
||||
struct LRCMFrameDecrypt
|
||||
{
|
||||
typedef AsyncFrameDecrypter< LRCMFrameDecrypt > Decrypter;
|
||||
Decrypter* decrypter;
|
||||
std::deque< EncryptedFrame > frames;
|
||||
std::deque< EncryptedAck > acks;
|
||||
EncryptedFrame lastFrame;
|
||||
PathContext* context;
|
||||
RouterID from;
|
||||
LR_CommitRecord record;
|
||||
|
||||
LRCMFrameDecrypt(PathContext* ctx, Decrypter* dec,
|
||||
const LR_CommitMessage* commit)
|
||||
: decrypter(dec)
|
||||
, lastFrame(commit->lasthopFrame)
|
||||
, context(ctx)
|
||||
, from(commit->remote)
|
||||
{
|
||||
for(const auto& f : commit->frames)
|
||||
frames.push_front(f);
|
||||
for(const auto& a : commit->acks)
|
||||
acks.push_front(a);
|
||||
}
|
||||
|
||||
~LRCMFrameDecrypt()
|
||||
{
|
||||
delete decrypter;
|
||||
}
|
||||
|
||||
static void
|
||||
HandleDecrypted(llarp_buffer_t* buf, LRCMFrameDecrypt* self)
|
||||
{
|
||||
if(!buf)
|
||||
{
|
||||
llarp::Error("LRCM decrypt failed from ", self->from);
|
||||
delete self;
|
||||
return;
|
||||
}
|
||||
llarp::Debug("decrypted LRCM from ", self->from);
|
||||
// successful decrypt
|
||||
if(!self->record.BDecode(buf))
|
||||
{
|
||||
llarp::Error("malformed frame inside LRCM from ", self->from);
|
||||
delete self;
|
||||
return;
|
||||
}
|
||||
TransitHopInfo info(self->from, self->record);
|
||||
if(self->context->HasTransitHop(info))
|
||||
{
|
||||
llarp::Error("duplicate transit hop ", info);
|
||||
delete self;
|
||||
return;
|
||||
}
|
||||
TransitHop hop;
|
||||
// choose rx id
|
||||
// TODO: check for duplicates
|
||||
info.rxID.Randomize();
|
||||
|
||||
// generate tx key as we are in a worker thread
|
||||
auto DH = self->context->Crypto()->dh_server;
|
||||
if(!DH(hop.txKey, self->record.commkey,
|
||||
self->context->EncryptionSecretKey(), self->record.tunnelNonce))
|
||||
{
|
||||
llarp::Error("LRCM DH Failed ", info);
|
||||
delete self;
|
||||
return;
|
||||
}
|
||||
if(self->context->HopIsUs(self->record.nextHop))
|
||||
{
|
||||
// we are the farthest hop
|
||||
llarp::Info("We are the farthest hop for ", info);
|
||||
}
|
||||
else
|
||||
{
|
||||
llarp::Info("Accepted ", info);
|
||||
self->context->PutPendingRelayCommit(info.upstream, info.txID, info,
|
||||
hop);
|
||||
size_t sz = self->frames.front().size;
|
||||
// we pop the front element it was ours
|
||||
self->frames.pop_front();
|
||||
// put random on the end
|
||||
// TODO: should this be an encrypted frame?
|
||||
self->frames.emplace_back(sz);
|
||||
self->frames.back().Randomize();
|
||||
// forward upstream
|
||||
self->context->ForwardLRCM(info.upstream, self->frames, self->acks,
|
||||
self->lastFrame);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
bool
|
||||
PathContext::HandleRelayCommit(const LR_CommitMessage* commit)
|
||||
{
|
||||
if(!m_AllowTransit)
|
||||
{
|
||||
llarp::Error("got LRCM from ", commit->remote,
|
||||
" when not allowing transit traffic");
|
||||
return false;
|
||||
}
|
||||
if(commit->frames.size() <= 1)
|
||||
{
|
||||
llarp::Error("got LRCM with too few frames from ", commit->remote);
|
||||
return false;
|
||||
}
|
||||
LRCMFrameDecrypt::Decrypter* decrypter =
|
||||
new LRCMFrameDecrypt::Decrypter(&m_Router->crypto, m_Router->encryption,
|
||||
&LRCMFrameDecrypt::HandleDecrypted);
|
||||
// copy frames so we own them
|
||||
LRCMFrameDecrypt* frames = new LRCMFrameDecrypt(this, decrypter, commit);
|
||||
|
||||
// decrypt frames async
|
||||
decrypter->AsyncDecrypt(m_Router->tp, &frames->frames.front(), frames);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
llarp_threadpool*
|
||||
PathContext::Worker()
|
||||
{
|
||||
return m_Router->tp;
|
||||
}
|
||||
|
||||
llarp_crypto*
|
||||
PathContext::Crypto()
|
||||
{
|
||||
return &m_Router->crypto;
|
||||
}
|
||||
|
||||
byte_t*
|
||||
PathContext::EncryptionSecretKey()
|
||||
{
|
||||
return m_Router->encryption;
|
||||
}
|
||||
|
||||
bool
|
||||
PathContext::HopIsUs(const PubKey& k) const
|
||||
{
|
||||
return memcmp(k, m_Router->pubkey(), PUBKEYSIZE) == 0;
|
||||
}
|
||||
|
||||
bool
|
||||
PathContext::ForwardLRCM(const RouterID& nextHop,
|
||||
std::deque< EncryptedFrame >& frames,
|
||||
std::deque< EncryptedAck >& acks,
|
||||
EncryptedFrame& lastHop)
|
||||
{
|
||||
LR_CommitMessage* msg = new LR_CommitMessage;
|
||||
while(frames.size())
|
||||
{
|
||||
msg->frames.push_back(frames.front());
|
||||
frames.pop_front();
|
||||
}
|
||||
while(acks.size())
|
||||
{
|
||||
msg->acks.push_back(acks.front());
|
||||
acks.pop_front();
|
||||
}
|
||||
msg->lasthopFrame = lastHop;
|
||||
return m_Router->SendToOrQueue(nextHop, {msg});
|
||||
}
|
||||
|
||||
template < typename Map_t, typename Value_t >
|
||||
bool
|
||||
MapHas(Map_t& map, const Value_t& val)
|
||||
{
|
||||
std::unique_lock< std::mutex > lock(map.first);
|
||||
return map.second.find(val) != map.second.end();
|
||||
}
|
||||
|
||||
template < typename Map_t, typename Key_t, typename Value_t >
|
||||
void
|
||||
MapPut(Map_t& map, const Key_t& k, const Value_t& v)
|
||||
{
|
||||
std::unique_lock< std::mutex > lock(map.first);
|
||||
map.second[k] = v;
|
||||
}
|
||||
|
||||
bool
|
||||
PathContext::HasTransitHop(const TransitHopInfo& info)
|
||||
{
|
||||
return MapHas(m_TransitPaths, info);
|
||||
}
|
||||
|
||||
void
|
||||
PathContext::PutPendingRelayCommit(const RouterID& upstream,
|
||||
const PathID_t& txid,
|
||||
const TransitHopInfo& info,
|
||||
const TransitHop& hop)
|
||||
{
|
||||
MapPut(m_WaitingForAcks, PendingPathKey(upstream, txid),
|
||||
std::make_pair(info, hop));
|
||||
}
|
||||
|
||||
bool
|
||||
PathContext::HasPendingRelayCommit(const RouterID& upstream,
|
||||
const PathID_t& txid)
|
||||
{
|
||||
return MapHas(m_WaitingForAcks, PendingPathKey(upstream, txid));
|
||||
}
|
||||
|
||||
TransitHopInfo::TransitHopInfo(const RouterID& down,
|
||||
const LR_CommitRecord& record)
|
||||
: txID(record.txid), upstream(record.nextHop), downstream(down)
|
||||
{
|
||||
}
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
#include <llarp/messages/relay_ack.hpp>
|
||||
|
||||
#include "router.hpp"
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
bool
|
||||
LR_AckRecord::BEncode(llarp_buffer_t* buf) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
LR_AckRecord::BDecode(llarp_buffer_t* buf)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
LR_AckMessage::LR_AckMessage(const RouterID& from) : ILinkMessage(from)
|
||||
{
|
||||
}
|
||||
LR_AckMessage::~LR_AckMessage()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
LR_AckMessage::BEncode(llarp_buffer_t* buf) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
LR_AckMessage::DecodeKey(llarp_buffer_t key, llarp_buffer_t* buf)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
struct LRAM_Decrypt
|
||||
{
|
||||
typedef AsyncFrameDecrypter< LRAM_Decrypt > Decrypter;
|
||||
|
||||
llarp_router* router;
|
||||
Decrypter* decrypt;
|
||||
std::vector< EncryptedFrame > frames;
|
||||
LR_AckRecord record;
|
||||
|
||||
LRAM_Decrypt(llarp_router* r, byte_t* seckey,
|
||||
const std::vector< EncryptedFrame >& f)
|
||||
: router(r), frames(f)
|
||||
{
|
||||
decrypt = new Decrypter(&r->crypto, seckey, &Decrypted);
|
||||
}
|
||||
|
||||
~LRAM_Decrypt()
|
||||
{
|
||||
delete decrypt;
|
||||
}
|
||||
|
||||
static void
|
||||
Decrypted(llarp_buffer_t* buf, LRAM_Decrypt* self)
|
||||
{
|
||||
if(!buf)
|
||||
{
|
||||
llarp::Error("Failed to decrypt LRAM frame");
|
||||
delete self;
|
||||
return;
|
||||
}
|
||||
if(!self->record.BDecode(buf))
|
||||
{
|
||||
llarp::Error("LRAR invalid format");
|
||||
delete self;
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
bool
|
||||
LR_AckMessage::HandleMessage(llarp_router* router) const
|
||||
{
|
||||
if(!router->paths.HasPendingRelayCommit(remote, txPathID))
|
||||
{
|
||||
llarp::Warn("got LRAM from ", remote,
|
||||
" with no previous LRCM txid=", txPathID);
|
||||
return false;
|
||||
}
|
||||
// TODO: use different private key for different path contexts as client
|
||||
LRAM_Decrypt* lram = new LRAM_Decrypt(router, router->encryption, acks);
|
||||
lram->decrypt->AsyncDecrypt(router->tp, &lram->frames[0], lram);
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
#include <llarp/messages/relay.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
RelayUpstreamMessage::RelayUpstreamMessage(const RouterID &from)
|
||||
: ILinkMessage(from)
|
||||
{
|
||||
}
|
||||
|
||||
RelayUpstreamMessage::~RelayUpstreamMessage()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
RelayUpstreamMessage::BEncode(llarp_buffer_t *buf) const
|
||||
{
|
||||
// TODO: implement me
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
RelayUpstreamMessage::DecodeKey(llarp_buffer_t key, llarp_buffer_t *buf)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
RelayUpstreamMessage::HandleMessage(llarp_router *router) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
RelayDownstreamMessage::RelayDownstreamMessage(const RouterID &from)
|
||||
: ILinkMessage(from)
|
||||
{
|
||||
}
|
||||
|
||||
RelayDownstreamMessage::~RelayDownstreamMessage()
|
||||
{
|
||||
}
|
||||
bool
|
||||
RelayDownstreamMessage::BEncode(llarp_buffer_t *buf) const
|
||||
{
|
||||
// TODO: implement me
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
RelayDownstreamMessage::DecodeKey(llarp_buffer_t key, llarp_buffer_t *buf)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
RelayDownstreamMessage::HandleMessage(llarp_router *router) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue