* add path building management

* fix bug in iwp that caused crash
This commit is contained in:
Jeff Becker 2018-06-25 11:12:08 -04:00
parent ce643cc8e0
commit da22f306e0
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05
28 changed files with 1030 additions and 707 deletions

View File

@ -54,6 +54,9 @@
"__config": "cpp",
"__nullptr": "cpp",
"algorithm": "cpp",
"io": "cpp"
"io": "cpp",
"strstream": "cpp",
"numeric": "cpp",
"valarray": "cpp"
}
}

View File

@ -125,6 +125,7 @@ set(LIB_SRC
llarp/nodedb.cpp
llarp/path.cpp
llarp/pathbuilder.cpp
llarp/pathset.cpp
llarp/proofofwork.cpp
llarp/relay_ack.cpp
llarp/relay_commit.cpp

View File

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

View File

@ -21,21 +21,22 @@ handle_signal(int sig)
#include <llarp/router_contact.h>
#include <llarp/time.h>
#include <fstream>
#include "fs.hpp"
#include "buffer.hpp"
#include "crypto.hpp"
#include "fs.hpp"
#include "router.hpp"
bool printNode(struct llarp_nodedb_iter *iter) {
bool
printNode(struct llarp_nodedb_iter *iter)
{
char ftmp[68] = {0};
const char *hexname =
llarp::HexEncode< llarp::PubKey, decltype(ftmp) >(iter->rc->pubkey, ftmp);
llarp::HexEncode< llarp::PubKey, decltype(ftmp) >(iter->rc->pubkey, ftmp);
printf("[%zu]=>[%s]\n", iter->index, hexname);
return false;
}
int
main(int argc, char *argv[])
{
@ -61,9 +62,9 @@ main(int argc, char *argv[])
"\n");
return 0;
}
bool genMode = false;
bool updMode = false;
bool listMode = false;
bool genMode = false;
bool updMode = false;
bool listMode = false;
bool importMode = false;
bool exportMode = false;
int c;
@ -71,8 +72,8 @@ main(int argc, char *argv[])
char defaultConfName[] = "daemon.ini";
conffname = defaultConfName;
char *rcfname;
char defaultRcName[] = "other.signed";
rcfname = defaultRcName;
char defaultRcName[] = "other.signed";
rcfname = defaultRcName;
bool haveRequiredOptions = false;
while(1)
{
@ -97,49 +98,51 @@ main(int argc, char *argv[])
break;
case 'l':
haveRequiredOptions = true;
listMode = true;
listMode = true;
break;
case 'i':
// printf ("option -g with value `%s'\n", optarg);
rcfname = optarg;
rcfname = optarg;
haveRequiredOptions = true;
importMode = true;
importMode = true;
break;
case 'e':
// printf ("option -g with value `%s'\n", optarg);
rcfname = optarg;
rcfname = optarg;
haveRequiredOptions = true;
exportMode = true;
exportMode = true;
break;
case 'g':
// printf ("option -g with value `%s'\n", optarg);
rcfname = optarg;
rcfname = optarg;
haveRequiredOptions = true;
genMode = true;
genMode = true;
break;
case 'u':
// printf ("option -u with value `%s'\n", optarg);
rcfname = optarg;
rcfname = optarg;
haveRequiredOptions = true;
updMode = true;
updMode = true;
break;
default:
abort();
}
}
if (!haveRequiredOptions) {
if(!haveRequiredOptions)
{
llarp::Error("Parameters dont all have their required parameters.\n");
return 0;
}
printf("parsed options\n");
if(!genMode && !updMode && !listMode &&!importMode && !exportMode)
if(!genMode && !updMode && !listMode && !importMode && !exportMode)
{
llarp::Error("I don't know what to do, no generate or update parameter\n");
return 0;
}
ctx = llarp_main_init(conffname, !TESTNET);
if (!ctx) {
if(!ctx)
{
llarp::Error("Cant set up context");
return 0;
}
@ -162,10 +165,12 @@ main(int argc, char *argv[])
llarp_crypto crypt;
llarp_crypto_libsodium_init(&crypt);
// which is in daemon.ini config: router.encryption-privkey (defaults "encryption.key")
// which is in daemon.ini config: router.encryption-privkey (defaults
// "encryption.key")
fs::path encryption_keyfile = "encryption.key";
llarp::SecretKey encryption;
llarp_findOrCreateEncryption(&crypt, encryption_keyfile.c_str(), &encryption);
llarp_findOrCreateEncryption(&crypt, encryption_keyfile.c_str(),
&encryption);
llarp_rc_set_pubenckey(&tmp, llarp::seckey_topublic(encryption));
// get identity public sig key
@ -206,33 +211,37 @@ main(int argc, char *argv[])
// write file
llarp_rc_write(&tmp, our_rc_file_out.c_str());
}
if (listMode) {
if(listMode)
{
llarp_main_loadDatabase(ctx);
llarp_nodedb_iter iter;
iter.visit = printNode;
llarp_main_iterateDatabase(ctx, iter);
}
if (importMode) {
if(importMode)
{
llarp_main_loadDatabase(ctx);
llarp::Info("Loading ", rcfname);
llarp_rc *rc = llarp_rc_read(rcfname);
if (!rc)
if(!rc)
{
llarp::Error("Can't load RC");
return 0;
}
llarp_main_putDatabase(ctx, rc);
}
if (exportMode) {
if(exportMode)
{
llarp_main_loadDatabase(ctx);
//llarp::Info("Looking for string: ", rcfname);
// llarp::Info("Looking for string: ", rcfname);
llarp::PubKey binaryPK;
llarp::HexDecode(rcfname, binaryPK.data());
llarp::Info("Looking for binary: ", binaryPK);
struct llarp_rc *rc = llarp_main_getDatabase(ctx, binaryPK.data());
if (!rc) {
if(!rc)
{
llarp::Error("Can't load RC from database");
}
std::string filename(rcfname);
@ -241,5 +250,5 @@ main(int argc, char *argv[])
llarp_rc_write(rc, filename.c_str());
}
llarp_main_free(ctx);
return 1; // success
return 1; // success
}

View File

@ -39,7 +39,6 @@ llarp_main_loadDatabase(struct llarp_main *ptr);
int
llarp_main_iterateDatabase(struct llarp_main *ptr, struct llarp_nodedb_iter i);
/// put RC into nodeDB
bool
llarp_main_putDatabase(struct llarp_main *ptr, struct llarp_rc *rc);
@ -47,7 +46,6 @@ llarp_main_putDatabase(struct llarp_main *ptr, struct llarp_rc *rc);
struct llarp_rc *
llarp_main_getDatabase(struct llarp_main *ptr, byte_t *pk);
void
llarp_main_free(struct llarp_main *ptr);

View File

@ -83,6 +83,14 @@ namespace llarp
b[idx] = f;
}
bool
IsZero() const
{
AlignedBuffer< sz > b;
b.Zero();
return memcmp(l, b.l, sz) == 0;
}
void
Zero()
{

View File

@ -30,9 +30,6 @@ namespace llarp
{
}
bool
IsZero() const;
Key_t
operator^(const Key_t& other) const
{
@ -49,8 +46,6 @@ namespace llarp
}
};
extern Key_t ZeroKey;
struct Node
{
llarp_rc* rc;

View File

@ -1,7 +1,7 @@
#ifndef LLARP_ENCODE_HPP
#define LLARP_ENCODE_HPP
#include <cstdlib>
#include <stdint.h>
#include <cstdlib>
namespace llarp
{
@ -28,8 +28,10 @@ namespace llarp
return &stack[0];
}
int char2int(char input);
void HexDecode(const char* src, uint8_t* target);
int
char2int(char input);
void
HexDecode(const char* src, uint8_t* target);
}
#endif

View File

@ -11,7 +11,10 @@
namespace llarp
{
// forward declare
struct PathContext;
namespace path
{
struct PathContext;
}
struct LR_CommitRecord
{
@ -67,7 +70,7 @@ namespace llarp
HandleMessage(llarp_router *router) const;
bool
AsyncDecrypt(PathContext *context) const;
AsyncDecrypt(llarp::path::PathContext *context) const;
};
} // namespace llarp

View File

@ -4,6 +4,9 @@
#include <llarp/router_contact.h>
#define MAXHOPS (8)
#define DEFAULT_PATH_LIFETIME (10 * 60 * 1000)
#define PATH_BUILD_TIMEOUT (30 * 1000)
#ifdef __cplusplus
extern "C" {
#endif

View File

@ -5,10 +5,12 @@
#include <llarp/time.h>
#include <llarp/aligned.hpp>
#include <llarp/crypto.hpp>
#include <llarp/dht.hpp>
#include <llarp/endpoint.hpp>
#include <llarp/messages/relay.hpp>
#include <llarp/messages/relay_commit.hpp>
#include <llarp/path_types.hpp>
#include <llarp/pathset.hpp>
#include <llarp/router_id.hpp>
#include <llarp/routing/handler.hpp>
#include <llarp/routing/message.hpp>
@ -19,292 +21,315 @@
#include <unordered_map>
#include <vector>
#define DEFAULT_PATH_LIFETIME (10 * 60 * 1000)
namespace llarp
{
struct TransitHopInfo
namespace path
{
TransitHopInfo() = default;
TransitHopInfo(const TransitHopInfo& other);
TransitHopInfo(const RouterID& down, const LR_CommitRecord& record);
PathID_t txID, rxID;
RouterID upstream;
RouterID downstream;
friend std::ostream&
operator<<(std::ostream& out, const TransitHopInfo& info)
struct TransitHopInfo
{
out << "<tx=" << info.txID << " rx=" << info.rxID;
out << " upstream=" << info.upstream << " downstream=" << info.downstream;
return out << ">";
}
TransitHopInfo() = default;
TransitHopInfo(const TransitHopInfo& other);
TransitHopInfo(const RouterID& down, const LR_CommitRecord& record);
bool
operator==(const TransitHopInfo& other) const
{
return txID == other.txID && rxID == other.rxID
&& upstream == other.upstream && downstream == other.downstream;
}
PathID_t txID, rxID;
RouterID upstream;
RouterID downstream;
bool
operator!=(const TransitHopInfo& other) const
{
return !(*this == other);
}
friend std::ostream&
operator<<(std::ostream& out, const TransitHopInfo& info)
{
out << "<tx=" << info.txID << " rx=" << info.rxID;
out << " upstream=" << info.upstream
<< " downstream=" << info.downstream;
return out << ">";
}
bool
operator<(const TransitHopInfo& other) const
{
return txID < other.txID || rxID < other.rxID || upstream < other.upstream
|| downstream < other.downstream;
}
bool
operator==(const TransitHopInfo& other) const
{
return txID == other.txID && rxID == other.rxID
&& upstream == other.upstream && downstream == other.downstream;
}
struct Hash
bool
operator!=(const TransitHopInfo& other) const
{
return !(*this == other);
}
bool
operator<(const TransitHopInfo& other) const
{
return txID < other.txID || rxID < other.rxID
|| upstream < other.upstream || downstream < other.downstream;
}
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.txID, sizeof(std::size_t));
memcpy(&idx3, a.rxID, sizeof(std::size_t));
return idx0 ^ idx1 ^ idx2;
}
};
};
struct PathIDHash
{
std::size_t
operator()(TransitHopInfo const& a) const
operator()(const PathID_t& 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.txID, sizeof(std::size_t));
memcpy(&idx3, a.rxID, sizeof(std::size_t));
return idx0 ^ idx1 ^ idx2;
std::size_t idx0;
memcpy(&idx0, a, sizeof(std::size_t));
return idx0;
}
};
};
struct PathIDHash
{
std::size_t
operator()(const PathID_t& a) const
struct IHopHandler
{
std::size_t idx0;
memcpy(&idx0, a, sizeof(std::size_t));
return idx0;
}
};
virtual ~IHopHandler(){};
struct IHopHandler
{
virtual ~IHopHandler(){};
virtual bool
Expired(llarp_time_t now) const = 0;
virtual bool
Expired(llarp_time_t now) const = 0;
virtual bool
SendRoutingMessage(const llarp::routing::IMessage* msg,
llarp_router* r) = 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,
// handle data in upstream direction
virtual bool
HandleUpstream(llarp_buffer_t X, const TunnelNonce& Y,
llarp_router* r) = 0;
};
struct TransitHop : public IHopHandler
{
TransitHop() = default;
// handle data in downstream direction
virtual bool
HandleDownstream(llarp_buffer_t X, const TunnelNonce& Y,
llarp_router* r) = 0;
};
TransitHop(const TransitHop& other);
TransitHopInfo info;
SharedSecret pathKey;
llarp_time_t started = 0;
// 10 minutes default
llarp_time_t lifetime = DEFAULT_PATH_LIFETIME;
llarp_proto_version_t version;
friend std::ostream&
operator<<(std::ostream& out, const TransitHop& h)
struct TransitHop : public IHopHandler
{
return out << "[TransitHop " << h.info << " started=" << h.started
<< " lifetime=" << h.lifetime << "]";
}
TransitHop() = default;
bool
Expired(llarp_time_t now) const;
TransitHop(const TransitHop& other);
bool
SendRoutingMessage(const llarp::routing::IMessage* msg, llarp_router* r);
TransitHopInfo info;
SharedSecret pathKey;
llarp_time_t started = 0;
// 10 minutes default
llarp_time_t lifetime = DEFAULT_PATH_LIFETIME;
llarp_proto_version_t version;
// handle data in upstream direction
bool
HandleUpstream(llarp_buffer_t X, const TunnelNonce& Y, llarp_router* r);
friend std::ostream&
operator<<(std::ostream& out, const TransitHop& h)
{
return out << "[TransitHop " << h.info << " started=" << h.started
<< " lifetime=" << h.lifetime << "]";
}
// handle data in downstream direction
bool
HandleDownstream(llarp_buffer_t X, const TunnelNonce& Y, llarp_router* r);
};
bool
Expired(llarp_time_t now) const;
/// configuration for a single hop when building a path
struct PathHopConfig
{
/// path id
PathID_t txID, rxID;
// router contact of router
llarp_rc router;
// temp public encryption key
SecretKey commkey;
/// shared secret at this hop
SharedSecret shared;
/// next hop's router id
RouterID upstream;
/// nonce for key exchange
TunnelNonce nonce;
// lifetime
llarp_time_t lifetime = DEFAULT_PATH_LIFETIME;
bool
SendRoutingMessage(const llarp::routing::IMessage* msg, llarp_router* r);
~PathHopConfig();
PathHopConfig();
};
// handle data in upstream direction
bool
HandleUpstream(llarp_buffer_t X, const TunnelNonce& Y, llarp_router* r);
enum PathStatus
{
ePathBuilding,
ePathEstablished,
ePathTimeout,
ePathExpired
};
// handle data in downstream direction
bool
HandleDownstream(llarp_buffer_t X, const TunnelNonce& Y, llarp_router* r);
};
/// A path we made
struct Path : public IHopHandler, public llarp::routing::IMessageHandler
{
typedef std::vector< PathHopConfig > HopList;
HopList hops;
llarp_time_t buildStarted;
PathStatus status;
/// configuration for a single hop when building a path
struct PathHopConfig
{
/// path id
PathID_t txID, rxID;
// router contact of router
llarp_rc router;
// temp public encryption key
SecretKey commkey;
/// shared secret at this hop
SharedSecret shared;
/// next hop's router id
RouterID upstream;
/// nonce for key exchange
TunnelNonce nonce;
// lifetime
llarp_time_t lifetime = DEFAULT_PATH_LIFETIME;
Path(llarp_path_hops* path);
~PathHopConfig();
PathHopConfig();
};
bool
Expired(llarp_time_t now) const;
/// A path we made
struct Path : public IHopHandler, public llarp::routing::IMessageHandler
{
typedef std::function< void(Path*) > BuildResultHookFunc;
typedef std::vector< PathHopConfig > HopList;
HopList hops;
llarp_time_t buildStarted;
PathStatus status;
bool
SendRoutingMessage(const llarp::routing::IMessage* msg, llarp_router* r);
Path(llarp_path_hops* path);
bool
HandleRoutingMessage(llarp_buffer_t buf, llarp_router* r);
void
SetBuildResultHook(BuildResultHookFunc func);
bool
HandleHiddenServiceData(llarp_buffer_t buf);
bool
Expired(llarp_time_t now) const;
// handle data in upstream direction
bool
HandleUpstream(llarp_buffer_t X, const TunnelNonce& Y, llarp_router* r);
bool
SendRoutingMessage(const llarp::routing::IMessage* msg, llarp_router* r);
// handle data in downstream direction
bool
HandleDownstream(llarp_buffer_t X, const TunnelNonce& Y, llarp_router* r);
bool
HandlePathConfirmMessage(const llarp::routing::PathConfirmMessage* msg);
// Is this deprecated?
const PathID_t&
TXID() const;
bool
HandlePathLatencyMessage(const llarp::routing::PathLatencyMessage* msg);
const PathID_t&
RXID() const;
bool
HandleDHTMessage(const llarp::dht::IMessage* msg);
RouterID
Upstream() const;
bool
HandleRoutingMessage(llarp_buffer_t buf, llarp_router* r);
protected:
llarp::routing::InboundMessageParser m_InboundMessageParser;
};
bool
HandleHiddenServiceData(llarp_buffer_t buf);
enum PathBuildStatus
{
ePathBuildSuccess,
ePathBuildTimeout,
ePathBuildReject
};
// handle data in upstream direction
bool
HandleUpstream(llarp_buffer_t X, const TunnelNonce& Y, llarp_router* r);
struct PathContext
{
PathContext(llarp_router* router);
~PathContext();
// handle data in downstream direction
bool
HandleDownstream(llarp_buffer_t X, const TunnelNonce& Y, llarp_router* r);
/// called from router tick function
void
ExpirePaths();
// Is this deprecated?
// nope not deprecated :^DDDD
const PathID_t&
TXID() const;
void
AllowTransit();
void
RejectTransit();
const PathID_t&
RXID() const;
bool
AllowingTransit() const;
RouterID
Upstream() const;
bool
HasTransitHop(const TransitHopInfo& info);
protected:
llarp::routing::InboundMessageParser m_InboundMessageParser;
bool
HandleRelayCommit(const LR_CommitMessage* msg);
private:
BuildResultHookFunc m_BuiltHook;
};
void
PutTransitHop(TransitHop* hop);
enum PathBuildStatus
{
ePathBuildSuccess,
ePathBuildTimeout,
ePathBuildReject
};
IHopHandler*
GetByUpstream(const RouterID& id, const PathID_t& path);
struct PathContext
{
PathContext(llarp_router* router);
~PathContext();
IHopHandler*
GetByDownstream(const RouterID& id, const PathID_t& path);
/// called from router tick function
void
ExpirePaths();
bool
ForwardLRCM(const RouterID& nextHop, std::deque< EncryptedFrame >& frames);
/// called from router tick function
/// builds all paths we need to build at current tick
void
BuildPaths();
bool
HopIsUs(const PubKey& k) const;
/// track a path builder with this context
void
AddPathBuilder(llarp_pathbuilder_context* set);
bool
HandleLRUM(const RelayUpstreamMessage* msg);
void
AllowTransit();
void
RejectTransit();
bool
HandleLRDM(const RelayDownstreamMessage* msg);
bool
AllowingTransit() const;
void
AddOwnPath(Path* p);
bool
HasTransitHop(const TransitHopInfo& info);
typedef std::multimap< PathID_t, TransitHop* > TransitHopsMap_t;
bool
HandleRelayCommit(const LR_CommitMessage* msg);
typedef std::pair< std::mutex, TransitHopsMap_t > SyncTransitMap_t;
void
PutTransitHop(TransitHop* hop);
typedef std::map< PathID_t, Path* > OwnedPathsMap_t;
IHopHandler*
GetByUpstream(const RouterID& id, const PathID_t& path);
typedef std::pair< std::mutex, OwnedPathsMap_t > SyncOwnedPathsMap_t;
IHopHandler*
GetByDownstream(const RouterID& id, const PathID_t& path);
llarp_threadpool*
Worker();
bool
ForwardLRCM(const RouterID& nextHop,
std::deque< EncryptedFrame >& frames);
llarp_crypto*
Crypto();
bool
HopIsUs(const PubKey& k) const;
llarp_logic*
Logic();
bool
HandleLRUM(const RelayUpstreamMessage* msg);
llarp_router*
Router();
bool
HandleLRDM(const RelayDownstreamMessage* msg);
byte_t*
EncryptionSecretKey();
void
AddOwnPath(PathSet* set, Path* p);
const byte_t*
OurRouterID() const;
typedef std::multimap< PathID_t, TransitHop* > TransitHopsMap_t;
private:
llarp_router* m_Router;
SyncTransitMap_t m_TransitPaths;
SyncTransitMap_t m_Paths;
SyncOwnedPathsMap_t m_OurPaths;
typedef std::pair< std::mutex, TransitHopsMap_t > SyncTransitMap_t;
bool m_AllowTransit;
};
// maps path id -> pathset owner of path
typedef std::map< PathID_t, PathSet* > OwnedPathsMap_t;
typedef std::pair< std::mutex, OwnedPathsMap_t > SyncOwnedPathsMap_t;
llarp_threadpool*
Worker();
llarp_crypto*
Crypto();
llarp_logic*
Logic();
llarp_router*
Router();
byte_t*
EncryptionSecretKey();
const byte_t*
OurRouterID() const;
private:
llarp_router* m_Router;
SyncTransitMap_t m_TransitPaths;
SyncTransitMap_t m_Paths;
SyncOwnedPathsMap_t m_OurPaths;
std::list< llarp_pathbuilder_context* > m_PathBuilders;
bool m_AllowTransit;
};
} // namespace path
} // namespace llarp
#endif

63
include/llarp/pathset.hpp Normal file
View File

@ -0,0 +1,63 @@
#ifndef LLARP_PATHSET_HPP
#define LLARP_PATHSET_HPP
#include <llarp/path_types.hpp>
#include <map>
#include <tuple>
namespace llarp
{
namespace path
{
enum PathStatus
{
ePathBuilding,
ePathEstablished,
ePathTimeout,
ePathExpired
};
// forward declare
struct Path;
/// a set of paths owned by an entity
struct PathSet
{
/// construct
/// @params numPaths the number of paths to maintain
PathSet(size_t numPaths);
void
RemovePath(Path* path);
void
HandlePathBuilt(Path* path);
void
AddPath(Path* path);
Path*
GetByUpstream(const RouterID& remote, const PathID_t& rxid);
void
ExpirePaths(llarp_time_t now);
size_t
NumInStatus(PathStatus st) const;
/// return true if we should build another path
bool
ShouldBuildMore() const;
private:
typedef std::map< PathID_t, Path* > PathMap_t;
// (tx,rx)
typedef std::tuple< PathMap_t, PathMap_t > PathContainer_t;
size_t m_NumPaths;
PathContainer_t m_Paths;
};
} // namespace path
} // namespace llarp
#endif

View File

@ -2,6 +2,9 @@
#define LLARP_ROUTING_HANDLER_HPP
#include <llarp/buffer.h>
#include <llarp/dht.hpp>
#include <llarp/messages/path_confirm.hpp>
#include <llarp/messages/path_latency.hpp>
namespace llarp
{
@ -12,6 +15,15 @@ namespace llarp
{
virtual bool
HandleHiddenServiceData(llarp_buffer_t buf) = 0;
virtual bool
HandlePathConfirmMessage(const PathConfirmMessage* msg) = 0;
virtual bool
HandlePathLatencyMessage(const PathLatencyMessage* msg) = 0;
virtual bool
HandleDHTMessage(const llarp::dht::IMessage* msg) = 0;
};
} // namespace routing
} // namespace llarp

View File

@ -7,7 +7,6 @@ namespace llarp
{
namespace api
{
bool
CreateSessionMessage::DecodeParams(llarp_buffer_t *buf)
{

View File

@ -29,7 +29,7 @@ namespace llarp
bool
Context::ReloadConfig()
{
//llarp::Info("loading config at ", configfile);
// llarp::Info("loading config at ", configfile);
if(llarp_load_config(config, configfile.c_str()))
{
llarp_free_config(&config);
@ -94,7 +94,7 @@ namespace llarp
llarp::Error("nodedb_dir is incorrect");
return 0;
}
//llarp::Info("nodedb_dir [", nodedb_dir, "] configured!");
// llarp::Info("nodedb_dir [", nodedb_dir, "] configured!");
ssize_t loaded = llarp_nodedb_load_dir(nodedb, nodedb_dir);
llarp::Info("nodedb_dir loaded ", loaded, " RCs from [", nodedb_dir, "]");
if(loaded < 0)

View File

@ -81,14 +81,6 @@ namespace llarp
namespace dht
{
Key_t ZeroKey;
bool
Key_t::IsZero() const
{
return memcmp(l, ZeroKey.l, 32) == 0;
}
GotRouterMessage::~GotRouterMessage()
{
for(auto &rc : R)

View File

@ -3,8 +3,8 @@
namespace llarp
{
int char2int(char input)
int
char2int(char input)
{
if(input >= '0' && input <= '9')
return input - '0';
@ -15,13 +15,13 @@ namespace llarp
throw std::invalid_argument("Invalid input string");
}
void HexDecode(const char* src, uint8_t* target)
void
HexDecode(const char* src, uint8_t* target)
{
while(*src && src[1])
{
*(target++) = char2int(*src)*16 + char2int(src[1]);
*(target++) = char2int(*src) * 16 + char2int(src[1]);
src += 2;
}
}
}

View File

@ -1933,6 +1933,7 @@ namespace iwp
delete link;
return;
}
link->frame.alive();
link->serv->put_session(link->addr, link);
llarp::Debug("send introack to ", link->addr, " via ", link->serv->addr);
if(llarp_ev_udp_sendto(link->udp, link->addr, i->buf, i->sz) == -1)

View File

@ -47,23 +47,23 @@ struct llarp_nodedb
return entries.find(pk) != entries.end();
}
/*
bool
Has(const byte_t *pk)
{
llarp::PubKey test(pk);
auto itr = this->entries.begin();
while(itr != this->entries.end())
/*
bool
Has(const byte_t *pk)
{
llarp::Info("Has byte_t [", test.size(), "] vs [", itr->first.size(), "]");
if (memcmp(test.data(), itr->first.data(), 32) == 0) {
llarp::Info("Match");
llarp::PubKey test(pk);
auto itr = this->entries.begin();
while(itr != this->entries.end())
{
llarp::Info("Has byte_t [", test.size(), "] vs [", itr->first.size(),
"]"); if (memcmp(test.data(), itr->first.data(), 32) == 0) {
llarp::Info("Match");
}
itr++;
}
itr++;
return entries.find(pk) != entries.end();
}
return entries.find(pk) != entries.end();
}
*/
*/
bool
pubKeyExists(llarp_rc *rc)
@ -185,7 +185,7 @@ struct llarp_nodedb
auto itr = i.begin();
while(itr != itr.end())
{
if (fs::is_regular_file(itr->symlink_status()) && loadfile(*itr))
if(fs::is_regular_file(itr->symlink_status()) && loadfile(*itr))
sz++;
++itr;
@ -198,12 +198,13 @@ struct llarp_nodedb
{
#if __APPLE__ && __MACH__
// skip .DS_Store files
if (strstr(fpath.c_str(), ".DS_Store") != 0) {
if(strstr(fpath.c_str(), ".DS_Store") != 0)
{
return false;
}
#endif
llarp_rc *rc = llarp_rc_read(fpath.c_str());
if (!rc)
if(!rc)
{
llarp::Error("Signature read failed", fpath);
return false;
@ -218,8 +219,10 @@ struct llarp_nodedb
return true;
}
bool iterate(struct llarp_nodedb_iter i) {
i.index = 0;
bool
iterate(struct llarp_nodedb_iter i)
{
i.index = 0;
auto itr = entries.begin();
while(itr != entries.end())
{
@ -372,12 +375,14 @@ llarp_nodedb_load_dir(struct llarp_nodedb *n, const char *dir)
}
bool
llarp_nodedb_put_rc(struct llarp_nodedb *n, struct llarp_rc *rc) {
llarp_nodedb_put_rc(struct llarp_nodedb *n, struct llarp_rc *rc)
{
return n->setRC(rc);
}
int
llarp_nodedb_iterate_all(struct llarp_nodedb *n, struct llarp_nodedb_iter i) {
llarp_nodedb_iterate_all(struct llarp_nodedb *n, struct llarp_nodedb_iter i)
{
n->iterate(i);
return n->entries.size();
}
@ -401,7 +406,7 @@ llarp_nodedb_async_load_rc(struct llarp_async_load_rc *job)
struct llarp_rc *
llarp_nodedb_get_rc(struct llarp_nodedb *n, const byte_t *pk)
{
//llarp::Info("llarp_nodedb_get_rc [", pk, "]");
// llarp::Info("llarp_nodedb_get_rc [", pk, "]");
if(n->Has(pk))
return n->getRC(pk);
else

View File

@ -2,312 +2,403 @@
#include <llarp/encrypted_frame.hpp>
#include <llarp/path.hpp>
#include "buffer.hpp"
#include "pathbuilder.hpp"
#include "router.hpp"
namespace llarp
{
PathContext::PathContext(llarp_router* router)
: m_Router(router), m_AllowTransit(false)
namespace path
{
}
PathContext::~PathContext()
{
}
void
PathContext::AllowTransit()
{
m_AllowTransit = true;
}
bool
PathContext::AllowingTransit() const
{
return m_AllowTransit;
}
llarp_threadpool*
PathContext::Worker()
{
return m_Router->tp;
}
llarp_crypto*
PathContext::Crypto()
{
return &m_Router->crypto;
}
llarp_logic*
PathContext::Logic()
{
return m_Router->logic;
}
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)
{
llarp::Info("fowarding LRCM to ", nextHop);
LR_CommitMessage* msg = new LR_CommitMessage;
while(frames.size())
PathContext::PathContext(llarp_router* router)
: m_Router(router), m_AllowTransit(false)
{
msg->frames.push_back(frames.front());
frames.pop_front();
}
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 range = map.second.equal_range(k);
for(auto i = range.first; i != range.second; ++i)
{
if(check(i->second))
return i->second;
}
return nullptr;
}
template < typename Map_t, typename Key_t, typename CheckValue_t >
bool
MapHas(Map_t& map, const Key_t& k, CheckValue_t check)
{
std::unique_lock< std::mutex > lock(map.first);
auto range = map.second.equal_range(k);
for(auto i = range.first; i != range.second; ++i)
PathContext::~PathContext()
{
if(check(i->second))
}
void
PathContext::AllowTransit()
{
m_AllowTransit = true;
}
bool
PathContext::AllowingTransit() const
{
return m_AllowTransit;
}
llarp_threadpool*
PathContext::Worker()
{
return m_Router->tp;
}
llarp_crypto*
PathContext::Crypto()
{
return &m_Router->crypto;
}
llarp_logic*
PathContext::Logic()
{
return m_Router->logic;
}
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)
{
llarp::Info("fowarding LRCM to ", nextHop);
LR_CommitMessage* msg = new LR_CommitMessage;
while(frames.size())
{
msg->frames.push_back(frames.front());
frames.pop_front();
}
return m_Router->SendToOrQueue(nextHop, msg);
}
template < typename Map_t, typename Key_t, typename CheckValue_t,
typename GetFunc_t >
IHopHandler*
MapGet(Map_t& map, const Key_t& k, CheckValue_t check, GetFunc_t get)
{
std::unique_lock< std::mutex > lock(map.first);
auto range = map.second.equal_range(k);
for(auto i = range.first; i != range.second; ++i)
{
if(check(i->second))
return get(i->second);
}
return nullptr;
}
template < typename Map_t, typename Key_t, typename CheckValue_t >
bool
MapHas(Map_t& map, const Key_t& k, CheckValue_t check)
{
std::unique_lock< std::mutex > lock(map.first);
auto range = map.second.equal_range(k);
for(auto i = range.first; i != range.second; ++i)
{
if(check(i->second))
return true;
}
return false;
}
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.emplace(k, v);
}
template < typename Map_t, typename Visit_t >
void
MapIter(Map_t& map, Visit_t v)
{
std::unique_lock< std::mutex > lock(map.first);
for(const auto& item : map.second)
v(item);
}
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 range = map.second.equal_range(k);
for(auto i = range.first; i != range.second;)
{
if(check(i->second))
i = map.second.erase(i);
else
++i;
}
}
void
PathContext::AddOwnPath(PathSet* set, Path* path)
{
set->AddPath(path);
MapPut(m_OurPaths, path->TXID(), set);
MapPut(m_OurPaths, path->RXID(), set);
}
bool
PathContext::HasTransitHop(const TransitHopInfo& info)
{
return MapHas(m_TransitPaths, info.txID, [info](TransitHop* hop) -> bool {
return info == hop->info;
});
}
IHopHandler*
PathContext::GetByUpstream(const RouterID& remote, const PathID_t& id)
{
auto own = MapGet(m_OurPaths, id,
[](const PathSet* s) -> bool {
// TODO: is this right?
return true;
},
[remote, id](PathSet* p) -> IHopHandler* {
return p->GetByUpstream(remote, id);
});
if(own)
return own;
return MapGet(m_TransitPaths, id,
[remote](const TransitHop* hop) -> bool {
return hop->info.upstream == remote;
},
[](TransitHop* h) -> IHopHandler* { return h; });
}
IHopHandler*
PathContext::GetByDownstream(const RouterID& remote, const PathID_t& id)
{
return MapGet(m_TransitPaths, id,
[remote](const TransitHop* hop) -> bool {
return hop->info.downstream == remote;
},
[](TransitHop* h) -> IHopHandler* { return h; });
}
const byte_t*
PathContext::OurRouterID() const
{
return m_Router->pubkey();
}
llarp_router*
PathContext::Router()
{
return m_Router;
}
void
PathContext::PutTransitHop(TransitHop* hop)
{
MapPut(m_TransitPaths, hop->info.txID, hop);
MapPut(m_TransitPaths, hop->info.rxID, hop);
}
void
PathContext::ExpirePaths()
{
std::unique_lock< std::mutex > lock(m_TransitPaths.first);
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))
{
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;
}
for(auto& builder : m_PathBuilders)
{
builder->ExpirePaths(now);
}
}
void
PathContext::BuildPaths()
{
for(auto& builder : m_PathBuilders)
{
if(builder->ShouldBuildMore())
{
builder->BuildOne();
}
}
}
void
PathContext::AddPathBuilder(llarp_pathbuilder_context* ctx)
{
m_PathBuilders.push_back(ctx);
}
PathHopConfig::PathHopConfig()
{
llarp_rc_clear(&router);
}
PathHopConfig::~PathHopConfig()
{
llarp_rc_free(&router);
}
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);
hops[idx].txID.Randomize();
hops[idx].rxID.Randomize();
}
for(size_t idx = (h->numHops - 1); idx > 0; --idx)
{
hops[idx].txID = hops[idx - 1].rxID;
}
}
void
Path::SetBuildResultHook(BuildResultHookFunc func)
{
m_BuiltHook = func;
}
const PathID_t&
Path::TXID() const
{
return hops[0].txID;
}
const PathID_t&
Path::RXID() const
{
return hops[0].rxID;
}
RouterID
Path::Upstream() const
{
return hops[0].router.pubkey;
}
bool
Path::HandleUpstream(llarp_buffer_t buf, const TunnelNonce& Y,
llarp_router* r)
{
for(const auto& hop : hops)
{
r->crypto.xchacha20(buf, hop.shared, Y);
}
RelayUpstreamMessage* msg = new RelayUpstreamMessage;
msg->X = buf;
msg->Y = Y;
msg->pathid = TXID();
return r->SendToOrQueue(Upstream(), msg);
}
bool
Path::Expired(llarp_time_t now) const
{
if(status == ePathEstablished)
return now - buildStarted > hops[0].lifetime;
else if(status == ePathBuilding)
return now - buildStarted > PATH_BUILD_TIMEOUT;
else
return true;
}
return false;
}
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.emplace(k, v);
}
template < typename Map_t, typename Visit_t >
void
MapIter(Map_t& map, Visit_t v)
{
std::unique_lock< std::mutex > lock(map.first);
for(const auto& item : map.second)
v(item);
}
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 range = map.second.equal_range(k);
for(auto i = range.first; i != range.second;)
bool
Path::HandleDownstream(llarp_buffer_t buf, const TunnelNonce& Y,
llarp_router* r)
{
if(check(i->second))
i = map.second.erase(i);
else
++i;
}
}
void
PathContext::AddOwnPath(Path* path)
{
MapPut(m_OurPaths, path->TXID(), path);
MapPut(m_OurPaths, path->RXID(), path);
}
bool
PathContext::HasTransitHop(const TransitHopInfo& info)
{
return MapHas(m_TransitPaths, info.txID, [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;
});
}
IHopHandler*
PathContext::GetByDownstream(const RouterID& remote, const PathID_t& id)
{
return MapGet(m_TransitPaths, id, [remote](const TransitHop* hop) -> bool {
return hop->info.downstream == remote;
});
}
const byte_t*
PathContext::OurRouterID() const
{
return m_Router->pubkey();
}
llarp_router*
PathContext::Router()
{
return m_Router;
}
void
PathContext::PutTransitHop(TransitHop* hop)
{
MapPut(m_TransitPaths, hop->info.txID, hop);
MapPut(m_TransitPaths, hop->info.rxID, hop);
}
void
PathContext::ExpirePaths()
{
std::unique_lock< std::mutex > lock(m_TransitPaths.first);
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))
for(const auto& hop : hops)
{
TransitHop* path = itr->second;
llarp::Info("transit path expired ", path);
removePaths.insert(path);
r->crypto.xchacha20(buf, hop.shared, Y);
}
++itr;
return HandleRoutingMessage(buf, r);
}
for(auto& p : removePaths)
bool
Path::HandleHiddenServiceData(llarp_buffer_t buf)
{
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);
hops[idx].txID.Randomize();
hops[idx].rxID.Randomize();
}
for(size_t idx = (h->numHops - 1); idx > 0; --idx)
{
hops[idx].txID = hops[idx - 1].rxID;
}
}
const PathID_t&
Path::TXID() const
{
return hops[0].txID;
}
const PathID_t&
Path::RXID() const
{
return hops[0].rxID;
}
RouterID
Path::Upstream() const
{
return hops[0].router.pubkey;
}
bool
Path::HandleUpstream(llarp_buffer_t buf, const TunnelNonce& Y,
llarp_router* r)
{
for(const auto& hop : hops)
{
r->crypto.xchacha20(buf, hop.shared, Y);
}
RelayUpstreamMessage* msg = new RelayUpstreamMessage;
msg->X = buf;
msg->Y = Y;
msg->pathid = TXID();
return r->SendToOrQueue(Upstream(), msg);
}
bool
Path::Expired(llarp_time_t now) const
{
return now - buildStarted > hops[0].lifetime;
}
bool
Path::HandleDownstream(llarp_buffer_t buf, const TunnelNonce& Y,
llarp_router* r)
{
for(const auto& hop : hops)
{
r->crypto.xchacha20(buf, hop.shared, Y);
}
return HandleRoutingMessage(buf, r);
}
bool
Path::HandleHiddenServiceData(llarp_buffer_t buf)
{
// TODO: implement me
return false;
}
bool
Path::HandleRoutingMessage(llarp_buffer_t buf, llarp_router* r)
{
if(!m_InboundMessageParser.ParseMessageBuffer(buf, this))
{
llarp::Warn("Failed to parse inbound routing message");
// TODO: implement me
return false;
}
return true;
}
bool
Path::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))
bool
Path::HandleRoutingMessage(llarp_buffer_t buf, llarp_router* r)
{
if(!m_InboundMessageParser.ParseMessageBuffer(buf, this))
{
llarp::Warn("Failed to parse inbound routing message");
return false;
}
return true;
}
bool
Path::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))
return false;
// rewind
buf.sz = buf.cur - buf.base;
buf.cur = buf.base;
// make nonce
TunnelNonce N;
N.Randomize();
return HandleUpstream(buf, N, r);
}
bool
Path::HandlePathConfirmMessage(
const llarp::routing::PathConfirmMessage* msg)
{
if(status == ePathBuilding)
{
// confirm that we build the path
status = ePathEstablished;
if(m_BuiltHook)
m_BuiltHook(this);
m_BuiltHook = nullptr;
return true;
}
llarp::Warn("got unwarrented path confirm message on rx=", RXID(),
" tx=", TXID());
return false;
// rewind
buf.sz = buf.cur - buf.base;
buf.cur = buf.base;
// make nonce
TunnelNonce N;
N.Randomize();
return HandleUpstream(buf, N, r);
}
}
bool
Path::HandlePathLatencyMessage(
const llarp::routing::PathLatencyMessage* msg)
{
// TODO: implement me
return false;
}
bool
Path::HandleDHTMessage(const llarp::dht::IMessage* msg)
{
// TODO: implement me
return false;
}
} // namespace path
} // namespace llarp

View File

@ -9,7 +9,10 @@ namespace llarp
template < typename User >
struct AsyncPathKeyExchangeContext
{
Path* path = nullptr;
typedef llarp::path::Path Path_t;
typedef llarp::path::PathSet PathSet_t;
PathSet_t* pathset = nullptr;
Path_t* path = nullptr;
typedef void (*Handler)(AsyncPathKeyExchangeContext< User >*);
User* user = nullptr;
Handler result = nullptr;
@ -105,8 +108,8 @@ namespace llarp
/// Generate all keys asynchronously and call hadler when done
void
AsyncGenerateKeys(Path* p, llarp_logic* l, llarp_threadpool* pool, User* u,
Handler func)
AsyncGenerateKeys(Path_t* p, llarp_logic* l, llarp_threadpool* pool,
User* u, Handler func)
{
path = p;
logic = l;
@ -124,16 +127,6 @@ namespace llarp
}
};
PathHopConfig::PathHopConfig()
{
llarp_rc_clear(&router);
}
PathHopConfig::~PathHopConfig()
{
llarp_rc_free(&router);
}
void
pathbuilder_generated_keys(
AsyncPathKeyExchangeContext< llarp_pathbuild_job >* ctx)
@ -146,8 +139,8 @@ namespace llarp
llarp::Error("failed to send LRCM");
return;
}
ctx->path->status = ePathBuilding;
router->paths.AddOwnPath(ctx->path);
ctx->path->status = llarp::path::ePathBuilding;
router->paths.AddOwnPath(ctx->pathset, ctx->path);
ctx->user->pathBuildStarted(ctx->user);
}
@ -171,16 +164,33 @@ namespace llarp
AsyncPathKeyExchangeContext< llarp_pathbuild_job >* ctx =
new AsyncPathKeyExchangeContext< llarp_pathbuild_job >(
&job->router->crypto);
ctx->AsyncGenerateKeys(new Path(&job->hops), job->router->logic,
job->router->tp, job, &pathbuilder_generated_keys);
ctx->pathset = job->context;
auto path = new llarp::path::Path(&job->hops);
path->SetBuildResultHook(std::bind(&llarp::path::PathSet::HandlePathBuilt,
ctx->pathset, std::placeholders::_1));
ctx->AsyncGenerateKeys(path, job->router->logic, job->router->tp, job,
&pathbuilder_generated_keys);
}
} // namespace llarp
llarp_pathbuilder_context::llarp_pathbuilder_context(
llarp_router* p_router, struct llarp_dht_context* p_dht)
: router(p_router), dht(p_dht)
// TODO: hardcoded value
: llarp::path::PathSet(4), router(p_router), dht(p_dht)
{
p_router->paths.AddPathBuilder(this);
}
void
llarp_pathbuilder_context::BuildOne()
{
llarp_pathbuild_job* job = new llarp_pathbuild_job;
job->context = this;
job->selectHop = nullptr;
job->hops.numHops = 4;
job->user = nullptr;
job->pathBuildStarted = [](llarp_pathbuild_job* j) { delete j; };
llarp_pathbuilder_build_path(job);
}
extern "C" {
@ -200,7 +210,7 @@ llarp_pathbuilder_context_free(struct llarp_pathbuilder_context* ctx)
void
llarp_pathbuilder_build_path(struct llarp_pathbuild_job* job)
{
if (!job->context)
if(!job->context)
{
llarp::Error("failed to build path because no context is set in job");
return;
@ -211,4 +221,4 @@ llarp_pathbuilder_build_path(struct llarp_pathbuild_job* job)
llarp_logic_queue_job(job->router->logic,
{job, &llarp::pathbuilder_start_build});
}
} // end extern c
} // end extern c

View File

@ -2,13 +2,16 @@
#define LLARP_PATHFINDER_HPP_
#include <llarp/pathbuilder.h>
struct llarp_pathbuilder_context
struct llarp_pathbuilder_context : public llarp::path::PathSet
{
struct llarp_router* router;
struct llarp_dht_context* dht;
/// copy cstr
/// construct
llarp_pathbuilder_context(llarp_router* p_router,
struct llarp_dht_context* p_dht);
void
BuildOne();
};
#endif

97
llarp/pathset.cpp Normal file
View File

@ -0,0 +1,97 @@
#include <llarp/path.hpp>
#include <llarp/pathset.hpp>
namespace llarp
{
namespace path
{
PathSet::PathSet(size_t num) : m_NumPaths(num)
{
}
bool
PathSet::ShouldBuildMore() const
{
return std::get< 0 >(m_Paths).size() < m_NumPaths;
}
void
PathSet::ExpirePaths(llarp_time_t now)
{
{
auto& map = std::get< 0 >(m_Paths);
auto itr = map.begin();
while(itr != map.end())
{
if(itr->second->Expired(now))
{
itr = map.erase(itr);
}
}
}
{
auto& map = std::get< 1 >(m_Paths);
auto itr = map.begin();
while(itr != map.end())
{
if(itr->second->Expired(now))
{
// delete path on second iteration
delete itr->second;
itr = map.erase(itr);
}
}
}
}
size_t
PathSet::NumInStatus(PathStatus st) const
{
size_t count = 0;
auto& map = std::get< 0 >(m_Paths);
auto itr = map.begin();
while(itr != map.end())
{
if(itr->second->status == st)
++count;
++itr;
}
return count;
}
void
PathSet::AddPath(Path* path)
{
std::get< 0 >(m_Paths).emplace(path->TXID(), path);
std::get< 1 >(m_Paths).emplace(path->RXID(), path);
}
void
PathSet::RemovePath(Path* path)
{
std::get< 0 >(m_Paths).erase(path->TXID());
std::get< 1 >(m_Paths).erase(path->RXID());
}
Path*
PathSet::GetByUpstream(const RouterID& remote, const PathID_t& rxid)
{
auto& set = std::get< 1 >(m_Paths);
auto itr = set.begin();
while(itr != set.end())
{
if(itr->second->Upstream() == remote)
return itr->second;
++itr;
}
return nullptr;
}
void
PathSet::HandlePathBuilt(Path* path)
{
// TODO: implement me
}
} // namespace path
} // namespace llarp

View File

@ -155,18 +155,20 @@ namespace llarp
struct LRCMFrameDecrypt
{
typedef llarp::path::PathContext Context;
typedef llarp::path::TransitHop Hop;
typedef AsyncFrameDecrypter< LRCMFrameDecrypt > Decrypter;
Decrypter* decrypter;
std::deque< EncryptedFrame > frames;
PathContext* context;
Context* context;
// decrypted record
LR_CommitRecord record;
// the actual hop
TransitHop* hop;
Hop* hop;
LRCMFrameDecrypt(PathContext* ctx, Decrypter* dec,
LRCMFrameDecrypt(Context* ctx, Decrypter* dec,
const LR_CommitMessage* commit)
: decrypter(dec), context(ctx), hop(new TransitHop)
: decrypter(dec), context(ctx), hop(new Hop)
{
for(const auto& f : commit->frames)
frames.push_back(f);
@ -276,7 +278,7 @@ namespace llarp
};
bool
LR_CommitMessage::AsyncDecrypt(PathContext* context) const
LR_CommitMessage::AsyncDecrypt(llarp::path::PathContext* context) const
{
LRCMFrameDecrypt::Decrypter* decrypter = new LRCMFrameDecrypt::Decrypter(
context->Crypto(), context->EncryptionSecretKey(),

View File

@ -356,6 +356,7 @@ llarp_router::HandleExploritoryPathBuildStarted(llarp_pathbuild_job *job)
delete job;
}
// TODO: do we still need this?
void
llarp_router::BuildExploritoryPath()
{
@ -379,7 +380,7 @@ llarp_router::Tick()
auto N = llarp_nodedb_num_loaded(nodedb);
if(N > 5)
{
BuildExploritoryPath();
paths.BuildPaths();
}
else
{
@ -595,16 +596,14 @@ llarp_router::Run()
// set public encryption key
llarp_rc_set_pubenckey(&rc, llarp::seckey_topublic(encryption));
char ftmp[68] = {0};
const char *hexKey = llarp::HexEncode< llarp::PubKey,
decltype(ftmp) >(llarp::seckey_topublic(encryption),
ftmp);
char ftmp[68] = {0};
const char *hexKey = llarp::HexEncode< llarp::PubKey, decltype(ftmp) >(
llarp::seckey_topublic(encryption), ftmp);
llarp::Info("Your Encryption pubkey ", hexKey);
// set public signing key
llarp_rc_set_pubsigkey(&rc, llarp::seckey_topublic(identity));
hexKey = llarp::HexEncode< llarp::PubKey,
decltype(ftmp) >(llarp::seckey_topublic(identity),
ftmp);
hexKey = llarp::HexEncode< llarp::PubKey, decltype(ftmp) >(
llarp::seckey_topublic(identity), ftmp);
llarp::Info("Your Identity pubkey ", hexKey);
llarp_rc_sign(&crypto, identity, &rc);
@ -641,14 +640,16 @@ llarp_router::Run()
// immediate connect all for service node
uint64_t delay = rand() % 100;
llarp_logic_call_later(logic, {delay, this, &ConnectAll});
//llarp_logic_call_later(logic, {static_cast<uint64_t>(delay), this, &ConnectAll});
// llarp_logic_call_later(logic, {static_cast<uint64_t>(delay), this,
// &ConnectAll});
}
else
{
// delayed connect all for clients
uint64_t delay = ((rand() % 10) * 500) + 1000;
llarp_logic_call_later(logic, {delay, this, &ConnectAll});
//llarp_logic_call_later(logic, {static_cast<uint64_t>(delay), this, &ConnectAll});
// llarp_logic_call_later(logic, {static_cast<uint64_t>(delay), this,
// &ConnectAll});
}
llarp::PubKey ourPubkey = pubkey();
@ -850,7 +851,7 @@ llarp_rc_read(const char *fpath)
return 0;
f.read((char *)buf.base, sz);
//printf("contents[%s]\n", tmpc);
// printf("contents[%s]\n", tmpc);
llarp_rc *rc = new llarp_rc;
llarp::Zero(rc, sizeof(llarp_rc));
if(!llarp_rc_bdecode(rc, &buf))
@ -977,12 +978,12 @@ llarp_findOrCreateIdentity(llarp_crypto *crypto, const char *fpath,
return false;
}
} // end extern C
} // end extern C
// C++ ...
bool
llarp_findOrCreateEncryption(llarp_crypto *crypto, const char *fpath,
llarp::SecretKey *encryption)
llarp::SecretKey *encryption)
{
llarp::Debug("find or create ", fpath);
fs::path path(fpath);

View File

@ -58,7 +58,7 @@ struct llarp_router
llarp_threadpool *tp;
llarp_logic *logic;
llarp_crypto crypto;
llarp::PathContext paths;
llarp::path::PathContext paths;
llarp::SecretKey identity;
llarp::SecretKey encryption;
llarp_threadpool *disk;

View File

@ -44,9 +44,7 @@ namespace llarp
bool
PathConfirmMessage::HandleMessage(IMessageHandler* h) const
{
llarp::Info("got path confirm created=", pathCreated,
" lifetime=", pathLifetime);
return true;
return h && h->HandlePathConfirmMessage(this);
}
} // namespace routing

View File

@ -4,85 +4,87 @@
namespace llarp
{
bool
TransitHop::Expired(llarp_time_t now) const
namespace path
{
return now - started > lifetime;
}
TransitHopInfo::TransitHopInfo(const TransitHopInfo& other)
: txID(other.txID)
, rxID(other.rxID)
, upstream(other.upstream)
, downstream(other.downstream)
{
}
TransitHopInfo::TransitHopInfo(const RouterID& down,
const LR_CommitRecord& record)
: txID(record.txid)
, rxID(record.rxid)
, 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))
bool
TransitHop::Expired(llarp_time_t now) const
{
llarp::Error("failed to encode routing message");
return false;
return now - started > lifetime;
}
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,
TransitHopInfo::TransitHopInfo(const TransitHopInfo& other)
: txID(other.txID)
, rxID(other.rxID)
, upstream(other.upstream)
, downstream(other.downstream)
{
}
TransitHopInfo::TransitHopInfo(const RouterID& down,
const LR_CommitRecord& record)
: txID(record.txid)
, rxID(record.rxid)
, 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.txID;
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)
{
RelayDownstreamMessage* msg = new RelayDownstreamMessage;
msg->pathid = info.txID;
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.rxID;
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);
}
{
RelayUpstreamMessage* msg = new RelayUpstreamMessage;
msg->pathid = info.rxID;
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 path
} // namespace llarp