mirror of
https://github.com/oxen-io/lokinet.git
synced 2024-11-05 21:20:38 +00:00
baf8019fe5
This commit refactors functionality from the Router class into separate, dedicated classes. There are a few behavior changes that came as a result of discussion on what the correct behavior should be. In addition, many things Router was previously doing can now be provided callback functions to alert the calling point when the asynchronous action completes, successfully or otherwise.
234 lines
5.2 KiB
C++
234 lines
5.2 KiB
C++
#ifndef LLARP_NODEDB_HPP
|
|
#define LLARP_NODEDB_HPP
|
|
|
|
#include <router_contact.hpp>
|
|
#include <router_id.hpp>
|
|
#include <util/common.hpp>
|
|
#include <util/fs.hpp>
|
|
#include <util/threading.hpp>
|
|
|
|
#include <absl/base/thread_annotations.h>
|
|
|
|
#include <set>
|
|
|
|
#ifdef _MSC_VER
|
|
#include <BaseTsd.h>
|
|
typedef SSIZE_T ssize_t;
|
|
#endif
|
|
|
|
/**
|
|
* nodedb.hpp
|
|
*
|
|
* persistent storage API for router contacts
|
|
*/
|
|
|
|
struct llarp_threadpool;
|
|
|
|
namespace llarp
|
|
{
|
|
class Logic;
|
|
|
|
namespace thread
|
|
{
|
|
class ThreadPool;
|
|
}
|
|
} // namespace llarp
|
|
|
|
struct llarp_nodedb_iter
|
|
{
|
|
void *user;
|
|
llarp::RouterContact *rc;
|
|
size_t index;
|
|
bool (*visit)(struct llarp_nodedb_iter *);
|
|
};
|
|
|
|
struct llarp_nodedb
|
|
{
|
|
explicit llarp_nodedb(std::shared_ptr< llarp::thread::ThreadPool > diskworker)
|
|
: disk(diskworker)
|
|
{
|
|
}
|
|
|
|
~llarp_nodedb()
|
|
{
|
|
Clear();
|
|
}
|
|
|
|
std::shared_ptr< llarp::thread::ThreadPool > disk;
|
|
mutable llarp::util::Mutex access; // protects entries
|
|
|
|
struct NetDBEntry
|
|
{
|
|
const llarp::RouterContact rc;
|
|
llarp_time_t inserted;
|
|
|
|
NetDBEntry(const llarp::RouterContact &data);
|
|
};
|
|
|
|
using NetDBMap_t =
|
|
std::unordered_map< llarp::RouterID, NetDBEntry, llarp::RouterID::Hash >;
|
|
|
|
NetDBMap_t entries GUARDED_BY(access);
|
|
fs::path nodePath;
|
|
|
|
bool
|
|
Remove(const llarp::RouterID &pk) LOCKS_EXCLUDED(access);
|
|
|
|
void
|
|
RemoveIf(std::function< bool(const llarp::RouterContact &) > filter)
|
|
LOCKS_EXCLUDED(access);
|
|
|
|
void
|
|
Clear() LOCKS_EXCLUDED(access);
|
|
|
|
bool
|
|
Get(const llarp::RouterID &pk, llarp::RouterContact &result)
|
|
LOCKS_EXCLUDED(access);
|
|
|
|
bool
|
|
Has(const llarp::RouterID &pk) LOCKS_EXCLUDED(access);
|
|
|
|
std::string
|
|
getRCFilePath(const llarp::RouterID &pubkey) const;
|
|
|
|
/// insert and write to disk
|
|
bool
|
|
Insert(const llarp::RouterContact &rc) LOCKS_EXCLUDED(access);
|
|
|
|
/// unconditional insert and write to disk in background
|
|
/// updates the inserted time of the entry
|
|
void
|
|
InsertAsync(llarp::RouterContact rc,
|
|
std::shared_ptr< llarp::Logic > l = nullptr,
|
|
std::function< void(void) > completionHandler = nullptr);
|
|
|
|
/// 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);
|
|
|
|
ssize_t
|
|
Load(const fs::path &path);
|
|
|
|
ssize_t
|
|
loadSubdir(const fs::path &dir);
|
|
/// save all entries to disk async
|
|
void
|
|
AsyncFlushToDisk();
|
|
|
|
bool
|
|
loadfile(const fs::path &fpath) LOCKS_EXCLUDED(access);
|
|
|
|
void
|
|
visit(std::function< bool(const llarp::RouterContact &) > visit)
|
|
LOCKS_EXCLUDED(access);
|
|
|
|
void
|
|
set_dir(const char *dir);
|
|
|
|
ssize_t
|
|
load_dir(const char *dir);
|
|
ssize_t
|
|
store_dir(const char *dir);
|
|
|
|
/// visit all entries inserted into nodedb cache before a timestamp
|
|
void
|
|
VisitInsertedBefore(std::function< void(const llarp::RouterContact &) > visit,
|
|
llarp_time_t insertedAfter) LOCKS_EXCLUDED(access);
|
|
|
|
void
|
|
RemoveStaleRCs(const std::set< llarp::RouterID > &keep, llarp_time_t cutoff);
|
|
|
|
size_t
|
|
num_loaded() const LOCKS_EXCLUDED(access);
|
|
|
|
bool
|
|
select_random_exit(llarp::RouterContact &rc) LOCKS_EXCLUDED(access);
|
|
|
|
bool
|
|
select_random_hop(const llarp::RouterContact &prev,
|
|
llarp::RouterContact &result, size_t N)
|
|
LOCKS_EXCLUDED(access);
|
|
|
|
bool
|
|
select_random_hop_excluding(llarp::RouterContact &result,
|
|
const std::set< llarp::RouterID > &exclude)
|
|
LOCKS_EXCLUDED(access);
|
|
|
|
static bool
|
|
ensure_dir(const char *dir);
|
|
|
|
void
|
|
SaveAll() LOCKS_EXCLUDED(access);
|
|
};
|
|
|
|
/// struct for async rc verification
|
|
struct llarp_async_verify_rc;
|
|
|
|
using llarp_async_verify_rc_hook_func =
|
|
std::function< void(struct llarp_async_verify_rc *) >;
|
|
|
|
/// verify rc request
|
|
struct llarp_async_verify_rc
|
|
{
|
|
/// async_verify_context
|
|
void *user;
|
|
/// nodedb storage
|
|
llarp_nodedb *nodedb;
|
|
// llarp::Logic for queue_job
|
|
std::shared_ptr< llarp::Logic > logic;
|
|
std::shared_ptr< llarp::thread::ThreadPool > cryptoworker;
|
|
std::shared_ptr< llarp::thread::ThreadPool > diskworker;
|
|
|
|
/// router contact
|
|
llarp::RouterContact rc;
|
|
/// 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;
|
|
|
|
using llarp_async_load_rc_hook_func =
|
|
std::function< void(struct llarp_async_load_rc *) >;
|
|
|
|
struct llarp_async_load_rc
|
|
{
|
|
/// async_verify_context
|
|
void *user;
|
|
/// nodedb storage
|
|
llarp_nodedb *nodedb;
|
|
/// llarp::Logic for calling hook
|
|
llarp::Logic *logic;
|
|
/// disk worker threadpool
|
|
llarp::thread::ThreadPool *diskworker;
|
|
/// target pubkey
|
|
llarp::PubKey pubkey;
|
|
/// router contact result
|
|
llarp::RouterContact result;
|
|
/// 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);
|
|
|
|
#endif
|