mirror of https://github.com/oxen-io/lokinet
* add path building management
* fix bug in iwp that caused crash
This commit is contained in:
parent
ce643cc8e0
commit
da22f306e0
|
@ -54,6 +54,9 @@
|
|||
"__config": "cpp",
|
||||
"__nullptr": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"io": "cpp"
|
||||
"io": "cpp",
|
||||
"strstream": "cpp",
|
||||
"numeric": "cpp",
|
||||
"valarray": "cpp"
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
2
Makefile
2
Makefile
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -7,7 +7,6 @@ namespace llarp
|
|||
{
|
||||
namespace api
|
||||
{
|
||||
|
||||
bool
|
||||
CreateSessionMessage::DecodeParams(llarp_buffer_t *buf)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
663
llarp/path.cpp
663
llarp/path.cpp
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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(),
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue