2021-03-09 22:24:35 +00:00
|
|
|
#pragma once
|
2018-12-12 02:52:51 +00:00
|
|
|
|
2021-03-09 22:24:35 +00:00
|
|
|
#include "path/path.hpp"
|
|
|
|
#include "router_id.hpp"
|
|
|
|
#include "util/bencode.hpp"
|
|
|
|
#include "util/thread/threading.hpp"
|
2018-09-13 16:41:53 +00:00
|
|
|
|
2021-03-09 22:24:35 +00:00
|
|
|
#include "util/thread/annotations.hpp"
|
2018-09-13 16:41:53 +00:00
|
|
|
#include <map>
|
|
|
|
|
|
|
|
namespace llarp
|
|
|
|
{
|
2019-05-24 02:01:36 +00:00
|
|
|
struct RouterProfile
|
2018-09-13 16:41:53 +00:00
|
|
|
{
|
2018-09-14 14:50:37 +00:00
|
|
|
static constexpr size_t MaxSize = 256;
|
2020-04-07 18:38:56 +00:00
|
|
|
uint64_t connectTimeoutCount = 0;
|
|
|
|
uint64_t connectGoodCount = 0;
|
|
|
|
uint64_t pathSuccessCount = 0;
|
|
|
|
uint64_t pathFailCount = 0;
|
2020-10-27 21:34:09 +00:00
|
|
|
uint64_t pathTimeoutCount = 0;
|
2020-04-07 18:38:56 +00:00
|
|
|
llarp_time_t lastUpdated = 0s;
|
|
|
|
llarp_time_t lastDecay = 0s;
|
|
|
|
uint64_t version = LLARP_PROTO_VERSION;
|
2018-09-13 16:41:53 +00:00
|
|
|
|
|
|
|
bool
|
2019-05-24 02:01:36 +00:00
|
|
|
BEncode(llarp_buffer_t* buf) const;
|
2018-09-13 16:41:53 +00:00
|
|
|
|
|
|
|
bool
|
2019-05-24 02:01:36 +00:00
|
|
|
DecodeKey(const llarp_buffer_t& k, llarp_buffer_t* buf);
|
2018-09-13 16:41:53 +00:00
|
|
|
|
|
|
|
bool
|
2018-09-14 14:50:37 +00:00
|
|
|
IsGood(uint64_t chances) const;
|
2019-03-04 17:03:18 +00:00
|
|
|
|
2019-04-16 11:44:55 +00:00
|
|
|
bool
|
|
|
|
IsGoodForConnect(uint64_t chances) const;
|
|
|
|
|
|
|
|
bool
|
|
|
|
IsGoodForPath(uint64_t chances) const;
|
|
|
|
|
2019-03-05 13:38:50 +00:00
|
|
|
/// decay stats
|
2019-03-04 17:03:18 +00:00
|
|
|
void
|
2019-03-05 13:38:50 +00:00
|
|
|
Decay();
|
2019-03-04 17:03:18 +00:00
|
|
|
|
|
|
|
// rotate stats if timeout reached
|
|
|
|
void
|
|
|
|
Tick();
|
2018-09-13 16:41:53 +00:00
|
|
|
};
|
|
|
|
|
2019-05-24 02:01:36 +00:00
|
|
|
struct Profiling
|
2018-09-13 16:41:53 +00:00
|
|
|
{
|
2019-04-25 11:00:18 +00:00
|
|
|
Profiling();
|
2018-09-13 16:41:53 +00:00
|
|
|
|
2021-05-04 21:01:29 +00:00
|
|
|
inline static const int profiling_chances = 4;
|
|
|
|
|
2019-04-16 11:44:55 +00:00
|
|
|
/// generic variant
|
2018-09-13 16:41:53 +00:00
|
|
|
bool
|
2021-05-04 21:01:29 +00:00
|
|
|
IsBad(const RouterID& r, uint64_t chances = profiling_chances) EXCLUDES(m_ProfilesMutex);
|
2018-09-13 16:41:53 +00:00
|
|
|
|
2019-05-24 02:01:36 +00:00
|
|
|
/// check if this router should have paths built over it
|
2019-04-16 13:20:48 +00:00
|
|
|
bool
|
2021-05-04 21:01:29 +00:00
|
|
|
IsBadForPath(const RouterID& r, uint64_t chances = profiling_chances) EXCLUDES(m_ProfilesMutex);
|
2019-04-16 11:44:55 +00:00
|
|
|
|
|
|
|
/// check if this router should be connected directly to
|
2019-04-16 13:20:48 +00:00
|
|
|
bool
|
2021-05-04 21:01:29 +00:00
|
|
|
IsBadForConnect(const RouterID& r, uint64_t chances = profiling_chances)
|
|
|
|
EXCLUDES(m_ProfilesMutex);
|
2019-04-16 11:44:55 +00:00
|
|
|
|
2018-09-13 16:41:53 +00:00
|
|
|
void
|
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
|
|
|
MarkConnectTimeout(const RouterID& r) EXCLUDES(m_ProfilesMutex);
|
2018-09-13 16:41:53 +00:00
|
|
|
|
|
|
|
void
|
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
|
|
|
MarkConnectSuccess(const RouterID& r) EXCLUDES(m_ProfilesMutex);
|
2019-03-03 20:51:47 +00:00
|
|
|
|
2020-10-27 21:34:09 +00:00
|
|
|
void
|
|
|
|
MarkPathTimeout(path::Path* p) EXCLUDES(m_ProfilesMutex);
|
|
|
|
|
2019-03-03 20:51:47 +00:00
|
|
|
void
|
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
|
|
|
MarkPathFail(path::Path* p) EXCLUDES(m_ProfilesMutex);
|
2019-03-03 20:51:47 +00:00
|
|
|
|
|
|
|
void
|
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
|
|
|
MarkPathSuccess(path::Path* p) EXCLUDES(m_ProfilesMutex);
|
2018-09-13 16:41:53 +00:00
|
|
|
|
2020-01-03 12:52:19 +00:00
|
|
|
void
|
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
|
|
|
MarkHopFail(const RouterID& r) EXCLUDES(m_ProfilesMutex);
|
2020-01-03 12:52:19 +00:00
|
|
|
|
2019-03-31 15:25:13 +00:00
|
|
|
void
|
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
|
|
|
ClearProfile(const RouterID& r) EXCLUDES(m_ProfilesMutex);
|
2019-03-31 15:25:13 +00:00
|
|
|
|
2019-03-04 17:03:18 +00:00
|
|
|
void
|
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
|
|
|
Tick() EXCLUDES(m_ProfilesMutex);
|
2019-03-04 17:03:18 +00:00
|
|
|
|
2018-09-13 16:41:53 +00:00
|
|
|
bool
|
2020-11-05 11:19:43 +00:00
|
|
|
BEncode(llarp_buffer_t* buf) const;
|
2018-09-13 16:41:53 +00:00
|
|
|
|
2020-11-03 15:54:55 +00:00
|
|
|
bool
|
|
|
|
BDecode(llarp_buffer_t* buf);
|
|
|
|
|
2018-09-13 16:41:53 +00:00
|
|
|
bool
|
2020-04-07 18:38:56 +00:00
|
|
|
DecodeKey(const llarp_buffer_t& k, llarp_buffer_t* buf) NO_THREAD_SAFETY_ANALYSIS;
|
2019-05-24 02:01:36 +00:00
|
|
|
// disabled because we do load -> bencode::BDecodeReadFromFile -> DecodeKey
|
2018-09-13 16:41:53 +00:00
|
|
|
|
|
|
|
bool
|
2020-11-03 15:54:55 +00:00
|
|
|
Load(const fs::path fname) EXCLUDES(m_ProfilesMutex);
|
2018-09-13 16:41:53 +00:00
|
|
|
|
|
|
|
bool
|
2020-11-03 15:54:55 +00:00
|
|
|
Save(const fs::path fname) EXCLUDES(m_ProfilesMutex);
|
2018-09-14 14:50:37 +00:00
|
|
|
|
2019-03-25 15:41:37 +00:00
|
|
|
bool
|
|
|
|
ShouldSave(llarp_time_t now) const;
|
|
|
|
|
2019-04-25 11:00:18 +00:00
|
|
|
void
|
|
|
|
Disable();
|
|
|
|
|
|
|
|
void
|
|
|
|
Enable();
|
|
|
|
|
2018-09-13 16:41:53 +00:00
|
|
|
private:
|
2019-03-03 20:51:47 +00:00
|
|
|
mutable util::Mutex m_ProfilesMutex; // protects m_Profiles
|
2020-04-07 18:38:56 +00:00
|
|
|
std::map<RouterID, RouterProfile> m_Profiles GUARDED_BY(m_ProfilesMutex);
|
2020-02-24 19:40:45 +00:00
|
|
|
llarp_time_t m_LastSave = 0s;
|
2020-04-07 18:38:56 +00:00
|
|
|
std::atomic<bool> m_DisableProfiling;
|
2018-09-13 16:41:53 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace llarp
|