1
1
Fork 0
mirror of https://github.com/oxen-io/lokinet synced 2023-12-14 06:53:00 +01:00

onion routing downstream traffic relaying works on testnet

This commit is contained in:
Jeff Becker 2018-06-22 09:59:28 -04:00
parent 2f8cde8e07
commit f2c42e4e5a
No known key found for this signature in database
GPG key ID: F357B3B42F6F9B05
15 changed files with 291 additions and 156 deletions

View file

@ -124,7 +124,6 @@ set(LIB_SRC
llarp/nodedb.cpp llarp/nodedb.cpp
llarp/path.cpp llarp/path.cpp
llarp/pathbuilder.cpp llarp/pathbuilder.cpp
llarp/path_confirm.cpp
llarp/proofofwork.cpp llarp/proofofwork.cpp
llarp/relay_ack.cpp llarp/relay_ack.cpp
llarp/relay_commit.cpp llarp/relay_commit.cpp
@ -136,6 +135,8 @@ set(LIB_SRC
llarp/testnet.c llarp/testnet.c
llarp/time.cpp llarp/time.cpp
llarp/timer.cpp llarp/timer.cpp
llarp/routing/message_parser.cpp
llarp/routing/path_confirm.cpp
vendor/cppbackport-master/lib/fs/rename.cpp vendor/cppbackport-master/lib/fs/rename.cpp
vendor/cppbackport-master/lib/fs/filestatus.cpp vendor/cppbackport-master/lib/fs/filestatus.cpp
vendor/cppbackport-master/lib/fs/filetype.cpp vendor/cppbackport-master/lib/fs/filetype.cpp

View file

@ -66,7 +66,7 @@ testnet-build: testnet-configure
testnet: testnet-build testnet: testnet-build
mkdir -p $(TESTNET_ROOT) mkdir -p $(TESTNET_ROOT)
python3 contrib/testnet/genconf.py --bin=$(REPO)/llarpd --svc=30 --clients=300 --dir=$(TESTNET_ROOT) --out $(TESTNET_CONF) python3 contrib/testnet/genconf.py --bin=$(REPO)/llarpd --svc=30 --clients=1 --dir=$(TESTNET_ROOT) --out $(TESTNET_CONF)
supervisord -n -d $(TESTNET_ROOT) -l $(TESTNET_LOG) -c $(TESTNET_CONF) supervisord -n -d $(TESTNET_ROOT) -l $(TESTNET_LOG) -c $(TESTNET_CONF)
test: debug-configure test: debug-configure

View file

@ -48,6 +48,23 @@ namespace llarp
return true; return true;
} }
template < typename Int_t >
bool
BEncodeMaybeReadDictInt(const char* k, Int_t& i, bool& read,
llarp_buffer_t key, llarp_buffer_t* buf)
{
if(llarp_buffer_eq(key, k))
{
if(!bencode_read_integer(buf, &i))
{
llarp::Warn("failed to decode key ", k);
return false;
}
read = true;
}
return true;
}
template < typename Item_t > template < typename Item_t >
bool bool
BEncodeMaybeReadVersion(const char* k, Item_t& item, uint64_t expect, BEncodeMaybeReadVersion(const char* k, Item_t& item, uint64_t expect,

View file

@ -46,7 +46,7 @@ typedef byte_t llarp_tunnel_nonce_t[TUNNONCESIZE];
/// PKE(result, publickey, secretkey, nonce) /// PKE(result, publickey, secretkey, nonce)
typedef bool (*llarp_path_dh_func)(byte_t *, byte_t *, byte_t *, byte_t *); typedef bool (*llarp_path_dh_func)(byte_t *, byte_t *, byte_t *, byte_t *);
/// TKE(result publickey, secretkey, nonce) /// TKE(result, publickey, secretkey, nonce)
typedef bool (*llarp_transport_dh_func)(byte_t *, byte_t *, byte_t *, byte_t *); typedef bool (*llarp_transport_dh_func)(byte_t *, byte_t *, byte_t *, byte_t *);
/// SD/SE(buffer, key, nonce) /// SD/SE(buffer, key, nonce)

View file

@ -1,7 +1,7 @@
#ifndef LLARP_MESSAGE_PATH_CONFIRM_HPP #ifndef LLARP_MESSAGE_PATH_CONFIRM_HPP
#define LLARP_MESSAGE_PATH_CONFIRM_HPP #define LLARP_MESSAGE_PATH_CONFIRM_HPP
#include <llarp/routing_message.hpp> #include <llarp/routing/message.hpp>
namespace llarp namespace llarp
{ {
@ -11,18 +11,21 @@ namespace llarp
{ {
uint64_t pathLifetime; uint64_t pathLifetime;
uint64_t pathCreated; uint64_t pathCreated;
PathConfirmMessage();
PathConfirmMessage(uint64_t lifetime); PathConfirmMessage(uint64_t lifetime);
~PathConfirmMessage(){}; ~PathConfirmMessage(){};
bool bool
BEncode(llarp_buffer_t* buf) const; BEncode(llarp_buffer_t* buf) const;
bool
DecodeKey(llarp_buffer_t key, llarp_buffer_t* val);
bool bool
BDecode(llarp_buffer_t* buf); BDecode(llarp_buffer_t* buf);
bool bool
HandleMessage(llarp_router* r) const; HandleMessage(IMessageHandler* h) const;
}; };
} // namespace routing } // namespace routing
} // namespace llarp } // namespace llarp

View file

@ -10,7 +10,8 @@
#include <llarp/messages/relay_commit.hpp> #include <llarp/messages/relay_commit.hpp>
#include <llarp/path_types.hpp> #include <llarp/path_types.hpp>
#include <llarp/router_id.hpp> #include <llarp/router_id.hpp>
#include <llarp/routing_message.hpp> #include <llarp/routing/handler.hpp>
#include <llarp/routing/message.hpp>
#include <list> #include <list>
#include <map> #include <map>
@ -173,7 +174,7 @@ namespace llarp
}; };
/// A path we made /// A path we made
struct Path : public IHopHandler struct Path : public IHopHandler, public llarp::routing::IMessageHandler
{ {
typedef std::vector< PathHopConfig > HopList; typedef std::vector< PathHopConfig > HopList;
HopList hops; HopList hops;
@ -207,6 +208,9 @@ namespace llarp
RouterID RouterID
Upstream() const; Upstream() const;
protected:
llarp::routing::InboundMessageParser m_InboundMessageParser;
}; };
enum PathBuildStatus enum PathBuildStatus

View file

@ -0,0 +1,14 @@
#ifndef LLARP_ROUTING_HANDLER_HPP
#define LLARP_ROUTING_HANDLER_HPP
namespace llarp
{
namespace routing
{
struct IMessageHandler
{
};
} // namespace routing
} // namespace llarp
#endif

View file

@ -0,0 +1,46 @@
#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 IMessageHandler;
struct IMessage
{
llarp::PathID_t from;
virtual ~IMessage(){};
virtual bool
BEncode(llarp_buffer_t* buf) const = 0;
virtual bool
DecodeKey(llarp_buffer_t key, llarp_buffer_t* buf) = 0;
virtual bool
HandleMessage(IMessageHandler* r) const = 0;
};
struct InboundMessageParser
{
InboundMessageParser();
bool
ParseMessageBuffer(llarp_buffer_t buf, IMessageHandler* handler);
private:
static bool
OnKey(dict_reader* r, llarp_buffer_t* key);
bool firstKey;
dict_reader reader;
IMessage* msg;
};
} // namespace routing
} // namespace llarp
#endif

View file

@ -1,30 +0,0 @@
#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

View file

@ -1397,7 +1397,7 @@ namespace iwp
UnmapAddr(addr); UnmapAddr(addr);
session *s = static_cast< session * >(itr->second.impl); session *s = static_cast< session * >(itr->second.impl);
s->done(); s->done();
m_sessions.erase(itr); m_sessions.erase(addr);
if(s->frames) if(s->frames)
{ {
llarp::Warn("session has ", s->frames, llarp::Warn("session has ", s->frames,

View file

@ -291,127 +291,128 @@ nodedb_async_load_rc(void *user)
llarp_logic_queue_job(job->logic, {job, &nodedb_inform_load_rc}); llarp_logic_queue_job(job->logic, {job, &nodedb_inform_load_rc});
} }
extern "C" { extern "C"
struct llarp_nodedb *
llarp_nodedb_new(struct llarp_crypto *crypto)
{ {
return new llarp_nodedb(crypto); struct llarp_nodedb *
} llarp_nodedb_new(struct llarp_crypto *crypto)
void
llarp_nodedb_free(struct llarp_nodedb **n)
{
if(*n)
{ {
auto i = *n; return new llarp_nodedb(crypto);
*n = nullptr;
i->Clear();
delete i;
} }
}
bool void
llarp_nodedb_ensure_dir(const char *dir) llarp_nodedb_free(struct llarp_nodedb **n)
{
fs::path path(dir);
std::error_code ec;
if(!fs::exists(dir, ec))
fs::create_directories(path, ec);
if(ec)
return false;
if(!fs::is_directory(path))
return false;
for(const char &ch : skiplist_subdirs)
{ {
std::string p; if(*n)
p += ch; {
fs::path sub = path / p; auto i = *n;
fs::create_directory(sub, ec); *n = nullptr;
i->Clear();
delete i;
}
}
bool
llarp_nodedb_ensure_dir(const char *dir)
{
fs::path path(dir);
std::error_code ec;
if(!fs::exists(dir, ec))
fs::create_directories(path, ec);
if(ec) if(ec)
return false; return false;
if(!fs::is_directory(path))
return false;
for(const char &ch : skiplist_subdirs)
{
std::string p;
p += ch;
fs::path sub = path / p;
fs::create_directory(sub, ec);
if(ec)
return false;
}
return true;
} }
return true;
}
ssize_t ssize_t
llarp_nodedb_load_dir(struct llarp_nodedb *n, const char *dir) llarp_nodedb_load_dir(struct llarp_nodedb *n, const char *dir)
{
std::error_code ec;
if(!fs::exists(dir, ec))
{ {
return -1; std::error_code ec;
if(!fs::exists(dir, ec))
{
return -1;
}
n->nodePath = dir;
return n->Load(dir);
} }
n->nodePath = dir;
return n->Load(dir);
}
void void
llarp_nodedb_async_verify(struct llarp_async_verify_rc *job) llarp_nodedb_async_verify(struct llarp_async_verify_rc *job)
{
// switch to crypto threadpool and continue with
// crypto_threadworker_verifyrc
llarp_threadpool_queue_job(job->cryptoworker,
{job, &crypto_threadworker_verifyrc});
}
void
llarp_nodedb_async_load_rc(struct llarp_async_load_rc *job)
{
// call in the disk io thread so we don't bog down the others
llarp_threadpool_queue_job(job->diskworker, {job, &nodedb_async_load_rc});
}
struct llarp_rc *
llarp_nodedb_get_rc(struct llarp_nodedb *n, const byte_t *pk)
{
if(n->Has(pk))
return n->getRC(pk);
else
return nullptr;
}
size_t
llarp_nodedb_num_loaded(struct llarp_nodedb *n)
{
return n->entries.size();
}
void
llarp_nodedb_select_random_hop(struct llarp_nodedb *n, struct llarp_rc *prev,
struct llarp_rc *result, size_t N)
{
/// TODO: check for "guard" status for N = 0?
auto sz = n->entries.size();
if(prev)
{ {
do // switch to crypto threadpool and continue with
// crypto_threadworker_verifyrc
llarp_threadpool_queue_job(job->cryptoworker,
{job, &crypto_threadworker_verifyrc});
}
void
llarp_nodedb_async_load_rc(struct llarp_async_load_rc *job)
{
// call in the disk io thread so we don't bog down the others
llarp_threadpool_queue_job(job->diskworker, {job, &nodedb_async_load_rc});
}
struct llarp_rc *
llarp_nodedb_get_rc(struct llarp_nodedb *n, const byte_t *pk)
{
if(n->Has(pk))
return n->getRC(pk);
else
return nullptr;
}
size_t
llarp_nodedb_num_loaded(struct llarp_nodedb *n)
{
return n->entries.size();
}
void
llarp_nodedb_select_random_hop(struct llarp_nodedb *n, struct llarp_rc *prev,
struct llarp_rc *result, size_t N)
{
/// TODO: check for "guard" status for N = 0?
auto sz = n->entries.size();
if(prev)
{
do
{
auto itr = n->entries.begin();
if(sz > 1)
{
auto idx = rand() % sz;
std::advance(itr, idx);
}
if(memcmp(prev->pubkey, itr->second.pubkey, PUBKEYSIZE) == 0)
continue;
llarp_rc_copy(result, &itr->second);
return;
} while(true);
}
else
{ {
auto itr = n->entries.begin(); auto itr = n->entries.begin();
if(sz > 1) if(sz > 1)
{ {
auto idx = rand() % (sz - 1); auto idx = rand() % sz;
std::advance(itr, idx); std::advance(itr, idx);
} }
if(memcmp(prev->pubkey, itr->second.pubkey, PUBKEYSIZE) == 0)
continue;
llarp_rc_copy(result, &itr->second); llarp_rc_copy(result, &itr->second);
return;
} while(true);
}
else
{
auto itr = n->entries.begin();
if(sz > 1)
{
auto idx = rand() % (sz - 1);
std::advance(itr, idx);
} }
llarp_rc_copy(result, &itr->second);
} }
}
} // end extern } // end extern

View file

@ -269,14 +269,9 @@ namespace llarp
Path::HandleDownstream(llarp_buffer_t buf, const TunnelNonce& Y, Path::HandleDownstream(llarp_buffer_t buf, const TunnelNonce& Y,
llarp_router* r) llarp_router* r)
{ {
size_t idx = hops.size() - 1; for(const auto& hop : hops)
while(idx >= 0)
{ {
r->crypto.xchacha20(buf, hops[idx].shared, Y); r->crypto.xchacha20(buf, hop.shared, Y);
if(idx)
idx--;
else
break;
} }
return HandleRoutingMessage(buf, r); return HandleRoutingMessage(buf, r);
} }
@ -284,7 +279,11 @@ namespace llarp
bool bool
Path::HandleRoutingMessage(llarp_buffer_t buf, llarp_router* r) Path::HandleRoutingMessage(llarp_buffer_t buf, llarp_router* r)
{ {
// TODO: implement me if(!m_InboundMessageParser.ParseMessageBuffer(buf, this))
{
llarp::Warn("Failed to parse inbound routing message");
return false;
}
return true; return true;
} }

View file

@ -47,10 +47,9 @@ namespace llarp
abort(); abort();
return; return;
} }
++ctx->idx; ++ctx->idx;
bool isFarthestHop = ctx->idx == ctx->path->hops.size() - 1; bool isFarthestHop = ctx->idx == ctx->path->hops.size();
if(isFarthestHop) if(isFarthestHop)
{ {

View file

@ -0,0 +1,69 @@
#include <llarp/messages/path_confirm.hpp>
#include <llarp/routing/message.hpp>
namespace llarp
{
namespace routing
{
InboundMessageParser::InboundMessageParser()
{
reader.user = this;
reader.on_key = &OnKey;
firstKey = false;
}
bool
InboundMessageParser::OnKey(dict_reader* r, llarp_buffer_t* key)
{
InboundMessageParser* self =
static_cast< InboundMessageParser* >(r->user);
if(key == nullptr && self->firstKey)
{
// empty dict
return false;
}
if(!key)
return true;
if(self->firstKey)
{
llarp_buffer_t strbuf;
if(!llarp_buffer_eq(*key, "A"))
return false;
if(!bencode_read_string(r->buffer, &strbuf))
return false;
if(strbuf.sz != 1)
return false;
switch(*strbuf.cur)
{
case 'P':
self->msg = new PathConfirmMessage;
break;
default:
llarp::Error("invalid routing message id: ", *strbuf.cur);
}
self->firstKey = false;
return self->msg != nullptr;
}
else
{
return self->msg->DecodeKey(*key, r->buffer);
}
}
bool
InboundMessageParser::ParseMessageBuffer(llarp_buffer_t buf,
IMessageHandler* h)
{
bool result = false;
msg = nullptr;
firstKey = true;
if(bencode_read_dict(&buf, &reader))
{
result = msg->HandleMessage(h);
delete msg;
}
return result;
}
} // namespace routing
} // namespace llarp

View file

@ -1,16 +1,32 @@
#include <llarp/time.h> #include <llarp/time.h>
#include <llarp/bencode.hpp> #include <llarp/bencode.hpp>
#include <llarp/messages/path_confirm.hpp> #include <llarp/messages/path_confirm.hpp>
#include <llarp/routing/handler.hpp>
namespace llarp namespace llarp
{ {
namespace routing namespace routing
{ {
PathConfirmMessage::PathConfirmMessage() : pathLifetime(0), pathCreated(0)
{
}
PathConfirmMessage::PathConfirmMessage(uint64_t lifetime) PathConfirmMessage::PathConfirmMessage(uint64_t lifetime)
: pathLifetime(lifetime), pathCreated(llarp_time_now_ms()) : pathLifetime(lifetime), pathCreated(llarp_time_now_ms())
{ {
} }
bool
PathConfirmMessage::DecodeKey(llarp_buffer_t key, llarp_buffer_t* val)
{
bool read = false;
if(!BEncodeMaybeReadDictInt("L", pathLifetime, read, key, val))
return false;
if(!BEncodeMaybeReadDictInt("S", pathCreated, read, key, val))
return false;
return read;
}
bool bool
PathConfirmMessage::BEncode(llarp_buffer_t* buf) const PathConfirmMessage::BEncode(llarp_buffer_t* buf) const
{ {
@ -26,14 +42,10 @@ namespace llarp
} }
bool bool
PathConfirmMessage::BDecode(llarp_buffer_t* buf) PathConfirmMessage::HandleMessage(IMessageHandler* h) const
{
return false;
}
bool
PathConfirmMessage::HandleMessage(llarp_router* r) const
{ {
llarp::Info("got path confirm created=", pathCreated,
" lifetime=", pathLifetime);
return true; return true;
} }