2018-08-30 18:48:43 +00:00
|
|
|
#ifndef LLARP_NODEDB_HPP
|
|
|
|
#define LLARP_NODEDB_HPP
|
2018-12-12 01:55:30 +00:00
|
|
|
|
|
|
|
#include <router_contact.hpp>
|
2018-12-12 02:52:51 +00:00
|
|
|
#include <router_id.hpp>
|
2019-01-10 19:41:51 +00:00
|
|
|
#include <util/common.hpp>
|
|
|
|
#include <util/fs.hpp>
|
2019-03-03 20:51:47 +00:00
|
|
|
#include <util/threading.hpp>
|
|
|
|
|
|
|
|
#include <absl/base/thread_annotations.h>
|
2018-12-10 23:29:58 +00:00
|
|
|
|
2019-03-11 13:58:31 +00:00
|
|
|
#include <set>
|
2019-07-30 23:42:13 +00:00
|
|
|
#include <utility>
|
2019-03-11 13:58:31 +00:00
|
|
|
|
2019-04-19 18:24:33 +00:00
|
|
|
#ifdef _MSC_VER
|
|
|
|
#include <BaseTsd.h>
|
|
|
|
typedef SSIZE_T ssize_t;
|
|
|
|
#endif
|
|
|
|
|
2018-05-31 13:08:06 +00:00
|
|
|
/**
|
2018-08-30 18:48:43 +00:00
|
|
|
* nodedb.hpp
|
2018-05-31 13:08:06 +00:00
|
|
|
*
|
|
|
|
* persistent storage API for router contacts
|
|
|
|
*/
|
|
|
|
|
2019-01-13 16:30:07 +00:00
|
|
|
struct llarp_threadpool;
|
|
|
|
|
2018-12-10 14:14:55 +00:00
|
|
|
namespace llarp
|
|
|
|
{
|
|
|
|
class Logic;
|
2019-05-18 18:46:49 +00:00
|
|
|
|
|
|
|
namespace thread
|
|
|
|
{
|
|
|
|
class ThreadPool;
|
|
|
|
}
|
2019-01-13 16:30:07 +00:00
|
|
|
} // namespace llarp
|
2018-12-10 14:14:55 +00:00
|
|
|
|
2018-06-18 22:05:02 +00:00
|
|
|
struct llarp_nodedb_iter
|
|
|
|
{
|
|
|
|
void *user;
|
2018-08-30 18:48:43 +00:00
|
|
|
llarp::RouterContact *rc;
|
2018-06-19 09:46:21 +00:00
|
|
|
size_t index;
|
2018-06-18 22:05:02 +00:00
|
|
|
bool (*visit)(struct llarp_nodedb_iter *);
|
|
|
|
};
|
|
|
|
|
2018-12-10 23:29:58 +00:00
|
|
|
struct llarp_nodedb
|
|
|
|
{
|
2019-07-09 13:47:24 +00:00
|
|
|
explicit llarp_nodedb(std::shared_ptr< llarp::thread::ThreadPool > diskworker)
|
2019-07-30 23:42:13 +00:00
|
|
|
: disk(std::move(diskworker))
|
2018-12-10 23:29:58 +00:00
|
|
|
{
|
|
|
|
}
|
2018-06-18 22:05:02 +00:00
|
|
|
|
2018-12-10 23:29:58 +00:00
|
|
|
~llarp_nodedb()
|
|
|
|
{
|
|
|
|
Clear();
|
|
|
|
}
|
2018-09-11 15:53:54 +00:00
|
|
|
|
2019-07-09 13:47:24 +00:00
|
|
|
std::shared_ptr< llarp::thread::ThreadPool > disk;
|
2019-03-03 20:51:47 +00:00
|
|
|
mutable llarp::util::Mutex access; // protects entries
|
2019-06-10 12:47:21 +00:00
|
|
|
|
|
|
|
struct NetDBEntry
|
|
|
|
{
|
|
|
|
const llarp::RouterContact rc;
|
2019-06-26 21:39:29 +00:00
|
|
|
llarp_time_t inserted;
|
2019-06-10 12:47:21 +00:00
|
|
|
|
2019-07-30 23:42:13 +00:00
|
|
|
NetDBEntry(llarp::RouterContact data);
|
2019-06-10 12:47:21 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
using NetDBMap_t =
|
|
|
|
std::unordered_map< llarp::RouterID, NetDBEntry, llarp::RouterID::Hash >;
|
|
|
|
|
|
|
|
NetDBMap_t entries GUARDED_BY(access);
|
2018-12-10 23:29:58 +00:00
|
|
|
fs::path nodePath;
|
2018-06-19 17:11:24 +00:00
|
|
|
|
2018-12-10 23:29:58 +00:00
|
|
|
bool
|
2019-03-03 20:51:47 +00:00
|
|
|
Remove(const llarp::RouterID &pk) LOCKS_EXCLUDED(access);
|
2018-06-18 22:05:02 +00:00
|
|
|
|
2019-03-25 13:52:22 +00:00
|
|
|
void
|
|
|
|
RemoveIf(std::function< bool(const llarp::RouterContact &) > filter)
|
|
|
|
LOCKS_EXCLUDED(access);
|
|
|
|
|
2018-12-10 23:29:58 +00:00
|
|
|
void
|
2019-03-03 20:51:47 +00:00
|
|
|
Clear() LOCKS_EXCLUDED(access);
|
2018-06-18 22:05:02 +00:00
|
|
|
|
2018-12-10 23:29:58 +00:00
|
|
|
bool
|
2019-03-03 20:51:47 +00:00
|
|
|
Get(const llarp::RouterID &pk, llarp::RouterContact &result)
|
|
|
|
LOCKS_EXCLUDED(access);
|
2018-12-10 23:29:58 +00:00
|
|
|
|
|
|
|
bool
|
2019-03-03 20:51:47 +00:00
|
|
|
Has(const llarp::RouterID &pk) LOCKS_EXCLUDED(access);
|
2018-12-10 23:29:58 +00:00
|
|
|
|
|
|
|
std::string
|
2019-01-02 01:04:04 +00:00
|
|
|
getRCFilePath(const llarp::RouterID &pubkey) const;
|
2018-12-10 23:29:58 +00:00
|
|
|
|
|
|
|
/// insert and write to disk
|
|
|
|
bool
|
2019-03-03 20:51:47 +00:00
|
|
|
Insert(const llarp::RouterContact &rc) LOCKS_EXCLUDED(access);
|
2018-12-10 23:29:58 +00:00
|
|
|
|
2019-06-17 14:23:38 +00:00
|
|
|
/// unconditional insert and write to disk in background
|
|
|
|
/// updates the inserted time of the entry
|
2018-12-19 16:17:41 +00:00
|
|
|
void
|
2019-05-22 16:20:50 +00:00
|
|
|
InsertAsync(llarp::RouterContact rc,
|
|
|
|
std::shared_ptr< llarp::Logic > l = nullptr,
|
2019-04-17 19:05:54 +00:00
|
|
|
std::function< void(void) > completionHandler = nullptr);
|
2018-12-19 16:17:41 +00:00
|
|
|
|
2019-06-17 14:23:38 +00:00
|
|
|
/// update rc if newer
|
|
|
|
/// return true if we started to put this rc in the database
|
|
|
|
/// retur false if not newer
|
|
|
|
bool
|
|
|
|
UpdateAsyncIfNewer(llarp::RouterContact rc,
|
|
|
|
std::shared_ptr< llarp::Logic > l = nullptr,
|
|
|
|
std::function< void(void) > completionHandler = nullptr)
|
|
|
|
LOCKS_EXCLUDED(access);
|
|
|
|
|
2018-12-10 23:29:58 +00:00
|
|
|
ssize_t
|
|
|
|
Load(const fs::path &path);
|
|
|
|
|
|
|
|
ssize_t
|
|
|
|
loadSubdir(const fs::path &dir);
|
2019-06-17 14:23:38 +00:00
|
|
|
/// save all entries to disk async
|
|
|
|
void
|
|
|
|
AsyncFlushToDisk();
|
2018-12-10 23:29:58 +00:00
|
|
|
|
|
|
|
bool
|
2019-03-03 20:51:47 +00:00
|
|
|
loadfile(const fs::path &fpath) LOCKS_EXCLUDED(access);
|
2018-12-10 23:29:58 +00:00
|
|
|
|
|
|
|
void
|
2019-03-03 20:51:47 +00:00
|
|
|
visit(std::function< bool(const llarp::RouterContact &) > visit)
|
|
|
|
LOCKS_EXCLUDED(access);
|
2018-12-10 23:29:58 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
set_dir(const char *dir);
|
|
|
|
|
|
|
|
ssize_t
|
|
|
|
load_dir(const char *dir);
|
|
|
|
ssize_t
|
|
|
|
store_dir(const char *dir);
|
|
|
|
|
2019-06-20 14:00:04 +00:00
|
|
|
/// visit all entries inserted into nodedb cache before a timestamp
|
2019-06-10 12:47:21 +00:00
|
|
|
void
|
2019-06-20 14:00:04 +00:00
|
|
|
VisitInsertedBefore(std::function< void(const llarp::RouterContact &) > visit,
|
|
|
|
llarp_time_t insertedAfter) LOCKS_EXCLUDED(access);
|
2018-12-10 23:29:58 +00:00
|
|
|
|
2019-06-26 21:39:29 +00:00
|
|
|
void
|
|
|
|
RemoveStaleRCs(const std::set< llarp::RouterID > &keep, llarp_time_t cutoff);
|
|
|
|
|
2018-12-10 23:29:58 +00:00
|
|
|
size_t
|
2019-03-03 20:51:47 +00:00
|
|
|
num_loaded() const LOCKS_EXCLUDED(access);
|
2018-12-10 23:29:58 +00:00
|
|
|
|
|
|
|
bool
|
2019-03-03 20:51:47 +00:00
|
|
|
select_random_exit(llarp::RouterContact &rc) LOCKS_EXCLUDED(access);
|
2018-12-10 23:29:58 +00:00
|
|
|
|
|
|
|
bool
|
|
|
|
select_random_hop(const llarp::RouterContact &prev,
|
2019-03-03 20:51:47 +00:00
|
|
|
llarp::RouterContact &result, size_t N)
|
|
|
|
LOCKS_EXCLUDED(access);
|
2018-12-10 23:29:58 +00:00
|
|
|
|
2019-03-11 13:58:31 +00:00
|
|
|
bool
|
|
|
|
select_random_hop_excluding(llarp::RouterContact &result,
|
|
|
|
const std::set< llarp::RouterID > &exclude)
|
|
|
|
LOCKS_EXCLUDED(access);
|
|
|
|
|
2018-12-10 23:29:58 +00:00
|
|
|
static bool
|
|
|
|
ensure_dir(const char *dir);
|
2019-06-17 14:23:38 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
SaveAll() LOCKS_EXCLUDED(access);
|
2018-12-10 23:29:58 +00:00
|
|
|
};
|
2018-09-13 16:41:53 +00:00
|
|
|
|
2018-06-18 22:05:02 +00:00
|
|
|
/// struct for async rc verification
|
|
|
|
struct llarp_async_verify_rc;
|
|
|
|
|
2018-11-22 23:59:03 +00:00
|
|
|
using llarp_async_verify_rc_hook_func =
|
|
|
|
std::function< void(struct llarp_async_verify_rc *) >;
|
2018-06-18 22:05:02 +00:00
|
|
|
|
|
|
|
/// verify rc request
|
|
|
|
struct llarp_async_verify_rc
|
|
|
|
{
|
|
|
|
/// async_verify_context
|
|
|
|
void *user;
|
|
|
|
/// nodedb storage
|
2019-05-18 18:46:49 +00:00
|
|
|
llarp_nodedb *nodedb;
|
2018-12-10 14:14:55 +00:00
|
|
|
// llarp::Logic for queue_job
|
2019-07-12 14:07:12 +00:00
|
|
|
std::shared_ptr< llarp::Logic > logic;
|
2019-07-09 13:47:24 +00:00
|
|
|
std::shared_ptr< llarp::thread::ThreadPool > cryptoworker;
|
|
|
|
std::shared_ptr< llarp::thread::ThreadPool > diskworker;
|
2018-06-18 22:05:02 +00:00
|
|
|
|
2018-07-03 13:13:56 +00:00
|
|
|
/// router contact
|
2018-08-30 18:48:43 +00:00
|
|
|
llarp::RouterContact rc;
|
2018-06-18 22:05:02 +00:00
|
|
|
/// result
|
|
|
|
bool valid;
|
|
|
|
/// hook
|
|
|
|
llarp_async_verify_rc_hook_func hook;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
struct for async rc verification
|
|
|
|
data is loaded in disk io threadpool
|
|
|
|
crypto is done on the crypto worker threadpool
|
|
|
|
result is called on the logic thread
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
llarp_nodedb_async_verify(struct llarp_async_verify_rc *job);
|
|
|
|
|
|
|
|
struct llarp_async_load_rc;
|
|
|
|
|
2018-11-22 23:59:03 +00:00
|
|
|
using llarp_async_load_rc_hook_func =
|
|
|
|
std::function< void(struct llarp_async_load_rc *) >;
|
2018-06-18 22:05:02 +00:00
|
|
|
|
|
|
|
struct llarp_async_load_rc
|
|
|
|
{
|
|
|
|
/// async_verify_context
|
|
|
|
void *user;
|
|
|
|
/// nodedb storage
|
2019-05-18 18:46:49 +00:00
|
|
|
llarp_nodedb *nodedb;
|
2018-12-10 14:14:55 +00:00
|
|
|
/// llarp::Logic for calling hook
|
|
|
|
llarp::Logic *logic;
|
2018-06-18 22:05:02 +00:00
|
|
|
/// disk worker threadpool
|
2019-05-18 18:46:49 +00:00
|
|
|
llarp::thread::ThreadPool *diskworker;
|
2018-06-18 22:05:02 +00:00
|
|
|
/// target pubkey
|
2018-08-30 18:48:43 +00:00
|
|
|
llarp::PubKey pubkey;
|
2018-06-18 22:05:02 +00:00
|
|
|
/// router contact result
|
2018-08-30 18:48:43 +00:00
|
|
|
llarp::RouterContact result;
|
2018-06-18 22:05:02 +00:00
|
|
|
/// set to true if we loaded the rc
|
|
|
|
bool loaded;
|
|
|
|
/// hook function called in logic thread
|
|
|
|
llarp_async_load_rc_hook_func hook;
|
|
|
|
};
|
|
|
|
|
|
|
|
/// asynchronously load an rc from disk
|
|
|
|
void
|
|
|
|
llarp_nodedb_async_load_rc(struct llarp_async_load_rc *job);
|
2018-06-13 12:58:51 +00:00
|
|
|
|
2018-04-08 12:18:16 +00:00
|
|
|
#endif
|