2021-03-09 22:24:35 +00:00
|
|
|
#pragma once
|
|
|
|
|
2023-10-24 13:18:03 +00:00
|
|
|
#include "abstracthophandler.hpp"
|
|
|
|
#include "path_types.hpp"
|
|
|
|
#include "pathset.hpp"
|
|
|
|
#include "transit_hop.hpp"
|
|
|
|
|
2023-10-19 11:49:46 +00:00
|
|
|
#include <llarp/crypto/encrypted_frame.hpp>
|
2023-10-24 13:18:03 +00:00
|
|
|
#include <llarp/ev/ev.hpp>
|
2023-10-19 11:49:46 +00:00
|
|
|
#include <llarp/net/ip_address.hpp>
|
2021-03-09 22:24:35 +00:00
|
|
|
#include <llarp/util/compare_ptr.hpp>
|
|
|
|
#include <llarp/util/decaying_hashset.hpp>
|
|
|
|
#include <llarp/util/types.hpp>
|
2023-10-24 13:18:03 +00:00
|
|
|
|
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
|
|
|
|
{
|
2023-09-15 14:55:32 +00:00
|
|
|
struct Router;
|
2019-06-17 23:19:39 +00:00
|
|
|
struct RouterID;
|
|
|
|
|
|
|
|
namespace path
|
|
|
|
{
|
|
|
|
struct TransitHop;
|
|
|
|
struct TransitHopInfo;
|
|
|
|
|
2020-04-07 18:38:56 +00:00
|
|
|
using TransitHop_ptr = std::shared_ptr<TransitHop>;
|
2019-06-17 23:19:39 +00:00
|
|
|
|
|
|
|
struct PathContext
|
|
|
|
{
|
2023-09-15 14:55:32 +00:00
|
|
|
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
|
2019-09-16 10:21:12 +00:00
|
|
|
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
|
|
|
|
2023-09-29 21:00:13 +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
|
2020-04-07 18:38:56 +00:00
|
|
|
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);
|
|
|
|
|
2020-04-07 18:38:56 +00:00
|
|
|
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);
|
|
|
|
|
2021-03-09 18:39:40 +00:00
|
|
|
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;
|
2020-04-07 18:38:56 +00:00
|
|
|
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
|
|
|
|
2021-11-09 17:52:03 +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);
|
2020-04-07 18:38:56 +00:00
|
|
|
for (const auto& item : second)
|
2019-06-17 23:19:39 +00:00
|
|
|
visit(item.second);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// maps path id -> pathset owner of path
|
2021-03-09 18:39:40 +00:00
|
|
|
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
|
|
|
|
2021-11-09 17:52:03 +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
|
2021-11-09 17:52:03 +00:00
|
|
|
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);
|
2020-04-07 18:38:56 +00:00
|
|
|
for (const auto& item : second)
|
2019-06-17 23:19:39 +00:00
|
|
|
visit(item.second);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2021-03-02 07:02:59 +00:00
|
|
|
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
|
|
|
|
2022-01-13 21:24:08 +00:00
|
|
|
/// current number of paths we created in status
|
|
|
|
uint64_t
|
|
|
|
CurrentOwnedPaths(path::PathStatus status = path::PathStatus::ePathEstablished);
|
|
|
|
|
2023-09-21 14:20:49 +00:00
|
|
|
Router*
|
|
|
|
router() const
|
|
|
|
{
|
|
|
|
return _router;
|
|
|
|
}
|
|
|
|
|
2019-06-17 23:19:39 +00:00
|
|
|
private:
|
2023-09-21 14:20:49 +00:00
|
|
|
Router* _router;
|
2019-06-17 23:19:39 +00:00
|
|
|
SyncTransitMap_t m_TransitPaths;
|
|
|
|
SyncOwnedPathsMap_t m_OurPaths;
|
|
|
|
bool m_AllowTransit;
|
2023-09-29 21:00:13 +00:00
|
|
|
util::DecayingHashSet<IpAddress> path_limits;
|
2019-06-17 23:19:39 +00:00
|
|
|
};
|
|
|
|
} // namespace path
|
|
|
|
} // namespace llarp
|