ALMOST got path building working

pull/1/head
Jeff Becker 6 years ago
parent 50402820e1
commit 39c63432be
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05

@ -124,6 +124,7 @@ set(LIB_SRC
llarp/nodedb.cpp
llarp/path.cpp
llarp/pathbuilder.cpp
llarp/path_confirm.cpp
llarp/proofofwork.cpp
llarp/relay_ack.cpp
llarp/relay_commit.cpp
@ -131,6 +132,7 @@ set(LIB_SRC
llarp/router_contact.cpp
llarp/router.cpp
llarp/threadpool.cpp
llarp/transit_hop.cpp
llarp/testnet.c
llarp/time.cpp
llarp/timer.cpp

@ -294,7 +294,8 @@ the path is extended by w.y seconds
c: "<32 byte public encryption key used for upstream>",
i: "<32 byte RC.k of next hop>",
n: "<32 bytes nounce for key exchange>",
p: "<16 bytes path id>",
r: "<16 bytes rx path id>",
t: "<16 bytes tx path id>",
v: 0,
w: proof of work
}

@ -19,6 +19,12 @@ namespace llarp
AlignedBuffer() = default;
AlignedBuffer(const AlignedBuffer& other)
{
for(size_t idx = 0; idx < (sz / 8); ++idx)
l[idx] = other.l[idx];
}
AlignedBuffer(const byte_t* data)
{
for(size_t idx = 0; idx < sz; ++idx)

@ -12,7 +12,7 @@ namespace llarp
struct Encrypted
{
Encrypted(Encrypted&&) = delete;
Encrypted();
Encrypted(const byte_t* buf, size_t sz);
Encrypted(size_t sz);
~Encrypted();
@ -23,6 +23,18 @@ namespace llarp
return bencode_write_bytestring(buf, _data, _sz);
}
Encrypted&
operator=(llarp_buffer_t buf)
{
if(_data)
delete[] _data;
_sz = buf.sz;
_data = new byte_t[_sz];
memcpy(_data, buf.base, _sz);
UpdateBuffer();
return *this;
}
void
Fill(byte_t fill)
{
@ -61,6 +73,12 @@ namespace llarp
return &m_Buffer;
}
llarp_buffer_t
Buffer() const
{
return m_Buffer;
}
size_t
size()
{

@ -12,4 +12,6 @@
#include <llarp/messages/relay_ack.hpp>
#include <llarp/messages/relay_commit.hpp>
#include <llarp/messages/path_confirm.hpp>
#endif

@ -0,0 +1,30 @@
#ifndef LLARP_MESSAGE_PATH_CONFIRM_HPP
#define LLARP_MESSAGE_PATH_CONFIRM_HPP
#include <llarp/routing_message.hpp>
namespace llarp
{
namespace routing
{
struct PathConfirmMessage : public IMessage
{
uint64_t pathLifetime;
uint64_t pathCreated;
PathConfirmMessage(uint64_t lifetime);
~PathConfirmMessage(){};
bool
BEncode(llarp_buffer_t* buf) const;
bool
BDecode(llarp_buffer_t* buf);
bool
HandleMessage(llarp_router* r) const;
};
} // namespace routing
} // namespace llarp
#endif

@ -2,10 +2,20 @@
#define LLARP_MESSAGES_RELAY_HPP
#include <llarp/link_message.hpp>
#include <llarp/crypto.hpp>
#include <llarp/encrypted.hpp>
#include <llarp/path_types.hpp>
#include <vector>
namespace llarp
{
struct RelayUpstreamMessage : public ILinkMessage
{
PathID_t pathid;
Encrypted X;
TunnelNonce Y;
RelayUpstreamMessage();
RelayUpstreamMessage(const RouterID& from);
~RelayUpstreamMessage();
@ -21,6 +31,10 @@ namespace llarp
struct RelayDownstreamMessage : public ILinkMessage
{
PathID_t pathid;
Encrypted X;
TunnelNonce Y;
RelayDownstreamMessage();
RelayDownstreamMessage(const RouterID& from);
~RelayDownstreamMessage();
@ -33,6 +47,6 @@ namespace llarp
bool
HandleMessage(llarp_router* router) const;
};
}
} // namespace llarp
#endif

@ -18,7 +18,8 @@ namespace llarp
PubKey commkey;
RouterID nextHop;
TunnelNonce tunnelNonce;
PathID_t pathid;
PathID_t txid, rxid;
PoW *work = nullptr;
uint64_t version = 0;

@ -6,10 +6,11 @@
#include <llarp/aligned.hpp>
#include <llarp/crypto.hpp>
#include <llarp/endpoint.hpp>
#include <llarp/messages/relay_ack.hpp>
#include <llarp/messages/relay.hpp>
#include <llarp/messages/relay_commit.hpp>
#include <llarp/path_types.hpp>
#include <llarp/router_id.hpp>
#include <llarp/routing_message.hpp>
#include <list>
#include <map>
@ -17,21 +18,24 @@
#include <unordered_map>
#include <vector>
#define DEFAULT_PATH_LIFETIME (10 * 60 * 1000)
namespace llarp
{
struct TransitHopInfo
{
TransitHopInfo() = default;
TransitHopInfo(const TransitHopInfo& other);
TransitHopInfo(const RouterID& down, const LR_CommitRecord& record);
PathID_t pathID;
PathID_t txID, rxID;
RouterID upstream;
RouterID downstream;
friend std::ostream&
operator<<(std::ostream& out, const TransitHopInfo& info)
{
out << "<Transit Hop id=" << info.pathID;
out << "<tx=" << info.txID << " rx=" << info.rxID;
out << " upstream=" << info.upstream << " downstream=" << info.downstream;
return out << ">";
}
@ -39,8 +43,8 @@ namespace llarp
bool
operator==(const TransitHopInfo& other) const
{
return pathID == other.pathID && upstream == other.upstream
&& downstream == other.downstream;
return txID == other.txID && rxID == other.rxID
&& upstream == other.upstream && downstream == other.downstream;
}
bool
@ -52,7 +56,7 @@ namespace llarp
bool
operator<(const TransitHopInfo& other) const
{
return pathID < other.pathID || upstream < other.upstream
return txID < other.txID || rxID < other.rxID || upstream < other.upstream
|| downstream < other.downstream;
}
@ -61,10 +65,11 @@ namespace llarp
std::size_t
operator()(TransitHopInfo const& a) const
{
std::size_t idx0, idx1, idx2;
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.pathID, sizeof(std::size_t));
memcpy(&idx2, a.txID, sizeof(std::size_t));
memcpy(&idx3, a.rxID, sizeof(std::size_t));
return idx0 ^ idx1 ^ idx2;
}
};
@ -81,34 +86,67 @@ namespace llarp
}
};
struct TransitHop
struct IHopHandler
{
virtual ~IHopHandler(){};
virtual bool
Expired(llarp_time_t now) const = 0;
virtual bool
SendRoutingMessage(const llarp::routing::IMessage* msg,
llarp_router* r) = 0;
// handle data in upstream direction
virtual bool
HandleUpstream(llarp_buffer_t X, const TunnelNonce& Y, llarp_router* r) = 0;
// handle data in downstream direction
virtual bool
HandleDownstream(llarp_buffer_t X, const TunnelNonce& Y,
llarp_router* r) = 0;
};
struct TransitHop : public IHopHandler
{
TransitHop() = default;
TransitHop(const TransitHop& other);
TransitHopInfo info;
SharedSecret pathKey;
llarp_time_t started;
llarp_time_t started = 0;
// 10 minutes default
llarp_time_t lifetime = 360000;
llarp_time_t lifetime = DEFAULT_PATH_LIFETIME;
llarp_proto_version_t version;
friend std::ostream&
operator<<(std::ostream& out, const TransitHop& h)
{
return out << "[TransitHop " << h.info << " started=" << h.started
<< " lifetime=" << h.lifetime << "]";
}
bool
Expired(llarp_time_t now) const;
// forward data in upstream direction
void
ForwardUpstream(llarp_buffer_t X, const TunnelNonce& Y, llarp_router* r);
bool
SendRoutingMessage(const llarp::routing::IMessage* msg, llarp_router* r);
// forward data in downstream direction
void
ForwardDownstream(llarp_buffer_t X, const TunnelNonce& Y, llarp_router* r);
// handle data in upstream direction
bool
HandleUpstream(llarp_buffer_t X, const TunnelNonce& Y, llarp_router* r);
// handle data in downstream direction
bool
HandleDownstream(llarp_buffer_t X, const TunnelNonce& Y, llarp_router* r);
};
/// configuration for a single hop when building a path
struct PathHopConfig
{
/// path id
PathID_t pathID;
PathID_t txID, rxID;
// router contact of router
llarp_rc router;
// temp public encryption key
@ -119,6 +157,8 @@ namespace llarp
RouterID upstream;
/// nonce for key exchange
TunnelNonce nonce;
// lifetime
llarp_time_t lifetime = DEFAULT_PATH_LIFETIME;
~PathHopConfig();
PathHopConfig();
@ -133,7 +173,7 @@ namespace llarp
};
/// A path we made
struct Path
struct Path : public IHopHandler
{
typedef std::vector< PathHopConfig > HopList;
HopList hops;
@ -142,17 +182,28 @@ namespace llarp
Path(llarp_path_hops* path);
void
EncryptAndSend(llarp_buffer_t buf, llarp_router* r);
bool
Expired(llarp_time_t now) const;
void
DecryptAndRecv(llarp_buffer_t buf, IEndpointHandler* handler);
bool
SendRoutingMessage(const llarp::routing::IMessage* msg, llarp_router* r);
bool
HandleRoutingMessage(llarp_buffer_t buf, llarp_router* r);
// handle data in upstream direction
bool
HandleUpstream(llarp_buffer_t X, const TunnelNonce& Y, llarp_router* r);
// handle data in downstream direction
bool
HandleDownstream(llarp_buffer_t X, const TunnelNonce& Y, llarp_router* r);
const PathID_t&
PathID() const;
RouterID
Upstream();
Upstream() const;
};
enum PathBuildStatus
@ -185,11 +236,14 @@ namespace llarp
bool
HandleRelayCommit(const LR_CommitMessage* msg);
bool
HandleRelayAck(const LR_AckMessage* msg);
void
PutTransitHop(const TransitHop& hop);
PutTransitHop(TransitHop* hop);
IHopHandler*
GetByUpstream(const RouterID& id, const PathID_t& path);
IHopHandler*
GetDownstream(const RouterID& id, const PathID_t& path);
bool
ForwardLRCM(const RouterID& nextHop, std::deque< EncryptedFrame >& frames);
@ -197,11 +251,16 @@ namespace llarp
bool
HopIsUs(const PubKey& k) const;
bool
HandleLRUM(const RelayUpstreamMessage* msg);
bool
HandleLRDM(const RelayDownstreamMessage* msg);
void
AddOwnPath(Path* p);
typedef std::unordered_multimap< PathID_t, TransitHop, PathIDHash >
TransitHopsMap_t;
typedef std::multimap< PathID_t, TransitHop* > TransitHopsMap_t;
typedef std::pair< std::mutex, TransitHopsMap_t > SyncTransitMap_t;
@ -218,6 +277,9 @@ namespace llarp
llarp_logic*
Logic();
llarp_router*
Router();
byte_t*
EncryptionSecretKey();
@ -227,6 +289,7 @@ namespace llarp
private:
llarp_router* m_Router;
SyncTransitMap_t m_TransitPaths;
SyncTransitMap_t m_Paths;
SyncOwnedPathsMap_t m_OurPaths;
bool m_AllowTransit;

@ -0,0 +1,30 @@
#ifndef LLARP_ROUTING_MESSAGE_HPP
#define LLARP_ROUTING_MESSAGE_HPP
#include <llarp/buffer.h>
#include <llarp/router.h>
#include <llarp/path_types.hpp>
namespace llarp
{
namespace routing
{
struct IMessage
{
llarp::PathID_t from;
virtual ~IMessage(){};
virtual bool
BEncode(llarp_buffer_t* buf) const = 0;
virtual bool
BDecode(llarp_buffer_t* buf) = 0;
virtual bool
HandleMessage(llarp_router* r) const = 0;
};
} // namespace routing
} // namespace llarp
#endif

@ -5,6 +5,11 @@
namespace llarp
{
Encrypted::Encrypted()
{
UpdateBuffer();
}
Encrypted::Encrypted(const byte_t* buf, size_t sz) : _sz(sz)
{
_data = new byte_t[sz];

@ -1396,8 +1396,8 @@ namespace iwp
llarp::Debug("removing session ", addr);
UnmapAddr(addr);
session *s = static_cast< session * >(itr->second.impl);
m_sessions.erase(itr);
s->done();
m_sessions.erase(itr);
if(s->frames)
{
llarp::Warn("session has ", s->frames,
@ -1903,18 +1903,19 @@ namespace iwp
self->establish_job_id = 0;
if(self->establish_job)
{
self->establish_job->link = self->serv->parent;
auto job = self->establish_job;
self->establish_job = nullptr;
job->link = self->serv->parent;
if(self->IsEstablished())
{
self->establish_job->session = self->parent;
job->session = self->parent;
}
else
{
// timer timeout
self->establish_job->session = nullptr;
job->session = nullptr;
}
self->establish_job->result(self->establish_job);
self->establish_job = nullptr;
job->result(job);
}
}
@ -1950,22 +1951,23 @@ namespace iwp
}
} // namespace iwp
extern "C" {
void
iwp_link_init(struct llarp_link *link, struct llarp_iwp_args args)
extern "C"
{
link->impl = iwp::link_alloc(args.router, args.keyfile, args.crypto,
args.logic, args.cryptoworker);
link->name = iwp::link_name;
link->get_our_address = iwp::link_get_addr;
link->configure = iwp::link_configure;
link->start_link = iwp::link_start;
link->stop_link = iwp::link_stop;
link->iter_sessions = iwp::link_iter_sessions;
link->try_establish = iwp::link_try_establish;
link->has_session_to = iwp::server::HasSessionToRouter;
link->sendto = iwp::server::SendToSession;
link->mark_session_active = iwp::link_mark_session_active;
link->free_impl = iwp::link_free;
}
void
iwp_link_init(struct llarp_link *link, struct llarp_iwp_args args)
{
link->impl = iwp::link_alloc(args.router, args.keyfile, args.crypto,
args.logic, args.cryptoworker);
link->name = iwp::link_name;
link->get_our_address = iwp::link_get_addr;
link->configure = iwp::link_configure;
link->start_link = iwp::link_start;
link->stop_link = iwp::link_stop;
link->iter_sessions = iwp::link_iter_sessions;
link->try_establish = iwp::link_try_establish;
link->has_session_to = iwp::server::HasSessionToRouter;
link->sendto = iwp::server::SendToSession;
link->mark_session_active = iwp::link_mark_session_active;
link->free_impl = iwp::link_free;
}
}

@ -1,6 +1,7 @@
#include <deque>
#include <llarp/encrypted_frame.hpp>
#include <llarp/path.hpp>
#include "buffer.hpp"
#include "router.hpp"
namespace llarp
@ -69,6 +70,20 @@ namespace llarp
}
return m_Router->SendToOrQueue(nextHop, msg);
}
template < typename Map_t, typename Key_t, typename CheckValue_t >
IHopHandler*
MapGet(Map_t& map, const Key_t& k, CheckValue_t check)
{
std::unique_lock< std::mutex > lock(map.first);
auto itr = map.second.find(k);
while(itr != map.second.end())
{
if(check(itr->second))
return itr->second;
++itr;
}
return nullptr;
}
template < typename Map_t, typename Key_t, typename CheckValue_t >
bool
@ -93,6 +108,21 @@ namespace llarp
map.second.emplace(k, v);
}
template < typename Map_t, typename Key_t, typename Check_t >
void
MapDel(Map_t& map, const Key_t& k, Check_t check)
{
std::unique_lock< std::mutex > lock(map.first);
auto itr = map.second.find(k);
while(itr != map.second.end())
{
if(check(itr->second))
itr = map.second.erase(itr);
else
++itr;
}
}
void
PathContext::AddOwnPath(Path* path)
{
@ -102,9 +132,22 @@ namespace llarp
bool
PathContext::HasTransitHop(const TransitHopInfo& info)
{
return MapHas(
m_TransitPaths, info.pathID,
[info](const TransitHop& hop) -> bool { return info == hop.info; });
return MapHas(m_TransitPaths, info.pathID, [info](TransitHop* hop) -> bool {
return info == hop->info;
});
}
IHopHandler*
PathContext::GetByUpstream(const RouterID& remote, const PathID_t& id)
{
auto own = MapGet(m_OurPaths, id, [remote](const Path* p) -> bool {
return p->Upstream() == remote;
});
if(own)
return own;
return MapGet(m_TransitPaths, id, [remote](const TransitHop* hop) -> bool {
return hop->info.upstream == remote;
});
}
const byte_t*
@ -113,10 +156,17 @@ namespace llarp
return m_Router->pubkey();
}
llarp_router*
PathContext::Router()
{
return m_Router;
}
void
PathContext::PutTransitHop(const TransitHop& hop)
PathContext::PutTransitHop(TransitHop* hop)
{
MapPut(m_TransitPaths, hop.info.pathID, hop);
MapPut(m_TransitPaths, hop->info.txID, hop);
MapPut(m_TransitPaths, hop->info.rxID, hop);
}
void
@ -126,45 +176,110 @@ namespace llarp
auto now = llarp_time_now_ms();
auto& map = m_TransitPaths.second;
auto itr = map.begin();
std::set< TransitHop* > removePaths;
while(itr != map.end())
{
if(itr->second.Expired(now))
itr = map.erase(itr);
else
++itr;
if(itr->second->Expired(now))
{
TransitHop* path = itr->second;
llarp::Info("transit path expired ", path);
removePaths.insert(path);
}
++itr;
}
for(auto& p : removePaths)
{
map.erase(p->info.txID);
map.erase(p->info.rxID);
delete p;
}
}
Path::Path(llarp_path_hops* h) : hops(h->numHops)
{
for(size_t idx = 0; idx < h->numHops; ++idx)
{
llarp_rc_copy(&hops[idx].router, &h->hops[idx].router);
}
}
const PathID_t&
Path::TXID() const
{
return hops[0].pathTX;
}
const PathID_t&
Path::RXID() const
{
return hops[0].pathRX;
}
RouterID
Path::Upstream() const
{
return hops[0].router.pubkey;
}
bool
TransitHop::Expired(llarp_time_t now) const
Path::HandleUpstream(llarp_buffer_t buf, const TunnelNonce& Y,
llarp_router* r)
{
return now - started > lifetime;
for(const auto& hop : hops)
{
r->crypto.xchacha20(buf, hop.shared, Y);
}
RelayUpstreamMessage* msg = new RelayUpstreamMessage;
msg->X = buf;
msg->Y = Y;
msg->pathid = PathID();
msg->pathid.data_l()[1] = 0;
return r->SendToOrQueue(Upstream(), msg);
}
TransitHopInfo::TransitHopInfo(const RouterID& down,
const LR_CommitRecord& record)
: pathID(record.pathid), upstream(record.nextHop), downstream(down)
bool
Path::Expired(llarp_time_t now) const
{
return now - buildStarted > hops[0].lifetime;
}
Path::Path(llarp_path_hops* h) : hops(h->numHops)
bool
Path::HandleDownstream(llarp_buffer_t buf, const TunnelNonce& Y,
llarp_router* r)
{
for(size_t idx = 0; idx < h->numHops; ++idx)
size_t idx = hops.size() - 1;
while(idx >= 0)
{
llarp_rc_copy(&hops[idx].router, &h->hops[idx].router);
r->crypto.xchacha20(buf, hops[idx].shared, Y);
if(idx)
idx--;
else
break;
}
return HandleRoutingMessage(buf, r);
}
const PathID_t&
Path::PathID() const
bool
Path::HandleRoutingMessage(llarp_buffer_t buf, llarp_router* r)
{
return hops[0].pathID;
// TODO: implement me
return true;
}
RouterID
Path::Upstream()
bool
Path::SendRoutingMessage(const llarp::routing::IMessage* msg, llarp_router* r)
{
return hops[0].router.pubkey;
byte_t tmp[MAX_LINK_MSG_SIZE / 2];
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
if(!msg->BEncode(&buf))
return false;
// rewind
buf.sz = buf.cur - buf.base;
buf.cur = buf.base;
// make nonce
TunnelNonce N;
N.Randomize();
return HandleUpstream(buf, N, r);
}
} // namespace llarp

@ -0,0 +1,41 @@
#include <llarp/time.h>
#include <llarp/bencode.hpp>
#include <llarp/messages/path_confirm.hpp>
namespace llarp
{
namespace routing
{
PathConfirmMessage::PathConfirmMessage(uint64_t lifetime)
: pathLifetime(lifetime), pathCreated(llarp_time_now_ms())
{
}
bool
PathConfirmMessage::BEncode(llarp_buffer_t* buf) const
{
if(!bencode_start_dict(buf))
return false;
if(!BEncodeWriteDictMsgType(buf, "A", "P"))
return false;
if(!BEncodeWriteDictInt(buf, "L", pathLifetime))
return false;
if(!BEncodeWriteDictInt(buf, "S", pathCreated))
return false;
return bencode_end(buf);
}
bool
PathConfirmMessage::BDecode(llarp_buffer_t* buf)
{
return false;
}
bool
PathConfirmMessage::HandleMessage(llarp_router* r) const
{
return true;
}
} // namespace routing
} // namespace llarp

@ -47,8 +47,6 @@ namespace llarp
abort();
return;
}
// randomize hop's path id
hop.pathID.Randomize();
++ctx->idx;

@ -1,5 +1,7 @@
#include <llarp/bencode.hpp>
#include <llarp/messages/path_confirm.hpp>
#include <llarp/messages/relay_commit.hpp>
#include "buffer.hpp"
#include "logger.hpp"
#include "router.hpp"
@ -73,7 +75,9 @@ namespace llarp
return false;
if(!BEncodeWriteDictEntry("n", tunnelNonce, buf))
return false;
if(!BEncodeWriteDictEntry("p", pathid, buf))
if(!BEncodeWriteDictEntry("r", rxid, buf))
return false;
if(!BEncodeWriteDictEntry("t", txid, buf))
return false;
if(!bencode_write_version_entry(buf))
return false;
@ -106,7 +110,9 @@ namespace llarp
if(!BEncodeMaybeReadDictEntry("n", self->tunnelNonce, read, *key,
r->buffer))
return false;
if(!BEncodeMaybeReadDictEntry("p", self->pathid, read, *key, r->buffer))
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))
@ -144,7 +150,7 @@ namespace llarp
return false;
}
return nextHop == other.nextHop && commkey == other.commkey
&& pathid == other.pathid;
&& txid == other.txid && rxid == other.rxid;
}
struct LRCMFrameDecrypt
@ -156,15 +162,15 @@ namespace llarp
// decrypted record
LR_CommitRecord record;
// the actual hop
TransitHop hop;
TransitHop* hop;
LRCMFrameDecrypt(PathContext* ctx, Decrypter* dec,
const LR_CommitMessage* commit)
: decrypter(dec), context(ctx)
: decrypter(dec), context(ctx), hop(new TransitHop)
{
for(const auto& f : commit->frames)
frames.push_back(f);
hop.info.downstream = commit->remote;
hop->info.downstream = commit->remote;
}
~LRCMFrameDecrypt()
@ -177,19 +183,26 @@ namespace llarp
SendLRCM(void* user)
{
LRCMFrameDecrypt* self = static_cast< LRCMFrameDecrypt* >(user);
self->context->ForwardLRCM(self->hop.info.upstream, self->frames);
self->context->ForwardLRCM(self->hop->info.upstream, self->frames);
delete self;
}
static void
SendLRAM(void* user)
SendPathConfirm(void* user)
{
LRCMFrameDecrypt* self = static_cast< LRCMFrameDecrypt* >(user);
llarp::routing::PathConfirmMessage confirm(self->hop->lifetime);
if(!self->hop->SendRoutingMessage(&confirm, self->context->Router()))
{
llarp::Error("failed to send path confirmation for ", self->hop->info);
}
delete self;
}
static void
HandleDecrypted(llarp_buffer_t* buf, LRCMFrameDecrypt* self)
{
auto& info = self->hop.info;
auto& info = self->hop->info;
if(!buf)
{
llarp::Error("LRCM decrypt failed from ", info.downstream);
@ -206,7 +219,8 @@ namespace llarp
return;
}
info.pathID = self->record.pathid;
info.txID = self->record.txid;
info.rxID = self->record.rxid;
info.upstream = self->record.nextHop;
if(self->context->HasTransitHop(info))
{
@ -216,7 +230,7 @@ namespace llarp
}
// 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,
if(!DH(self->hop->pathKey, self->record.commkey,
self->context->EncryptionSecretKey(), self->record.tunnelNonce))
{
llarp::Error("LRCM DH Failed ", info);
@ -229,12 +243,12 @@ namespace llarp
{
llarp::Info("LRCM extended lifetime by ",
self->record.work->extendedLifetime, " seconds for ", info);
self->hop.lifetime += 1000 * self->record.work->extendedLifetime;
self->hop->lifetime += 1000 * self->record.work->extendedLifetime;
}
// TODO: check if we really want to accept it
self->hop.started = llarp_time_now_ms();
llarp::Info("Accepted ", self->hop.info);
self->hop->started = llarp_time_now_ms();
llarp::Info("Accepted ", self->hop->info);
self->context->PutTransitHop(self->hop);
size_t sz = self->frames.front().size();
@ -250,7 +264,7 @@ namespace llarp
// we are the farthest hop
llarp::Info("We are the farthest hop for ", info);
// send a LRAM down the path
llarp_logic_queue_job(self->context->Logic(), {self, &SendLRAM});
llarp_logic_queue_job(self->context->Logic(), {self, &SendPathConfirm});
}
else
{

@ -1,5 +1,8 @@
#include <llarp/bencode.hpp>
#include <llarp/messages/relay.hpp>
#include "router.hpp"
namespace llarp
{
RelayUpstreamMessage::RelayUpstreamMessage(const RouterID &from)
@ -7,6 +10,10 @@ namespace llarp
{
}
RelayUpstreamMessage::RelayUpstreamMessage() : ILinkMessage()
{
}
RelayUpstreamMessage::~RelayUpstreamMessage()
{
}
@ -35,25 +42,62 @@ namespace llarp
{
}
RelayDownstreamMessage::RelayDownstreamMessage() : ILinkMessage()
{
}
RelayDownstreamMessage::~RelayDownstreamMessage()
{
}
bool
RelayDownstreamMessage::BEncode(llarp_buffer_t *buf) const
{
// TODO: implement me
return false;
if(!bencode_start_dict(buf))
return false;
if(!BEncodeWriteDictMsgType(buf, "a", "d"))
return false;
if(!BEncodeWriteDictEntry("p", pathid, buf))
return false;
if(!BEncodeWriteDictInt(buf, "v", LLARP_PROTO_VERSION))
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)
{
return false;
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 *router) const
{
PathID_t id = pathid;
id.data_l()[0] = 0;
auto path = router->paths.GetByUpstream(remote, id);
if(path)
{
return path->HandleDownstream(X.Buffer(), Y, router);
}
else
{
llarp::Warn("No such path upstream=", remote, " pathid=", id);
}
return false;
}
}
} // namespace llarp

@ -54,7 +54,7 @@ llarp_router::HandleRecvLinkMessage(llarp_link_session *session,
bool
llarp_router::SendToOrQueue(const llarp::RouterID &remote,
llarp::ILinkMessage *msg)
const llarp::ILinkMessage *msg)
{
llarp_link *chosen = nullptr;
if(!outboundLink->has_session_to(outboundLink, remote))
@ -444,7 +444,7 @@ llarp_router::send_padded_message(llarp_link_session_iter *itr,
}
void
llarp_router::SendTo(llarp::RouterID remote, llarp::ILinkMessage *msg,
llarp_router::SendTo(llarp::RouterID remote, const llarp::ILinkMessage *msg,
llarp_link *link)
{
llarp_buffer_t buf =

@ -77,7 +77,7 @@ struct llarp_router
llarp_link *outboundLink = nullptr;
std::list< llarp_link * > inboundLinks;
typedef std::queue< llarp::ILinkMessage * > MessageQueue;
typedef std::queue< const llarp::ILinkMessage * > MessageQueue;
/// outbound message queue
std::map< llarp::RouterID, MessageQueue > outboundMesssageQueue;
@ -142,11 +142,11 @@ struct llarp_router
/// NOT threadsafe
/// MUST be called in the logic thread
bool
SendToOrQueue(const llarp::RouterID &remote, llarp::ILinkMessage *msg);
SendToOrQueue(const llarp::RouterID &remote, const llarp::ILinkMessage *msg);
/// sendto or drop
void
SendTo(llarp::RouterID remote, llarp::ILinkMessage *msg,
SendTo(llarp::RouterID remote, const llarp::ILinkMessage *msg,
llarp_link *chosen = nullptr);
/// manually flush outbound message queue for just 1 router

@ -0,0 +1,84 @@
#include <llarp/path.hpp>
#include "buffer.hpp"
#include "router.hpp"
namespace llarp
{
bool
TransitHop::Expired(llarp_time_t now) const
{
return now - started > lifetime;
}
TransitHopInfo::TransitHopInfo(const TransitHopInfo& other)
: pathID(other.pathID)
, upstream(other.upstream)
, downstream(other.downstream)
{
}
TransitHopInfo::TransitHopInfo(const RouterID& down,
const LR_CommitRecord& record)
: pathID(record.pathid), upstream(record.nextHop), downstream(down)
{
}
TransitHop::TransitHop(const TransitHop& other)
: info(other.info)
, pathKey(other.pathKey)
, started(other.started)
, lifetime(other.lifetime)
, version(other.version)
{
}
bool
TransitHop::SendRoutingMessage(const llarp::routing::IMessage* msg,
llarp_router* r)
{
byte_t tmp[MAX_LINK_MSG_SIZE / 2];
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
if(!msg->BEncode(&buf))
{
llarp::Error("failed to encode routing message");
return false;
}
TunnelNonce N;
N.Randomize();
// rewind
buf.sz = buf.cur - buf.base;
buf.cur = buf.base;
return HandleDownstream(buf, N, r);
}
bool
TransitHop::HandleDownstream(llarp_buffer_t buf, const TunnelNonce& Y,
llarp_router* r)
{
RelayDownstreamMessage* msg = new RelayDownstreamMessage;
msg->pathid = info.rxID;
msg->Y = Y;
r->crypto.xchacha20(buf, pathKey, Y);
msg->X = buf;
llarp::Info("relay ", msg->X.size(), " bytes downstream from ",
info.upstream, " to ", info.downstream);
return r->SendToOrQueue(info.downstream, msg);
}
bool
TransitHop::HandleUpstream(llarp_buffer_t buf, const TunnelNonce& Y,
llarp_router* r)
{
RelayUpstreamMessage* msg = new RelayUpstreamMessage;
msg->pathid = info.txID;
msg->Y = Y;
r->crypto.xchacha20(buf, pathKey, Y);
msg->X = buf;
llarp::Info("relay ", msg->X.size(), " bytes upstream from ",
info.downstream, " to ", info.upstream);
return r->SendToOrQueue(info.upstream, msg);
}
} // namespace llarp

@ -43,7 +43,8 @@ TEST_F(FrameTest, TestFrameCrypto)
LRCR record;
record.nextHop.Fill(1);
record.tunnelNonce.Fill(2);
record.pathid.Fill(3);
record.rxid.Fill(3);
record.txid.Fill(4);
auto buf = f.Buffer();
buf->cur = buf->base + EncryptedFrame::OverheadSize;

Loading…
Cancel
Save