lokinet/llarp/path/path_context.hpp

174 lines
4.0 KiB
C++
Raw Normal View History

#pragma once
#include "abstracthophandler.hpp"
#include "path_types.hpp"
#include "pathset.hpp"
#include "transit_hop.hpp"
#include <llarp/crypto/encrypted_frame.hpp>
#include <llarp/ev/ev.hpp>
#include <llarp/net/ip_address.hpp>
#include <llarp/util/compare_ptr.hpp>
#include <llarp/util/decaying_hashset.hpp>
#include <llarp/util/types.hpp>
2019-06-17 23:19:39 +00:00
#include <memory>
2019-12-03 17:03:19 +00:00
#include <unordered_map>
2019-06-17 23:19:39 +00:00
namespace llarp
{
struct Router;
2019-06-17 23:19:39 +00:00
struct RouterID;
namespace path
{
struct TransitHop;
struct TransitHopInfo;
using TransitHop_ptr = std::shared_ptr<TransitHop>;
2019-06-17 23:19:39 +00:00
struct PathContext
{
explicit PathContext(Router* router);
2019-06-17 23:19:39 +00:00
/// called from router tick function
void
ExpirePaths(llarp_time_t now);
2019-09-05 17:39:09 +00:00
void
PumpUpstream();
void
PumpDownstream();
2019-09-05 17:39:09 +00:00
2019-06-17 23:19:39 +00:00
void
AllowTransit();
void
RejectTransit();
2019-12-30 20:15:19 +00:00
bool
2020-05-06 20:38:44 +00:00
CheckPathLimitHitByIP(const IpAddress& ip);
2019-12-30 20:15:19 +00:00
bool
CheckPathLimitHitByIP(const std::string& ip);
2019-06-17 23:19:39 +00:00
bool
AllowingTransit() const;
bool
HasTransitHop(const TransitHopInfo& info);
void
PutTransitHop(std::shared_ptr<TransitHop> hop);
2019-06-17 23:19:39 +00:00
HopHandler_ptr
GetByUpstream(const RouterID& id, const PathID_t& path);
bool
TransitHopPreviousIsRouter(const PathID_t& path, const RouterID& r);
2019-11-21 14:48:31 +00:00
TransitHop_ptr
2019-06-17 23:19:39 +00:00
GetPathForTransfer(const PathID_t& topath);
HopHandler_ptr
GetByDownstream(const RouterID& id, const PathID_t& path);
2021-06-07 12:39:38 +00:00
std::optional<std::weak_ptr<TransitHop>>
TransitHopByInfo(const TransitHopInfo&);
std::optional<std::weak_ptr<TransitHop>>
TransitHopByUpstream(const RouterID&, const PathID_t&);
2019-06-17 23:19:39 +00:00
PathSet_ptr
GetLocalPathSet(const PathID_t& id);
using EndpointPathPtrSet = std::set<Path_ptr, ComparePtr<Path_ptr>>;
2019-06-17 23:19:39 +00:00
/// get a set of all paths that we own who's endpoint is r
EndpointPathPtrSet
FindOwnedPathsWithEndpoint(const RouterID& r);
bool
HopIsUs(const RouterID& k) const;
void
AddOwnPath(PathSet_ptr set, Path_ptr p);
void
RemovePathSet(PathSet_ptr set);
using TransitHopsMap_t = std::unordered_multimap<PathID_t, TransitHop_ptr>;
2019-06-17 23:19:39 +00:00
struct SyncTransitMap_t
{
2019-09-04 12:24:17 +00:00
using Mutex_t = util::NullMutex;
using Lock_t = util::NullLock;
2019-09-04 12:24:17 +00:00
Mutex_t first; // protects second
2023-10-25 19:43:32 +00:00
TransitHopsMap_t second;
2019-06-17 23:19:39 +00:00
/// Invokes a callback for each transit path; visit must be invokable with a `const
/// TransitHop_ptr&` argument.
template <typename TransitHopVisitor>
2019-06-17 23:19:39 +00:00
void
2023-10-25 19:43:32 +00:00
ForEach(TransitHopVisitor&& visit)
2019-06-17 23:19:39 +00:00
{
De-abseil, part 2: mutex, locks, (most) time - util::Mutex is now a std::shared_timed_mutex, which is capable of exclusive and shared locks. - util::Lock is still present as a std::lock_guard<util::Mutex>. - the locking annotations are preserved, but updated to the latest supported by clang rather than using abseil's older/deprecated ones. - ACQUIRE_LOCK macro is gone since we don't pass mutexes by pointer into locks anymore (WTF abseil). - ReleasableLock is gone. Instead there are now some llarp::util helper methods to obtain unique and/or shared locks: - `auto lock = util::unique_lock(mutex);` gets an RAII-but-also unlockable object (std::unique_lock<T>, with T inferred from `mutex`). - `auto lock = util::shared_lock(mutex);` gets an RAII shared (i.e. "reader") lock of the mutex. - `auto lock = util::unique_locks(mutex1, mutex2, mutex3);` can be used to atomically lock multiple mutexes at once (returning a tuple of the locks). This are templated on the mutex which makes them a bit more flexible than using a concrete type: they can be used for any type of lockable mutex, not only util::Mutex. (Some of the code here uses them for getting locks around a std::mutex). Until C++17, using the RAII types is painfully verbose: ```C++ // pre-C++17 - needing to figure out the mutex type here is annoying: std::unique_lock<util::Mutex> lock(mutex); // pre-C++17 and even more verbose (but at least the type isn't needed): std::unique_lock<decltype(mutex)> lock(mutex); // our compromise: auto lock = util::unique_lock(mutex); // C++17: std::unique_lock lock(mutex); ``` All of these functions will also warn (under gcc or clang) if you discard the return value. You can also do fancy things like `auto l = util::unique_lock(mutex, std::adopt_lock)` (which lets a lock take over an already-locked mutex). - metrics code is gone, which also removes a big pile of code that was only used by metrics: - llarp::util::Scheduler - llarp::thread::TimerQueue - llarp::util::Stopwatch
2020-02-21 17:21:11 +00:00
Lock_t lock(first);
for (const auto& item : second)
2019-06-17 23:19:39 +00:00
visit(item.second);
}
};
// maps path id -> pathset owner of path
using OwnedPathsMap_t = std::unordered_map<PathID_t, Path_ptr>;
2019-06-17 23:19:39 +00:00
struct SyncOwnedPathsMap_t
{
De-abseil, part 2: mutex, locks, (most) time - util::Mutex is now a std::shared_timed_mutex, which is capable of exclusive and shared locks. - util::Lock is still present as a std::lock_guard<util::Mutex>. - the locking annotations are preserved, but updated to the latest supported by clang rather than using abseil's older/deprecated ones. - ACQUIRE_LOCK macro is gone since we don't pass mutexes by pointer into locks anymore (WTF abseil). - ReleasableLock is gone. Instead there are now some llarp::util helper methods to obtain unique and/or shared locks: - `auto lock = util::unique_lock(mutex);` gets an RAII-but-also unlockable object (std::unique_lock<T>, with T inferred from `mutex`). - `auto lock = util::shared_lock(mutex);` gets an RAII shared (i.e. "reader") lock of the mutex. - `auto lock = util::unique_locks(mutex1, mutex2, mutex3);` can be used to atomically lock multiple mutexes at once (returning a tuple of the locks). This are templated on the mutex which makes them a bit more flexible than using a concrete type: they can be used for any type of lockable mutex, not only util::Mutex. (Some of the code here uses them for getting locks around a std::mutex). Until C++17, using the RAII types is painfully verbose: ```C++ // pre-C++17 - needing to figure out the mutex type here is annoying: std::unique_lock<util::Mutex> lock(mutex); // pre-C++17 and even more verbose (but at least the type isn't needed): std::unique_lock<decltype(mutex)> lock(mutex); // our compromise: auto lock = util::unique_lock(mutex); // C++17: std::unique_lock lock(mutex); ``` All of these functions will also warn (under gcc or clang) if you discard the return value. You can also do fancy things like `auto l = util::unique_lock(mutex, std::adopt_lock)` (which lets a lock take over an already-locked mutex). - metrics code is gone, which also removes a big pile of code that was only used by metrics: - llarp::util::Scheduler - llarp::thread::TimerQueue - llarp::util::Stopwatch
2020-02-21 17:21:11 +00:00
util::Mutex first; // protects second
2023-10-25 19:43:32 +00:00
OwnedPathsMap_t second;
2019-06-17 23:19:39 +00:00
/// Invokes a callback for each owned path; visit must be invokable with a `const Path_ptr&`
/// argument.
template <typename OwnedHopVisitor>
2019-06-17 23:19:39 +00:00
void
ForEach(OwnedHopVisitor&& visit)
2019-06-17 23:19:39 +00:00
{
De-abseil, part 2: mutex, locks, (most) time - util::Mutex is now a std::shared_timed_mutex, which is capable of exclusive and shared locks. - util::Lock is still present as a std::lock_guard<util::Mutex>. - the locking annotations are preserved, but updated to the latest supported by clang rather than using abseil's older/deprecated ones. - ACQUIRE_LOCK macro is gone since we don't pass mutexes by pointer into locks anymore (WTF abseil). - ReleasableLock is gone. Instead there are now some llarp::util helper methods to obtain unique and/or shared locks: - `auto lock = util::unique_lock(mutex);` gets an RAII-but-also unlockable object (std::unique_lock<T>, with T inferred from `mutex`). - `auto lock = util::shared_lock(mutex);` gets an RAII shared (i.e. "reader") lock of the mutex. - `auto lock = util::unique_locks(mutex1, mutex2, mutex3);` can be used to atomically lock multiple mutexes at once (returning a tuple of the locks). This are templated on the mutex which makes them a bit more flexible than using a concrete type: they can be used for any type of lockable mutex, not only util::Mutex. (Some of the code here uses them for getting locks around a std::mutex). Until C++17, using the RAII types is painfully verbose: ```C++ // pre-C++17 - needing to figure out the mutex type here is annoying: std::unique_lock<util::Mutex> lock(mutex); // pre-C++17 and even more verbose (but at least the type isn't needed): std::unique_lock<decltype(mutex)> lock(mutex); // our compromise: auto lock = util::unique_lock(mutex); // C++17: std::unique_lock lock(mutex); ``` All of these functions will also warn (under gcc or clang) if you discard the return value. You can also do fancy things like `auto l = util::unique_lock(mutex, std::adopt_lock)` (which lets a lock take over an already-locked mutex). - metrics code is gone, which also removes a big pile of code that was only used by metrics: - llarp::util::Scheduler - llarp::thread::TimerQueue - llarp::util::Stopwatch
2020-02-21 17:21:11 +00:00
util::Lock lock(first);
for (const auto& item : second)
2019-06-17 23:19:39 +00:00
visit(item.second);
}
};
const EventLoop_ptr&
loop();
2019-06-17 23:19:39 +00:00
const SecretKey&
EncryptionSecretKey();
const byte_t*
OurRouterID() const;
2020-02-25 22:32:57 +00:00
/// current number of transit paths we have
uint64_t
2020-03-03 23:04:09 +00:00
CurrentTransitPaths();
2020-02-25 22:32:57 +00:00
/// current number of paths we created in status
uint64_t
CurrentOwnedPaths(path::PathStatus status = path::PathStatus::ePathEstablished);
Router*
router() const
{
return _router;
}
2019-06-17 23:19:39 +00:00
private:
Router* _router;
2019-06-17 23:19:39 +00:00
SyncTransitMap_t m_TransitPaths;
SyncOwnedPathsMap_t m_OurPaths;
bool m_AllowTransit;
util::DecayingHashSet<IpAddress> path_limits;
2019-06-17 23:19:39 +00:00
};
} // namespace path
} // namespace llarp