mirror of https://github.com/oxen-io/lokinet
Merge pull request #223 from michael-loki/structure_so_far
Produce hierarchy of 'libraries' inside libllarppull/225/head
commit
ee8c35188f
Binary file not shown.
After Width: | Height: | Size: 414 KiB |
@ -0,0 +1,102 @@
|
||||
digraph {
|
||||
constants -> util;
|
||||
|
||||
crypto -> constants;
|
||||
crypto -> llarp;
|
||||
crypto -> util;
|
||||
|
||||
dht -> crypto;
|
||||
dht -> messages;
|
||||
dht -> llarp;
|
||||
dht -> path;
|
||||
dht -> routing;
|
||||
dht -> service;
|
||||
dht -> util;
|
||||
|
||||
dns -> crypto;
|
||||
dns -> ev;
|
||||
dns -> handlers;
|
||||
dns -> llarp;
|
||||
dns -> net;
|
||||
dns -> service;
|
||||
dns -> util;
|
||||
|
||||
ev -> net;
|
||||
ev -> util;
|
||||
|
||||
exit -> crypto;
|
||||
exit -> handlers;
|
||||
exit -> messages;
|
||||
exit -> net;
|
||||
exit -> path;
|
||||
exit -> routing;
|
||||
exit -> util;
|
||||
|
||||
handlers -> dns;
|
||||
handlers -> ev;
|
||||
handlers -> exit;
|
||||
handlers -> net;
|
||||
handlers -> service;
|
||||
handlers -> util;
|
||||
|
||||
link -> constants;
|
||||
link -> crypto;
|
||||
link -> ev;
|
||||
link -> messages;
|
||||
link -> net;
|
||||
link -> util;
|
||||
|
||||
messages -> crypto;
|
||||
messages -> dht;
|
||||
messages -> exit;
|
||||
messages -> link;
|
||||
messages -> llarp;
|
||||
messages -> path;
|
||||
messages -> routing;
|
||||
messages -> service;
|
||||
messages -> util;
|
||||
|
||||
net -> crypto;
|
||||
net -> util;
|
||||
|
||||
path -> crypto;
|
||||
path -> dht;
|
||||
path -> llarp;
|
||||
path -> messages;
|
||||
path -> routing;
|
||||
path -> service;
|
||||
path -> util;
|
||||
|
||||
routing -> llarp;
|
||||
routing -> messages;
|
||||
routing -> path;
|
||||
routing -> util;
|
||||
|
||||
service -> crypto;
|
||||
service -> dht;
|
||||
service -> ev;
|
||||
service -> exit;
|
||||
service -> handlers;
|
||||
service -> messages;
|
||||
service -> net;
|
||||
service -> path;
|
||||
service -> routing;
|
||||
service -> util;
|
||||
|
||||
util -> constants;
|
||||
|
||||
llarp -> constants;
|
||||
llarp -> crypto;
|
||||
llarp -> dht;
|
||||
llarp -> dns;
|
||||
llarp -> ev;
|
||||
llarp -> exit;
|
||||
llarp -> handlers;
|
||||
llarp -> link;
|
||||
llarp -> messages;
|
||||
llarp -> net;
|
||||
llarp -> path;
|
||||
llarp -> routing;
|
||||
llarp -> service;
|
||||
llarp -> util;
|
||||
}
|
@ -1 +0,0 @@
|
||||
#include <codel.hpp>
|
@ -0,0 +1 @@
|
||||
#include <constants/link_layer.hpp>
|
@ -0,0 +1 @@
|
||||
#include <crypto/encrypted.hpp>
|
@ -1,7 +1,7 @@
|
||||
#ifndef LLARP_ENCCRYPTED_HPP
|
||||
#define LLARP_ENCCRYPTED_HPP
|
||||
#ifndef LLARP_ENCRYPTED_HPP
|
||||
#define LLARP_ENCRYPTED_HPP
|
||||
|
||||
#include <link_layer.hpp>
|
||||
#include <constants/link_layer.hpp>
|
||||
#include <util/aligned.hpp>
|
||||
#include <util/bencode.h>
|
||||
#include <util/buffer.h>
|
@ -1,4 +1,4 @@
|
||||
#include <encrypted_frame.hpp>
|
||||
#include <crypto/encrypted_frame.hpp>
|
||||
|
||||
#include <crypto/crypto.hpp>
|
||||
#include <util/logger.hpp>
|
@ -1,8 +1,8 @@
|
||||
#ifndef LLARP_ENCRYPTED_FRAME_HPP
|
||||
#define LLARP_ENCRYPTED_FRAME_HPP
|
||||
|
||||
#include <crypto/encrypted.hpp>
|
||||
#include <crypto/types.hpp>
|
||||
#include <encrypted.hpp>
|
||||
#include <util/buffer.hpp>
|
||||
#include <util/mem.h>
|
||||
#include <util/threadpool.h>
|
@ -1,6 +1,6 @@
|
||||
#include <dht.h>
|
||||
#include <dht/context.hpp>
|
||||
#include "router_contact.hpp"
|
||||
#include <dht/dht.h>
|
||||
#include <router_contact.hpp>
|
||||
|
||||
llarp_dht_context::llarp_dht_context(llarp::Router *router)
|
||||
{
|
@ -1 +0,0 @@
|
||||
#include <encrypted.hpp>
|
@ -1 +0,0 @@
|
||||
#include <encrypted_ack.hpp>
|
@ -1,12 +0,0 @@
|
||||
#ifndef LLARP_ENCRYPTED_ACK_HPP
|
||||
#define LLARP_ENCRYPTED_ACK_HPP
|
||||
|
||||
#include <encrypted.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
struct Crypto;
|
||||
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
@ -1 +0,0 @@
|
||||
#include <establish_job.hpp>
|
@ -1,35 +0,0 @@
|
||||
#ifndef LLARP_ESTABLISH_JOB_HPP
|
||||
#define LLARP_ESTABLISH_JOB_HPP
|
||||
|
||||
#include <router_contact.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
struct OutboundLinkEstablishJob
|
||||
{
|
||||
RouterContact rc;
|
||||
|
||||
OutboundLinkEstablishJob(const RouterContact& remote) : rc(remote)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~OutboundLinkEstablishJob(){};
|
||||
|
||||
virtual void
|
||||
Success() = 0;
|
||||
|
||||
virtual void
|
||||
Failed() = 0;
|
||||
|
||||
virtual void
|
||||
AttemptTimedout() = 0;
|
||||
|
||||
virtual void
|
||||
Attempt() = 0;
|
||||
|
||||
virtual bool
|
||||
ShouldRetry() const = 0;
|
||||
};
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
@ -1,175 +0,0 @@
|
||||
#include <messages/link_intro.hpp>
|
||||
|
||||
#include <router_contact.hpp>
|
||||
#include <router.hpp>
|
||||
#include <util/bencode.h>
|
||||
#include <util/logger.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
LinkIntroMessage::~LinkIntroMessage()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
LinkIntroMessage::DecodeKey(llarp_buffer_t key, llarp_buffer_t* buf)
|
||||
{
|
||||
if(llarp_buffer_eq(key, "a"))
|
||||
{
|
||||
llarp_buffer_t strbuf;
|
||||
if(!bencode_read_string(buf, &strbuf))
|
||||
return false;
|
||||
if(strbuf.sz != 1)
|
||||
return false;
|
||||
return *strbuf.cur == 'i';
|
||||
}
|
||||
if(llarp_buffer_eq(key, "n"))
|
||||
{
|
||||
if(N.BDecode(buf))
|
||||
return true;
|
||||
llarp::LogWarn("failed to decode nonce in LIM");
|
||||
return false;
|
||||
}
|
||||
if(llarp_buffer_eq(key, "p"))
|
||||
{
|
||||
return bencode_read_integer(buf, &P);
|
||||
}
|
||||
if(llarp_buffer_eq(key, "r"))
|
||||
{
|
||||
if(rc.BDecode(buf))
|
||||
return true;
|
||||
llarp::LogWarn("failed to decode RC in LIM");
|
||||
llarp::DumpBuffer(*buf);
|
||||
return false;
|
||||
}
|
||||
else if(llarp_buffer_eq(key, "v"))
|
||||
{
|
||||
if(!bencode_read_integer(buf, &version))
|
||||
return false;
|
||||
if(version != LLARP_PROTO_VERSION)
|
||||
{
|
||||
llarp::LogWarn("llarp protocol version missmatch ", version,
|
||||
" != ", LLARP_PROTO_VERSION);
|
||||
return false;
|
||||
}
|
||||
llarp::LogDebug("LIM version ", version);
|
||||
return true;
|
||||
}
|
||||
else if(llarp_buffer_eq(key, "z"))
|
||||
{
|
||||
return Z.BDecode(buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
llarp::LogWarn("invalid LIM key: ", *key.cur);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
LinkIntroMessage::BEncode(llarp_buffer_t* buf) const
|
||||
{
|
||||
if(!bencode_start_dict(buf))
|
||||
return false;
|
||||
|
||||
if(!bencode_write_bytestring(buf, "a", 1))
|
||||
return false;
|
||||
if(!bencode_write_bytestring(buf, "i", 1))
|
||||
return false;
|
||||
|
||||
if(!bencode_write_bytestring(buf, "n", 1))
|
||||
return false;
|
||||
if(!N.BEncode(buf))
|
||||
return false;
|
||||
|
||||
if(!bencode_write_bytestring(buf, "p", 1))
|
||||
return false;
|
||||
if(!bencode_write_uint64(buf, P))
|
||||
return false;
|
||||
|
||||
if(!bencode_write_bytestring(buf, "r", 1))
|
||||
return false;
|
||||
if(!rc.BEncode(buf))
|
||||
return false;
|
||||
|
||||
if(!bencode_write_version_entry(buf))
|
||||
return false;
|
||||
|
||||
if(!bencode_write_bytestring(buf, "z", 1))
|
||||
return false;
|
||||
if(!Z.BEncode(buf))
|
||||
return false;
|
||||
|
||||
return bencode_end(buf);
|
||||
}
|
||||
|
||||
LinkIntroMessage&
|
||||
LinkIntroMessage::operator=(const LinkIntroMessage& msg)
|
||||
{
|
||||
version = msg.version;
|
||||
Z = msg.Z;
|
||||
rc = msg.rc;
|
||||
N = msg.N;
|
||||
P = msg.P;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool
|
||||
LinkIntroMessage::HandleMessage(llarp::Router* router) const
|
||||
{
|
||||
if(!Verify(&router->crypto))
|
||||
return false;
|
||||
return session->GotLIM(this);
|
||||
}
|
||||
|
||||
void
|
||||
LinkIntroMessage::Clear()
|
||||
{
|
||||
P = 0;
|
||||
N.Zero();
|
||||
rc.Clear();
|
||||
Z.Zero();
|
||||
}
|
||||
|
||||
bool
|
||||
LinkIntroMessage::Sign(
|
||||
std::function< bool(Signature&, llarp_buffer_t) > signer)
|
||||
{
|
||||
Z.Zero();
|
||||
byte_t tmp[MaxSize] = {0};
|
||||
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
|
||||
if(!BEncode(&buf))
|
||||
return false;
|
||||
buf.sz = buf.cur - buf.base;
|
||||
buf.cur = buf.base;
|
||||
return signer(Z, buf);
|
||||
}
|
||||
|
||||
bool
|
||||
LinkIntroMessage::Verify(llarp::Crypto* c) const
|
||||
{
|
||||
LinkIntroMessage copy;
|
||||
copy = *this;
|
||||
copy.Z.Zero();
|
||||
byte_t tmp[MaxSize] = {0};
|
||||
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
|
||||
if(!copy.BEncode(&buf))
|
||||
return false;
|
||||
buf.sz = buf.cur - buf.base;
|
||||
buf.cur = buf.base;
|
||||
// outer signature
|
||||
if(!c->verify(rc.pubkey, buf, Z))
|
||||
{
|
||||
llarp::LogError("outer signature failure");
|
||||
return false;
|
||||
}
|
||||
// verify RC
|
||||
if(!rc.Verify(c, llarp::time_now_ms()))
|
||||
{
|
||||
llarp::LogError("invalid RC in link intro");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace llarp
|
@ -1 +0,0 @@
|
||||
#include <link_layer.hpp>
|
@ -1 +1,175 @@
|
||||
#include <messages/link_intro.hpp>
|
||||
|
||||
#include <router_contact.hpp>
|
||||
#include <router/router.hpp>
|
||||
#include <util/bencode.h>
|
||||
#include <util/logger.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
LinkIntroMessage::~LinkIntroMessage()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
LinkIntroMessage::DecodeKey(llarp_buffer_t key, llarp_buffer_t* buf)
|
||||
{
|
||||
if(llarp_buffer_eq(key, "a"))
|
||||
{
|
||||
llarp_buffer_t strbuf;
|
||||
if(!bencode_read_string(buf, &strbuf))
|
||||
return false;
|
||||
if(strbuf.sz != 1)
|
||||
return false;
|
||||
return *strbuf.cur == 'i';
|
||||
}
|
||||
if(llarp_buffer_eq(key, "n"))
|
||||
{
|
||||
if(N.BDecode(buf))
|
||||
return true;
|
||||
llarp::LogWarn("failed to decode nonce in LIM");
|
||||
return false;
|
||||
}
|
||||
if(llarp_buffer_eq(key, "p"))
|
||||
{
|
||||
return bencode_read_integer(buf, &P);
|
||||
}
|
||||
if(llarp_buffer_eq(key, "r"))
|
||||
{
|
||||
if(rc.BDecode(buf))
|
||||
return true;
|
||||
llarp::LogWarn("failed to decode RC in LIM");
|
||||
llarp::DumpBuffer(*buf);
|
||||
return false;
|
||||
}
|
||||
else if(llarp_buffer_eq(key, "v"))
|
||||
{
|
||||
if(!bencode_read_integer(buf, &version))
|
||||
return false;
|
||||
if(version != LLARP_PROTO_VERSION)
|
||||
{
|
||||
llarp::LogWarn("llarp protocol version missmatch ", version,
|
||||
" != ", LLARP_PROTO_VERSION);
|
||||
return false;
|
||||
}
|
||||
llarp::LogDebug("LIM version ", version);
|
||||
return true;
|
||||
}
|
||||
else if(llarp_buffer_eq(key, "z"))
|
||||
{
|
||||
return Z.BDecode(buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
llarp::LogWarn("invalid LIM key: ", *key.cur);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
LinkIntroMessage::BEncode(llarp_buffer_t* buf) const
|
||||
{
|
||||
if(!bencode_start_dict(buf))
|
||||
return false;
|
||||
|
||||
if(!bencode_write_bytestring(buf, "a", 1))
|
||||
return false;
|
||||
if(!bencode_write_bytestring(buf, "i", 1))
|
||||
return false;
|
||||
|
||||
if(!bencode_write_bytestring(buf, "n", 1))
|
||||
return false;
|
||||
if(!N.BEncode(buf))
|
||||
return false;
|
||||
|
||||
if(!bencode_write_bytestring(buf, "p", 1))
|
||||
return false;
|
||||
if(!bencode_write_uint64(buf, P))
|
||||
return false;
|
||||
|
||||
if(!bencode_write_bytestring(buf, "r", 1))
|
||||
return false;
|
||||
if(!rc.BEncode(buf))
|
||||
return false;
|
||||
|
||||
if(!bencode_write_version_entry(buf))
|
||||
return false;
|
||||
|
||||
if(!bencode_write_bytestring(buf, "z", 1))
|
||||
return false;
|
||||
if(!Z.BEncode(buf))
|
||||
return false;
|
||||
|
||||
return bencode_end(buf);
|
||||
}
|
||||
|
||||
LinkIntroMessage&
|
||||
LinkIntroMessage::operator=(const LinkIntroMessage& msg)
|
||||
{
|
||||
version = msg.version;
|
||||
Z = msg.Z;
|
||||
rc = msg.rc;
|
||||
N = msg.N;
|
||||
P = msg.P;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool
|
||||
LinkIntroMessage::HandleMessage(llarp::Router* router) const
|
||||
{
|
||||
if(!Verify(&router->crypto))
|
||||
return false;
|
||||
return session->GotLIM(this);
|
||||
}
|
||||
|
||||
void
|
||||
LinkIntroMessage::Clear()
|
||||
{
|
||||
P = 0;
|
||||
N.Zero();
|
||||
rc.Clear();
|
||||
Z.Zero();
|
||||
}
|
||||
|
||||
bool
|
||||
LinkIntroMessage::Sign(
|
||||
std::function< bool(Signature&, llarp_buffer_t) > signer)
|
||||
{
|
||||
Z.Zero();
|
||||
byte_t tmp[MaxSize] = {0};
|
||||
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
|
||||
if(!BEncode(&buf))
|
||||
return false;
|
||||
buf.sz = buf.cur - buf.base;
|
||||
buf.cur = buf.base;
|
||||
return signer(Z, buf);
|
||||
}
|
||||
|
||||
bool
|
||||
LinkIntroMessage::Verify(llarp::Crypto* c) const
|
||||
{
|
||||
LinkIntroMessage copy;
|
||||
copy = *this;
|
||||
copy.Z.Zero();
|
||||
byte_t tmp[MaxSize] = {0};
|
||||
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
|
||||
if(!copy.BEncode(&buf))
|
||||
return false;
|
||||
buf.sz = buf.cur - buf.base;
|
||||
buf.cur = buf.base;
|
||||
// outer signature
|
||||
if(!c->verify(rc.pubkey, buf, Z))
|
||||
{
|
||||
llarp::LogError("outer signature failure");
|
||||
return false;
|
||||
}
|
||||
// verify RC
|
||||
if(!rc.Verify(c, llarp::time_now_ms()))
|
||||
{
|
||||
llarp::LogError("invalid RC in link intro");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace llarp
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include <link_message_parser.hpp>
|
||||
#include <messages/link_message_parser.hpp>
|
||||
|
||||
#include <router_contact.hpp>
|
||||
#include <util/buffer.hpp>
|
@ -1,10 +1,10 @@
|
||||
#ifndef LLARP_LINK_MESSAGE_PARSER_HPP
|
||||
#define LLARP_LINK_MESSAGE_PARSER_HPP
|
||||
|
||||
#include <link_message.hpp>
|
||||
#include <messages/discard.hpp>
|
||||
#include <messages/dht_immediate.hpp>
|
||||
#include <messages/link_intro.hpp>
|
||||
#include <messages/link_message.hpp>
|
||||
#include <messages/relay.hpp>
|
||||
#include <messages/relay_commit.hpp>
|
||||
|
@ -1 +1,132 @@
|
||||
#include <messages/relay.hpp>
|
||||
|
||||
#include <router/router.hpp>
|
||||
#include <util/bencode.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
RelayUpstreamMessage::RelayUpstreamMessage() : ILinkMessage()
|
||||
{
|
||||
}
|
||||
|
||||
RelayUpstreamMessage::~RelayUpstreamMessage()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
RelayUpstreamMessage::Clear()
|
||||
{
|
||||
pathid.Zero();
|
||||
X.Clear();
|
||||
Y.Zero();
|
||||
}
|
||||
|
||||
bool
|
||||
RelayUpstreamMessage::BEncode(llarp_buffer_t *buf) const
|
||||
{
|
||||
if(!bencode_start_dict(buf))
|
||||
return false;
|
||||
if(!BEncodeWriteDictMsgType(buf, "a", "u"))
|
||||
return false;
|
||||
|
||||
if(!BEncodeWriteDictEntry("p", pathid, buf))
|
||||
return false;
|
||||
if(!BEncodeWriteDictInt("v", LLARP_PROTO_VERSION, buf))
|
||||
return false;
|
||||
if(!BEncodeWriteDictEntry("x", X, buf))
|
||||
return false;
|
||||
if(!BEncodeWriteDictEntry("y", Y, buf))
|
||||
return false;
|
||||
return bencode_end(buf);
|
||||
}
|
||||
|
||||
bool
|
||||
RelayUpstreamMessage::DecodeKey(llarp_buffer_t key, llarp_buffer_t *buf)
|
||||
{
|
||||
bool read = false;
|
||||
if(!BEncodeMaybeReadDictEntry("p", pathid, read, key, buf))
|
||||
return false;
|
||||
if(!BEncodeMaybeReadVersion("v", version, LLARP_PROTO_VERSION, read, key,
|
||||
buf))
|
||||
return false;
|
||||
if(!BEncodeMaybeReadDictEntry("x", X, read, key, buf))
|
||||
return false;
|
||||
if(!BEncodeMaybeReadDictEntry("y", Y, read, key, buf))
|
||||
return false;
|
||||
return read;
|
||||
}
|
||||
|
||||
bool
|
||||
RelayUpstreamMessage::HandleMessage(llarp::Router *r) const
|
||||
{
|
||||
auto path = r->paths.GetByDownstream(session->GetPubKey(), pathid);
|
||||
if(path)
|
||||
{
|
||||
return path->HandleUpstream(X.Buffer(), Y, r);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
RelayDownstreamMessage::RelayDownstreamMessage() : ILinkMessage()
|
||||
{
|
||||
}
|
||||
|
||||
RelayDownstreamMessage::~RelayDownstreamMessage()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
RelayDownstreamMessage::Clear()
|
||||
{
|
||||
pathid.Zero();
|
||||
X.Clear();
|
||||
Y.Zero();
|
||||
}
|
||||
|
||||
bool
|
||||
RelayDownstreamMessage::BEncode(llarp_buffer_t *buf) const
|
||||
{
|
||||
if(!bencode_start_dict(buf))
|
||||
return false;
|
||||
if(!BEncodeWriteDictMsgType(buf, "a", "d"))
|
||||
return false;
|
||||
|
||||
if(!BEncodeWriteDictEntry("p", pathid, buf))
|
||||
return false;
|
||||
if(!BEncodeWriteDictInt("v", LLARP_PROTO_VERSION, buf))
|
||||
return false;
|
||||
if(!BEncodeWriteDictEntry("x", X, buf))
|
||||
return false;
|
||||
if(!BEncodeWriteDictEntry("y", Y, buf))
|
||||
return false;
|
||||
return bencode_end(buf);
|
||||
}
|
||||
|
||||
bool
|
||||
RelayDownstreamMessage::DecodeKey(llarp_buffer_t key, llarp_buffer_t *buf)
|
||||
{
|
||||
bool read = false;
|
||||
if(!BEncodeMaybeReadDictEntry("p", pathid, read, key, buf))
|
||||
return false;
|
||||
if(!BEncodeMaybeReadVersion("v", version, LLARP_PROTO_VERSION, read, key,
|
||||
buf))
|
||||
return false;
|
||||
if(!BEncodeMaybeReadDictEntry("x", X, read, key, buf))
|
||||
return false;
|
||||
if(!BEncodeMaybeReadDictEntry("y", Y, read, key, buf))
|
||||
return false;
|
||||
return read;
|
||||
}
|
||||
|
||||
bool
|
||||
RelayDownstreamMessage::HandleMessage(llarp::Router *r) const
|
||||
{
|
||||
auto path = r->paths.GetByUpstream(session->GetPubKey(), pathid);
|
||||
if(path)
|
||||
{
|
||||
return path->HandleDownstream(X.Buffer(), Y, r);
|
||||
}
|
||||
llarp::LogWarn("unhandled downstream message");
|
||||
return false;
|
||||
}
|
||||
} // namespace llarp
|
||||
|
@ -1 +1,345 @@
|
||||
#include <messages/relay_commit.hpp>
|
||||
|
||||
#include <messages/path_confirm.hpp>
|
||||
#include <path/path.hpp>
|
||||
#include <router/router.hpp>
|
||||
#include <util/bencode.hpp>
|
||||
#include <util/buffer.hpp>
|
||||
#include <util/logger.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
LR_CommitMessage::~LR_CommitMessage()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
LR_CommitMessage::DecodeKey(llarp_buffer_t key, llarp_buffer_t* buf)
|
||||
{
|
||||
if(llarp_buffer_eq(key, "c"))
|
||||
{
|
||||
return BEncodeReadArray(frames, buf);
|
||||
}
|
||||
bool read = false;
|
||||
if(!BEncodeMaybeReadVersion("v", version, LLARP_PROTO_VERSION, read, key,
|
||||
buf))
|
||||
return false;
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
void
|
||||
LR_CommitMessage::Clear()
|
||||
{
|
||||
frames[0].Clear();
|
||||
frames[1].Clear();
|
||||
frames[2].Clear();
|
||||
frames[3].Clear();
|
||||
frames[4].Clear();
|
||||
frames[5].Clear();
|
||||
frames[6].Clear();
|
||||
frames[7].Clear();
|
||||
}
|
||||
|
||||
bool
|
||||
LR_CommitMessage::BEncode(llarp_buffer_t* buf) const
|
||||
{
|
||||
if(!bencode_start_dict(buf))
|
||||
return false;
|
||||
// msg type
|
||||
if(!BEncodeWriteDictMsgType(buf, "a", "c"))
|
||||
return false;
|
||||
// frames
|
||||
if(!BEncodeWriteDictArray("c", frames, buf))
|
||||
return false;
|
||||
// version
|
||||
if(!bencode_write_version_entry(buf))
|
||||
return false;
|
||||
|
||||
return bencode_end(buf);
|
||||
}
|
||||
|
||||
bool
|
||||
LR_CommitMessage::HandleMessage(llarp::Router* router) const
|
||||
{
|
||||
if(frames.size() != MAXHOPS)
|
||||
{
|
||||
llarp::LogError("LRCM invalid number of records, ", frames.size(),
|
||||
"!=", MAXHOPS);
|
||||
return false;
|
||||
}
|
||||
if(!router->paths.AllowingTransit())
|
||||
{
|
||||
llarp::LogError("got LRCM when not permitting transit");
|
||||
return false;
|
||||
}
|
||||
return AsyncDecrypt(&router->paths);
|
||||
}
|
||||
|
||||
bool
|
||||
LR_CommitRecord::BEncode(llarp_buffer_t* buf) const
|
||||
{
|
||||
if(!bencode_start_dict(buf))
|
||||
return false;
|
||||
|
||||
if(!BEncodeWriteDictEntry("c", commkey, buf))
|
||||
return false;
|
||||
if(!BEncodeWriteDictEntry("i", nextHop, buf))
|
||||
return false;
|
||||
if(lifetime > 10 && lifetime < 600)
|
||||
{
|
||||
if(!BEncodeWriteDictInt("i", lifetime, buf))
|
||||
return false;
|
||||
}
|
||||
if(!BEncodeWriteDictEntry("n", tunnelNonce, buf))
|
||||
return false;
|
||||
if(!BEncodeWriteDictEntry("r", rxid, buf))
|
||||
return false;
|
||||
if(!BEncodeWriteDictEntry("t", txid, buf))
|
||||
return false;
|
||||
if(!bencode_write_version_entry(buf))
|
||||
return false;
|
||||
if(work && !BEncodeWriteDictEntry("w", *work, buf))
|
||||
return false;
|
||||
|
||||
return bencode_end(buf);
|
||||
}
|
||||
|
||||
LR_CommitRecord::~LR_CommitRecord()
|
||||
{
|
||||
if(work)
|
||||
delete work;
|
||||
}
|
||||
|
||||
bool
|
||||
LR_CommitRecord::OnKey(dict_reader* r, llarp_buffer_t* key)
|
||||
{
|
||||
if(!key)
|
||||
return true;
|
||||
|
||||
LR_CommitRecord* self = static_cast< LR_CommitRecord* >(r->user);
|
||||
|
||||
bool read = false;
|
||||
|
||||
if(!BEncodeMaybeReadDictEntry("c", self->commkey, read, *key, r->buffer))
|
||||
return false;
|
||||
if(!BEncodeMaybeReadDictEntry("i", self->nextHop, read, *key, r->buffer))
|
||||
return false;
|
||||
if(!BEncodeMaybeReadDictInt("l", self->lifetime, read, *key, r->buffer))
|
||||
return false;
|
||||
if(!BEncodeMaybeReadDictEntry("n", self->tunnelNonce, read, *key,
|
||||
r->buffer))
|
||||
return false;
|
||||
if(!BEncodeMaybeReadDictEntry("r", self->rxid, read, *key, r->buffer))
|
||||
return false;
|
||||
if(!BEncodeMaybeReadDictEntry("t", self->txid, read, *key, r->buffer))
|
||||
return false;
|
||||
if(!BEncodeMaybeReadVersion("v", self->version, LLARP_PROTO_VERSION, read,
|
||||
*key, r->buffer))
|
||||
return false;
|
||||
if(llarp_buffer_eq(*key, "w"))
|
||||
{
|
||||
// check for duplicate
|
||||
if(self->work)
|
||||
{
|
||||
llarp::LogWarn("duplicate POW in LRCR");
|
||||
return false;
|
||||
}
|
||||
|
||||
self->work = new PoW();
|
||||
return self->work->BDecode(r->buffer);
|
||||
}
|
||||
return read;
|
||||
}
|
||||
|
||||
bool
|
||||
LR_CommitRecord::BDecode(llarp_buffer_t* buf)
|
||||
{
|
||||
dict_reader r;
|
||||
r.user = this;
|
||||
r.on_key = &OnKey;
|
||||
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
|
||||
&& txid == other.txid && rxid == other.rxid;
|
||||
}
|
||||
|
||||
struct LRCMFrameDecrypt
|
||||
{
|
||||
typedef llarp::path::PathContext Context;
|
||||
typedef llarp::path::TransitHop Hop;
|
||||
typedef AsyncFrameDecrypter< LRCMFrameDecrypt > Decrypter;
|
||||
Decrypter* decrypter;
|
||||
std::array< EncryptedFrame, 8 > frames;
|
||||
Context* context;
|
||||
// decrypted record
|
||||
LR_CommitRecord record;
|
||||
// the actual hop
|
||||
std::shared_ptr< Hop > hop;
|
||||
|
||||
LRCMFrameDecrypt(Context* ctx, Decrypter* dec,
|
||||
const LR_CommitMessage* commit)
|
||||
: decrypter(dec), frames(commit->frames), context(ctx), hop(new Hop())
|
||||
{
|
||||
hop->info.downstream = commit->session->GetPubKey();
|
||||
}
|
||||
|
||||
~LRCMFrameDecrypt()
|
||||
{
|
||||
delete decrypter;
|
||||
}
|
||||
|
||||
/// this is done from logic thread
|
||||
static void
|
||||
SendLRCM(void* user)
|
||||
{
|
||||
LRCMFrameDecrypt* self = static_cast< LRCMFrameDecrypt* >(user);
|
||||
// persist sessions to upstream and downstream routers until the commit
|
||||
// ends
|
||||
self->context->Router()->PersistSessionUntil(self->hop->info.downstream,
|
||||
self->hop->ExpireTime());
|
||||
self->context->Router()->PersistSessionUntil(self->hop->info.upstream,
|
||||
self->hop->ExpireTime());
|
||||
// put hop
|
||||
self->context->PutTransitHop(self->hop);
|
||||
// forward to next hop
|
||||
self->context->ForwardLRCM(self->hop->info.upstream, self->frames);
|
||||
self->hop = nullptr;
|
||||
delete self;
|
||||
}
|
||||
|
||||
// this is called from the logic thread
|
||||
static void
|
||||
SendPathConfirm(void* user)
|
||||
{
|
||||
LRCMFrameDecrypt* self = static_cast< LRCMFrameDecrypt* >(user);
|
||||
// persist session to downstream until path expiration
|
||||
self->context->Router()->PersistSessionUntil(self->hop->info.downstream,
|
||||
self->hop->ExpireTime());
|
||||
// put hop
|
||||
self->context->PutTransitHop(self->hop);
|
||||
// send path confirmation
|
||||
llarp::routing::PathConfirmMessage confirm(self->hop->lifetime);
|
||||
if(!self->hop->SendRoutingMessage(&confirm, self->context->Router()))
|
||||
{
|
||||
llarp::LogError("failed to send path confirmation for ",
|
||||
self->hop->info);
|
||||
}
|
||||
self->hop = nullptr;
|
||||
delete self;
|
||||
}
|
||||
|
||||
static void
|
||||
HandleDecrypted(llarp_buffer_t* buf, LRCMFrameDecrypt* self)
|
||||
{
|
||||
auto now = self->context->Router()->Now();
|
||||
auto& info = self->hop->info;
|
||||
if(!buf)
|
||||
{
|
||||
llarp::LogError("LRCM decrypt failed from ", info.downstream);
|
||||
delete self;
|
||||
return;
|
||||
}
|
||||
buf->cur = buf->base + EncryptedFrameOverheadSize;
|
||||
llarp::LogDebug("decrypted LRCM from ", info.downstream);
|
||||
// successful decrypt
|
||||
if(!self->record.BDecode(buf))
|
||||
{
|
||||
llarp::LogError("malformed frame inside LRCM from ", info.downstream);
|
||||
delete self;
|
||||
return;
|
||||
}
|
||||
|
||||
info.txID = self->record.txid;
|
||||
info.rxID = self->record.rxid;
|
||||
info.upstream = self->record.nextHop;
|
||||
if(self->context->HasTransitHop(info))
|
||||
{
|
||||
llarp::LogError("duplicate transit hop ", info);
|
||||
delete self;
|
||||
return;
|
||||
}
|
||||
// generate path key as we are in a worker thread
|
||||
auto DH = self->context->Crypto()->dh_server;
|
||||
if(!DH(self->hop->pathKey, self->record.commkey,
|
||||
self->context->EncryptionSecretKey(), self->record.tunnelNonce))
|
||||
{
|
||||
llarp::LogError("LRCM DH Failed ", info);
|
||||
delete self;
|
||||
return;
|
||||
}
|
||||
// generate hash of hop key for nonce mutation
|
||||
self->context->Crypto()->shorthash(self->hop->nonceXOR,
|
||||
self->hop->pathKey.as_buffer());
|
||||
if(self->record.work
|
||||
&& self->record.work->IsValid(self->context->Crypto()->shorthash, now))
|
||||
{
|
||||
llarp::LogDebug("LRCM extended lifetime by ",
|
||||
self->record.work->extendedLifetime, " seconds for ",
|
||||
info);
|
||||
self->hop->lifetime += 1000 * self->record.work->extendedLifetime;
|
||||
}
|
||||
else if(self->record.lifetime < 600 && self->record.lifetime > 10)
|
||||
{
|
||||
self->hop->lifetime = self->record.lifetime;
|
||||
llarp::LogDebug("LRCM short lifespan set to ", self->hop->lifetime,
|
||||
" seconds for ", info);
|
||||
}
|
||||
|
||||
// TODO: check if we really want to accept it
|
||||
self->hop->started = now;
|
||||
|
||||
size_t sz = self->frames[0].size();
|
||||
// shift
|
||||
std::array< EncryptedFrame, 8 > frames;
|
||||
frames[0] = self->frames[1];
|
||||
frames[1] = self->frames[2];
|
||||
frames[2] = self->frames[3];
|
||||
frames[3] = self->frames[4];
|
||||
frames[4] = self->frames[5];
|
||||
frames[5] = self->frames[6];
|
||||
frames[6] = self->frames[7];
|
||||
// put our response on the end
|
||||
frames[7] = EncryptedFrame(sz - EncryptedFrameOverheadSize);
|
||||
// random junk for now
|
||||
frames[7].Randomize();
|
||||
self->frames = std::move(frames);
|
||||
if(self->context->HopIsUs(info.upstream))
|
||||
{
|
||||
// we are the farthest hop
|
||||
llarp::LogDebug("We are the farthest hop for ", info);
|
||||
// send a LRAM down the path
|
||||
self->context->Logic()->queue_job({self, &SendPathConfirm});
|
||||
}
|
||||
else
|
||||
{
|
||||
// forward upstream
|
||||
// we are still in the worker thread so post job to logic
|
||||
self->context->Logic()->queue_job({self, &SendLRCM});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
bool
|
||||
LR_CommitMessage::AsyncDecrypt(llarp::path::PathContext* context) const
|
||||
{
|
||||
LRCMFrameDecrypt::Decrypter* decrypter = new LRCMFrameDecrypt::Decrypter(
|
||||
context->Crypto(), context->EncryptionSecretKey(),
|
||||
&LRCMFrameDecrypt::HandleDecrypted);
|
||||
// copy frames so we own them
|
||||
LRCMFrameDecrypt* frames = new LRCMFrameDecrypt(context, decrypter, this);
|
||||
|
||||
// decrypt frames async
|
||||
decrypter->AsyncDecrypt(context->Worker(), frames->frames[0], frames);
|
||||
return true;
|
||||
}
|
||||
} // namespace llarp
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include <address_info.hpp>
|
||||
#include <net/address_info.hpp>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
@ -1,4 +1,4 @@
|
||||
#include <ip.hpp>
|
||||
#include <net/ip.hpp>
|
||||
|
||||
#include <util/buffer.hpp>
|
||||
#include <util/endian.hpp>
|
@ -1 +1,58 @@
|
||||
#include <pow.hpp>
|
||||
|
||||
#include <util/buffer.hpp>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
PoW::~PoW()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
PoW::DecodeKey(__attribute__((unused)) llarp_buffer_t k,
|
||||
__attribute__((unused)) llarp_buffer_t* val)
|
||||
{
|
||||
// TODO: implement me
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
PoW::BEncode(llarp_buffer_t* buf) const
|
||||
{
|
||||
// TODO: implement me
|
||||
if(!bencode_start_dict(buf))
|
||||
return false;
|
||||
return bencode_end(buf);
|
||||
}
|
||||
|
||||
bool
|
||||
PoW::IsValid(shorthash_func hashfunc, llarp_time_t now) const
|
||||
{
|
||||
if(now - timestamp > (uint64_t(extendedLifetime) * 1000))
|
||||
return false;
|
||||
|
||||
ShortHash digest;
|
||||
byte_t tmp[MaxSize];
|
||||
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
|
||||
// encode
|
||||
if(!BEncode(&buf))
|
||||
return false;
|
||||
// rewind
|
||||
buf.sz = buf.cur - buf.base;
|
||||
buf.cur = buf.base;
|
||||
// hash
|
||||
if(!hashfunc(digest, buf))
|
||||
return false;
|
||||
// check bytes required
|
||||
uint32_t required = std::floor(std::log(extendedLifetime));
|
||||
for(uint32_t idx = 0; idx < required; ++idx)
|
||||
{
|
||||
if(digest[idx])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace llarp
|
||||
|
@ -1,58 +0,0 @@
|
||||
#include <pow.hpp>
|
||||
|
||||
#include <util/buffer.hpp>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
PoW::~PoW()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
PoW::DecodeKey(__attribute__((unused)) llarp_buffer_t k,
|
||||
__attribute__((unused)) llarp_buffer_t* val)
|
||||
{
|
||||
// TODO: implement me
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
PoW::BEncode(llarp_buffer_t* buf) const
|
||||
{
|
||||
// TODO: implement me
|
||||
if(!bencode_start_dict(buf))
|
||||
return false;
|
||||
return bencode_end(buf);
|
||||
}
|
||||
|
||||
bool
|
||||
PoW::IsValid(shorthash_func hashfunc, llarp_time_t now) const
|
||||
{
|
||||
if(now - timestamp > (uint64_t(extendedLifetime) * 1000))
|
||||
return false;
|
||||
|
||||
ShortHash digest;
|
||||
byte_t tmp[MaxSize];
|
||||
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
|
||||
// encode
|
||||
if(!BEncode(&buf))
|
||||
return false;
|
||||
// rewind
|
||||
buf.sz = buf.cur - buf.base;
|
||||
buf.cur = buf.base;
|
||||
// hash
|
||||
if(!hashfunc(digest, buf))
|
||||
return false;
|
||||
// check bytes required
|
||||
uint32_t required = std::floor(std::log(extendedLifetime));
|
||||
for(uint32_t idx = 0; idx < required; ++idx)
|
||||
{
|
||||
if(digest[idx])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace llarp
|
@ -1,344 +0,0 @@
|
||||
#include <messages/path_confirm.hpp>
|
||||
#include <messages/relay_commit.hpp>
|
||||
#include <path/path.hpp>
|
||||
#include <router.hpp>
|
||||
#include <util/bencode.hpp>
|
||||
#include <util/buffer.hpp>
|
||||
#include <util/logger.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
LR_CommitMessage::~LR_CommitMessage()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
LR_CommitMessage::DecodeKey(llarp_buffer_t key, llarp_buffer_t* buf)
|
||||
{
|
||||
if(llarp_buffer_eq(key, "c"))
|
||||
{
|
||||
return BEncodeReadArray(frames, buf);
|
||||
}
|
||||
bool read = false;
|
||||
if(!BEncodeMaybeReadVersion("v", version, LLARP_PROTO_VERSION, read, key,
|
||||
buf))
|
||||
return false;
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
void
|
||||
LR_CommitMessage::Clear()
|
||||
{
|
||||
frames[0].Clear();
|
||||
frames[1].Clear();
|
||||
frames[2].Clear();
|
||||
frames[3].Clear();
|
||||
frames[4].Clear();
|
||||
frames[5].Clear();
|
||||
frames[6].Clear();
|
||||
frames[7].Clear();
|
||||
}
|
||||
|
||||
bool
|
||||
LR_CommitMessage::BEncode(llarp_buffer_t* buf) const
|
||||
{
|
||||
if(!bencode_start_dict(buf))
|
||||
return false;
|
||||
// msg type
|
||||
if(!BEncodeWriteDictMsgType(buf, "a", "c"))
|
||||
return false;
|
||||
// frames
|
||||
if(!BEncodeWriteDictArray("c", frames, buf))
|
||||
return false;
|
||||
// version
|
||||
if(!bencode_write_version_entry(buf))
|
||||
return false;
|
||||
|
||||
return bencode_end(buf);
|
||||
}
|
||||
|
||||
bool
|
||||
LR_CommitMessage::HandleMessage(llarp::Router* router) const
|
||||
{
|
||||
if(frames.size() != MAXHOPS)
|
||||
{
|
||||
llarp::LogError("LRCM invalid number of records, ", frames.size(),
|
||||
"!=", MAXHOPS);
|
||||
return false;
|
||||
}
|
||||
if(!router->paths.AllowingTransit())
|
||||
{
|
||||
llarp::LogError("got LRCM when not permitting transit");
|
||||
return false;
|
||||
}
|
||||
return AsyncDecrypt(&router->paths);
|
||||
}
|
||||
|
||||
bool
|
||||
LR_CommitRecord::BEncode(llarp_buffer_t* buf) const
|
||||
{
|
||||
if(!bencode_start_dict(buf))
|
||||
return false;
|
||||
|
||||
if(!BEncodeWriteDictEntry("c", commkey, buf))
|
||||
return false;
|
||||
if(!BEncodeWriteDictEntry("i", nextHop, buf))
|
||||
return false;
|
||||
if(lifetime > 10 && lifetime < 600)
|
||||
{
|
||||
if(!BEncodeWriteDictInt("i", lifetime, buf))
|
||||
return false;
|
||||
}
|
||||
if(!BEncodeWriteDictEntry("n", tunnelNonce, buf))
|
||||
return false;
|
||||
if(!BEncodeWriteDictEntry("r", rxid, buf))
|
||||
return false;
|
||||
if(!BEncodeWriteDictEntry("t", txid, buf))
|
||||
return false;
|
||||
if(!bencode_write_version_entry(buf))
|
||||
return false;
|
||||
if(work && !BEncodeWriteDictEntry("w", *work, buf))
|
||||
return false;
|
||||
|
||||
return bencode_end(buf);
|
||||
}
|
||||
|
||||
LR_CommitRecord::~LR_CommitRecord()
|
||||
{
|
||||
if(work)
|
||||
delete work;
|
||||
}
|
||||
|
||||
bool
|
||||
LR_CommitRecord::OnKey(dict_reader* r, llarp_buffer_t* key)
|
||||
{
|
||||
if(!key)
|
||||
return true;
|
||||
|
||||
LR_CommitRecord* self = static_cast< LR_CommitRecord* >(r->user);
|
||||
|
||||
bool read = false;
|
||||
|
||||
if(!BEncodeMaybeReadDictEntry("c", self->commkey, read, *key, r->buffer))
|
||||
return false;
|
||||
if(!BEncodeMaybeReadDictEntry("i", self->nextHop, read, *key, r->buffer))
|
||||
return false;
|
||||
if(!BEncodeMaybeReadDictInt("l", self->lifetime, read, *key, r->buffer))
|
||||
return false;
|
||||
if(!BEncodeMaybeReadDictEntry("n", self->tunnelNonce, read, *key,
|
||||
r->buffer))
|
||||
return false;
|
||||
if(!BEncodeMaybeReadDictEntry("r", self->rxid, read, *key, r->buffer))
|
||||
return false;
|
||||
if(!BEncodeMaybeReadDictEntry("t", self->txid, read, *key, r->buffer))
|
||||
return false;
|
||||
if(!BEncodeMaybeReadVersion("v", self->version, LLARP_PROTO_VERSION, read,
|
||||
*key, r->buffer))
|
||||
return false;
|
||||
if(llarp_buffer_eq(*key, "w"))
|
||||
{
|
||||
// check for duplicate
|
||||
if(self->work)
|
||||
{
|
||||
llarp::LogWarn("duplicate POW in LRCR");
|
||||
return false;
|
||||
}
|
||||
|
||||
self->work = new PoW();
|
||||
return self->work->BDecode(r->buffer);
|
||||
}
|
||||
return read;
|
||||
}
|
||||
|
||||
bool
|
||||
LR_CommitRecord::BDecode(llarp_buffer_t* buf)
|
||||
{
|
||||
dict_reader r;
|
||||
r.user = this;
|
||||
r.on_key = &OnKey;
|
||||
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
|
||||
&& txid == other.txid && rxid == other.rxid;
|
||||
}
|
||||
|
||||
struct LRCMFrameDecrypt
|
||||
{
|
||||
typedef llarp::path::PathContext Context;
|
||||
typedef llarp::path::TransitHop Hop;
|
||||
typedef AsyncFrameDecrypter< LRCMFrameDecrypt > Decrypter;
|
||||
Decrypter* decrypter;
|
||||
std::array< EncryptedFrame, 8 > frames;
|
||||
Context* context;
|
||||
// decrypted record
|
||||
LR_CommitRecord record;
|
||||
// the actual hop
|
||||
std::shared_ptr< Hop > hop;
|
||||
|
||||
LRCMFrameDecrypt(Context* ctx, Decrypter* dec,
|
||||
const LR_CommitMessage* commit)
|
||||
: decrypter(dec), frames(commit->frames), context(ctx), hop(new Hop())
|
||||
{
|
||||
hop->info.downstream = commit->session->GetPubKey();
|
||||
}
|
||||
|
||||
~LRCMFrameDecrypt()
|
||||
{
|
||||
delete decrypter;
|
||||
}
|
||||
|
||||
/// this is done from logic thread
|
||||
static void
|
||||
SendLRCM(void* user)
|
||||
{
|
||||
LRCMFrameDecrypt* self = static_cast< LRCMFrameDecrypt* >(user);
|
||||
// persist sessions to upstream and downstream routers until the commit
|
||||
// ends
|
||||
self->context->Router()->PersistSessionUntil(self->hop->info.downstream,
|
||||
self->hop->ExpireTime());
|
||||
self->context->Router()->PersistSessionUntil(self->hop->info.upstream,
|
||||
self->hop->ExpireTime());
|
||||
// put hop
|
||||
self->context->PutTransitHop(self->hop);
|
||||
// forward to next hop
|
||||
self->context->ForwardLRCM(self->hop->info.upstream, self->frames);
|
||||
self->hop = nullptr;
|
||||
delete self;
|
||||
}
|
||||
|
||||
// this is called from the logic thread
|
||||
static void
|
||||
SendPathConfirm(void* user)
|
||||
{
|
||||
LRCMFrameDecrypt* self = static_cast< LRCMFrameDecrypt* >(user);
|
||||
// persist session to downstream until path expiration
|
||||
self->context->Router()->PersistSessionUntil(self->hop->info.downstream,
|
||||
self->hop->ExpireTime());
|
||||
// put hop
|
||||
self->context->PutTransitHop(self->hop);
|
||||
// send path confirmation
|
||||
llarp::routing::PathConfirmMessage confirm(self->hop->lifetime);
|
||||
if(!self->hop->SendRoutingMessage(&confirm, self->context->Router()))
|
||||
{
|
||||
llarp::LogError("failed to send path confirmation for ",
|
||||
self->hop->info);
|
||||
}
|
||||
self->hop = nullptr;
|
||||
delete self;
|
||||
}
|
||||
|
||||
static void
|
||||
HandleDecrypted(llarp_buffer_t* buf, LRCMFrameDecrypt* self)
|
||||
{
|
||||
auto now = self->context->Router()->Now();
|
||||
auto& info = self->hop->info;
|
||||
if(!buf)
|
||||
{
|
||||
llarp::LogError("LRCM decrypt failed from ", info.downstream);
|
||||
delete self;
|
||||
return;
|
||||
}
|
||||
buf->cur = buf->base + EncryptedFrameOverheadSize;
|
||||
llarp::LogDebug("decrypted LRCM from ", info.downstream);
|
||||
// successful decrypt
|
||||
if(!self->record.BDecode(buf))
|
||||
{
|
||||
llarp::LogError("malformed frame inside LRCM from ", info.downstream);
|
||||
delete self;
|
||||
return;
|
||||
}
|
||||
|
||||
info.txID = self->record.txid;
|
||||
info.rxID = self->record.rxid;
|
||||
info.upstream = self->record.nextHop;
|
||||
if(self->context->HasTransitHop(info))
|
||||
{
|
||||
llarp::LogError("duplicate transit hop ", info);
|
||||
delete self;
|
||||
return;
|
||||
}
|
||||
// generate path key as we are in a worker thread
|
||||
auto DH = self->context->Crypto()->dh_server;
|
||||
if(!DH(self->hop->pathKey, self->record.commkey,
|
||||
self->context->EncryptionSecretKey(), self->record.tunnelNonce))
|
||||
{
|
||||
llarp::LogError("LRCM DH Failed ", info);
|
||||
delete self;
|
||||
return;
|
||||
}
|
||||
// generate hash of hop key for nonce mutation
|
||||
self->context->Crypto()->shorthash(self->hop->nonceXOR,
|
||||
self->hop->pathKey.as_buffer());
|
||||
if(self->record.work
|
||||
&& self->record.work->IsValid(self->context->Crypto()->shorthash, now))
|
||||
{
|
||||
llarp::LogDebug("LRCM extended lifetime by ",
|
||||
self->record.work->extendedLifetime, " seconds for ",
|
||||
info);
|
||||
self->hop->lifetime += 1000 * self->record.work->extendedLifetime;
|
||||
}
|
||||
else if(self->record.lifetime < 600 && self->record.lifetime > 10)
|
||||
{
|
||||
self->hop->lifetime = self->record.lifetime;
|
||||
llarp::LogDebug("LRCM short lifespan set to ", self->hop->lifetime,
|
||||
" seconds for ", info);
|
||||
}
|
||||
|
||||
// TODO: check if we really want to accept it
|
||||
self->hop->started = now;
|
||||
|
||||
size_t sz = self->frames[0].size();
|
||||
// shift
|
||||
std::array< EncryptedFrame, 8 > frames;
|
||||
frames[0] = self->frames[1];
|
||||
frames[1] = self->frames[2];
|
||||
frames[2] = self->frames[3];
|
||||
frames[3] = self->frames[4];
|
||||
frames[4] = self->frames[5];
|
||||
frames[5] = self->frames[6];
|
||||
frames[6] = self->frames[7];
|
||||
// put our response on the end
|
||||
frames[7] = EncryptedFrame(sz - EncryptedFrameOverheadSize);
|
||||
// random junk for now
|
||||
frames[7].Randomize();
|
||||
self->frames = std::move(frames);
|
||||
if(self->context->HopIsUs(info.upstream))
|
||||
{
|
||||
// we are the farthest hop
|
||||
llarp::LogDebug("We are the farthest hop for ", info);
|
||||
// send a LRAM down the path
|
||||
self->context->Logic()->queue_job({self, &SendPathConfirm});
|
||||
}
|
||||
else
|
||||
{
|
||||
// forward upstream
|
||||
// we are still in the worker thread so post job to logic
|
||||
self->context->Logic()->queue_job({self, &SendLRCM});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
bool
|
||||
LR_CommitMessage::AsyncDecrypt(llarp::path::PathContext* context) const
|
||||
{
|
||||
LRCMFrameDecrypt::Decrypter* decrypter = new LRCMFrameDecrypt::Decrypter(
|
||||
context->Crypto(), context->EncryptionSecretKey(),
|
||||
&LRCMFrameDecrypt::HandleDecrypted);
|
||||
// copy frames so we own them
|
||||
LRCMFrameDecrypt* frames = new LRCMFrameDecrypt(context, decrypter, this);
|
||||
|
||||
// decrypt frames async
|
||||
decrypter->AsyncDecrypt(context->Worker(), frames->frames[0], frames);
|
||||
return true;
|
||||
}
|
||||
} // namespace llarp
|
@ -1,131 +0,0 @@
|
||||
#include <messages/relay.hpp>
|
||||
#include <router.hpp>
|
||||
#include <util/bencode.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
RelayUpstreamMessage::RelayUpstreamMessage() : ILinkMessage()
|
||||
{
|
||||
}
|
||||
|
||||
RelayUpstreamMessage::~RelayUpstreamMessage()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
RelayUpstreamMessage::Clear()
|
||||
{
|
||||
pathid.Zero();
|
||||
X.Clear();
|
||||
Y.Zero();
|
||||
}
|
||||
|
||||
bool
|
||||
RelayUpstreamMessage::BEncode(llarp_buffer_t *buf) const
|
||||
{
|
||||
if(!bencode_start_dict(buf))
|
||||
return false;
|
||||
if(!BEncodeWriteDictMsgType(buf, "a", "u"))
|
||||
return false;
|
||||
|
||||
if(!BEncodeWriteDictEntry("p", pathid, buf))
|
||||
return false;
|
||||
if(!BEncodeWriteDictInt("v", LLARP_PROTO_VERSION, buf))
|
||||
return false;
|
||||
if(!BEncodeWriteDictEntry("x", X, buf))
|
||||
return false;
|
||||
if(!BEncodeWriteDictEntry("y", Y, buf))
|
||||
return false;
|
||||
return bencode_end(buf);
|
||||
}
|
||||
|
||||
bool
|
||||
RelayUpstreamMessage::DecodeKey(llarp_buffer_t key, llarp_buffer_t *buf)
|
||||
{
|
||||
bool read = false;
|
||||
if(!BEncodeMaybeReadDictEntry("p", pathid, read, key, buf))
|
||||
return false;
|
||||
if(!BEncodeMaybeReadVersion("v", version, LLARP_PROTO_VERSION, read, key,
|
||||
buf))
|
||||
return false;
|
||||
if(!BEncodeMaybeReadDictEntry("x", X, read, key, buf))
|
||||
return false;
|
||||
if(!BEncodeMaybeReadDictEntry("y", Y, read, key, buf))
|
||||
return false;
|
||||
return read;
|
||||
}
|
||||
|
||||
bool
|
||||
RelayUpstreamMessage::HandleMessage(llarp::Router *r) const
|
||||
{
|
||||
auto path = r->paths.GetByDownstream(session->GetPubKey(), pathid);
|
||||
if(path)
|
||||
{
|
||||
return path->HandleUpstream(X.Buffer(), Y, r);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
RelayDownstreamMessage::RelayDownstreamMessage() : ILinkMessage()
|
||||
{
|
||||
}
|
||||
|
||||
RelayDownstreamMessage::~RelayDownstreamMessage()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
RelayDownstreamMessage::Clear()
|
||||
{
|
||||
pathid.Zero();
|
||||
X.Clear();
|
||||
Y.Zero();
|
||||
}
|
||||
|
||||
bool
|
||||
RelayDownstreamMessage::BEncode(llarp_buffer_t *buf) const
|
||||
{
|
||||
if(!bencode_start_dict(buf))
|
||||
return false;
|
||||
if(!BEncodeWriteDictMsgType(buf, "a", "d"))
|
||||
return false;
|
||||
|
||||
if(!BEncodeWriteDictEntry("p", pathid, buf))
|
||||
return false;
|
||||
if(!BEncodeWriteDictInt("v", LLARP_PROTO_VERSION, buf))
|
||||
return false;
|
||||
if(!BEncodeWriteDictEntry("x", X, buf))
|
||||
return false;
|
||||
if(!BEncodeWriteDictEntry("y", Y, buf))
|
||||
return false;
|
||||
return bencode_end(buf);
|
||||
}
|
||||
|
||||
bool
|
||||
RelayDownstreamMessage::DecodeKey(llarp_buffer_t key, llarp_buffer_t *buf)
|
||||
{
|
||||
bool read = false;
|
||||
if(!BEncodeMaybeReadDictEntry("p", pathid, read, key, buf))
|
||||
return false;
|
||||
if(!BEncodeMaybeReadVersion("v", version, LLARP_PROTO_VERSION, read, key,
|
||||
buf))
|
||||
return false;
|
||||
if(!BEncodeMaybeReadDictEntry("x", X, read, key, buf))
|
||||
return false;
|
||||
if(!BEncodeMaybeReadDictEntry("y", Y, read, key, buf))
|
||||
return false;
|
||||
return read;
|
||||
}
|
||||
|
||||
bool
|
||||
RelayDownstreamMessage::HandleMessage(llarp::Router *r) const
|
||||
{
|
||||
auto path = r->paths.GetByUpstream(session->GetPubKey(), pathid);
|
||||
if(path)
|
||||
{
|
||||
return path->HandleDownstream(X.Buffer(), Y, r);
|
||||
}
|
||||
llarp::LogWarn("unhandled downstream message");
|
||||
return false;
|
||||
}
|
||||
} // namespace llarp
|
@ -1,14 +1,14 @@
|
||||
#include <router.hpp>
|
||||
#include <router/router.hpp>
|
||||
|
||||
#include <constants/proto.hpp>
|
||||
#include <crypto/crypto.hpp>
|
||||
#include <dht/context.hpp>
|
||||
#include <link_message.hpp>
|
||||
#include <link/iwp.hpp>
|
||||
#include <link/server.hpp>
|
||||
#include <link/utp.hpp>
|
||||
#include <messages/link_message.hpp>
|
||||
#include <net/net.hpp>
|
||||
#include <rpc.hpp>
|
||||
#include <rpc/rpc.hpp>
|
||||
#include <util/buffer.hpp>
|
||||
#include <util/encode.hpp>
|
||||
#include <util/logger.hpp>
|
@ -1 +0,0 @@
|
||||
#include <routing_endpoint.hpp>
|
@ -1,18 +0,0 @@
|
||||
#ifndef LLARP_ROUTING_ENDPOINT_HPP
|
||||
#define LLARP_ROUTING_ENDPOINT_HPP
|
||||
|
||||
#include <util/aligned.hpp>
|
||||
#include <util/buffer.h>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
using RoutingEndpoint_t = AlignedBuffer< 32 >;
|
||||
|
||||
/// Interface for end to end crypto between endpoints
|
||||
struct IRoutingEndpoint
|
||||
{
|
||||
virtual ~IRoutingEndpoint(){};
|
||||
};
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
@ -0,0 +1 @@
|
||||
#include <util/codel.hpp>
|
Loading…
Reference in New Issue