2018-12-12 02:52:51 +00:00
|
|
|
#include <profiling.hpp>
|
|
|
|
|
2018-09-13 16:41:53 +00:00
|
|
|
#include <fstream>
|
|
|
|
|
|
|
|
namespace llarp
|
|
|
|
{
|
|
|
|
bool
|
|
|
|
RouterProfile::BEncode(llarp_buffer_t* buf) const
|
|
|
|
{
|
|
|
|
if(!bencode_start_dict(buf))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if(!BEncodeWriteDictInt("g", connectGoodCount, buf))
|
|
|
|
return false;
|
2018-09-14 14:50:37 +00:00
|
|
|
if(!BEncodeWriteDictInt("p", pathSuccessCount, buf))
|
|
|
|
return false;
|
|
|
|
if(!BEncodeWriteDictInt("s", pathFailCount, buf))
|
|
|
|
return false;
|
2018-09-13 16:41:53 +00:00
|
|
|
if(!BEncodeWriteDictInt("t", connectTimeoutCount, buf))
|
|
|
|
return false;
|
2019-03-04 17:03:18 +00:00
|
|
|
if(!BEncodeWriteDictInt("u", lastUpdated, buf))
|
|
|
|
return false;
|
2018-09-13 16:41:53 +00:00
|
|
|
if(!BEncodeWriteDictInt("v", version, buf))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return bencode_end(buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2019-02-02 23:12:42 +00:00
|
|
|
RouterProfile::DecodeKey(const llarp_buffer_t& k, llarp_buffer_t* buf)
|
2018-09-13 16:41:53 +00:00
|
|
|
{
|
|
|
|
bool read = false;
|
|
|
|
if(!BEncodeMaybeReadDictInt("g", connectGoodCount, read, k, buf))
|
|
|
|
return false;
|
|
|
|
if(!BEncodeMaybeReadDictInt("t", connectTimeoutCount, read, k, buf))
|
|
|
|
return false;
|
2019-03-04 17:03:18 +00:00
|
|
|
if(!BEncodeMaybeReadDictInt("u", lastUpdated, read, k, buf))
|
|
|
|
return false;
|
2018-09-13 16:41:53 +00:00
|
|
|
if(!BEncodeMaybeReadDictInt("v", version, read, k, buf))
|
|
|
|
return false;
|
2018-09-14 14:50:37 +00:00
|
|
|
if(!BEncodeMaybeReadDictInt("s", pathFailCount, read, k, buf))
|
|
|
|
return false;
|
|
|
|
if(!BEncodeMaybeReadDictInt("p", pathSuccessCount, read, k, buf))
|
|
|
|
return false;
|
2018-09-13 16:41:53 +00:00
|
|
|
return read;
|
|
|
|
}
|
|
|
|
|
2019-03-04 17:03:18 +00:00
|
|
|
void
|
2019-03-05 13:38:50 +00:00
|
|
|
RouterProfile::Decay()
|
2019-03-04 17:03:18 +00:00
|
|
|
{
|
2019-03-05 13:38:50 +00:00
|
|
|
connectGoodCount /= 2;
|
|
|
|
connectTimeoutCount /= 2;
|
|
|
|
pathSuccessCount /= 2;
|
|
|
|
pathFailCount /= 2;
|
|
|
|
lastUpdated = llarp::time_now_ms();
|
2019-03-04 17:03:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
RouterProfile::Tick()
|
|
|
|
{
|
2019-03-22 16:45:04 +00:00
|
|
|
// 5 minutes
|
2019-04-05 14:58:22 +00:00
|
|
|
static constexpr llarp_time_t updateInterval = path::default_lifetime / 2;
|
2019-03-04 17:03:18 +00:00
|
|
|
auto now = llarp::time_now_ms();
|
|
|
|
if(lastUpdated < now && now - lastUpdated > updateInterval)
|
|
|
|
{
|
2019-03-05 13:38:50 +00:00
|
|
|
Decay();
|
2019-03-04 17:03:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-13 16:41:53 +00:00
|
|
|
bool
|
2018-09-14 14:50:37 +00:00
|
|
|
RouterProfile::IsGood(uint64_t chances) const
|
2018-09-13 16:41:53 +00:00
|
|
|
{
|
2019-03-11 13:58:31 +00:00
|
|
|
if(connectTimeoutCount > chances)
|
2019-04-05 14:58:22 +00:00
|
|
|
return connectTimeoutCount < connectGoodCount
|
|
|
|
&& (pathSuccessCount * chances) > pathFailCount;
|
|
|
|
return (pathSuccessCount * chances) > pathFailCount;
|
2018-09-13 16:41:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2018-09-14 14:50:37 +00:00
|
|
|
Profiling::IsBad(const RouterID& r, uint64_t chances)
|
2018-09-13 16:41:53 +00:00
|
|
|
{
|
2019-03-03 15:01:05 +00:00
|
|
|
lock_t lock(&m_ProfilesMutex);
|
2018-09-13 16:41:53 +00:00
|
|
|
auto itr = m_Profiles.find(r);
|
|
|
|
if(itr == m_Profiles.end())
|
|
|
|
return false;
|
2018-09-14 14:50:37 +00:00
|
|
|
return !itr->second.IsGood(chances);
|
2018-09-13 16:41:53 +00:00
|
|
|
}
|
|
|
|
|
2019-03-04 17:03:18 +00:00
|
|
|
void
|
|
|
|
Profiling::Tick()
|
|
|
|
{
|
2019-03-06 00:54:35 +00:00
|
|
|
lock_t lock(&m_ProfilesMutex);
|
2019-03-04 17:03:18 +00:00
|
|
|
std::for_each(m_Profiles.begin(), m_Profiles.end(),
|
|
|
|
[](auto& item) { item.second.Tick(); });
|
|
|
|
}
|
|
|
|
|
2018-09-13 16:41:53 +00:00
|
|
|
void
|
|
|
|
Profiling::MarkTimeout(const RouterID& r)
|
|
|
|
{
|
2019-03-03 15:01:05 +00:00
|
|
|
lock_t lock(&m_ProfilesMutex);
|
2018-09-13 16:41:53 +00:00
|
|
|
m_Profiles[r].connectTimeoutCount += 1;
|
2019-03-04 17:03:18 +00:00
|
|
|
m_Profiles[r].lastUpdated = llarp::time_now_ms();
|
2018-09-13 16:41:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Profiling::MarkSuccess(const RouterID& r)
|
|
|
|
{
|
2019-03-03 15:01:05 +00:00
|
|
|
lock_t lock(&m_ProfilesMutex);
|
2018-09-13 16:41:53 +00:00
|
|
|
m_Profiles[r].connectGoodCount += 1;
|
2019-03-04 17:03:18 +00:00
|
|
|
m_Profiles[r].lastUpdated = llarp::time_now_ms();
|
2018-09-13 16:41:53 +00:00
|
|
|
}
|
|
|
|
|
2019-03-31 15:25:13 +00:00
|
|
|
void
|
|
|
|
Profiling::ClearProfile(const RouterID& r)
|
|
|
|
{
|
|
|
|
lock_t lock(&m_ProfilesMutex);
|
|
|
|
m_Profiles.erase(r);
|
|
|
|
}
|
|
|
|
|
2018-09-14 14:50:37 +00:00
|
|
|
void
|
|
|
|
Profiling::MarkPathFail(path::Path* p)
|
|
|
|
{
|
2019-03-03 15:01:05 +00:00
|
|
|
lock_t lock(&m_ProfilesMutex);
|
2018-09-14 14:50:37 +00:00
|
|
|
for(const auto& hop : p->hops)
|
|
|
|
{
|
|
|
|
// TODO: also mark bad?
|
|
|
|
m_Profiles[hop.rc.pubkey].pathFailCount += 1;
|
2019-03-04 17:03:18 +00:00
|
|
|
m_Profiles[hop.rc.pubkey].lastUpdated = llarp::time_now_ms();
|
2018-09-14 14:50:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Profiling::MarkPathSuccess(path::Path* p)
|
|
|
|
{
|
2019-03-03 15:01:05 +00:00
|
|
|
lock_t lock(&m_ProfilesMutex);
|
2019-03-25 15:41:37 +00:00
|
|
|
const auto sz = p->hops.size();
|
2018-09-14 14:50:37 +00:00
|
|
|
for(const auto& hop : p->hops)
|
|
|
|
{
|
2019-03-25 15:41:37 +00:00
|
|
|
m_Profiles[hop.rc.pubkey].pathSuccessCount += sz;
|
2019-03-04 17:03:18 +00:00
|
|
|
m_Profiles[hop.rc.pubkey].lastUpdated = llarp::time_now_ms();
|
2018-09-14 14:50:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-13 16:41:53 +00:00
|
|
|
bool
|
|
|
|
Profiling::Save(const char* fname)
|
|
|
|
{
|
2019-03-03 20:51:47 +00:00
|
|
|
absl::ReaderMutexLock lock(&m_ProfilesMutex);
|
2018-09-13 16:41:53 +00:00
|
|
|
size_t sz = (m_Profiles.size() * (RouterProfile::MaxSize + 32 + 8)) + 8;
|
|
|
|
|
2019-01-17 14:02:50 +00:00
|
|
|
std::vector< byte_t > tmp(sz, 0);
|
2019-02-02 23:12:42 +00:00
|
|
|
llarp_buffer_t buf(tmp);
|
2019-03-03 20:51:47 +00:00
|
|
|
auto res = BEncodeNoLock(&buf);
|
2018-09-13 16:41:53 +00:00
|
|
|
if(res)
|
|
|
|
{
|
|
|
|
buf.sz = buf.cur - buf.base;
|
|
|
|
std::ofstream f;
|
|
|
|
f.open(fname);
|
|
|
|
if(f.is_open())
|
|
|
|
{
|
|
|
|
f.write((char*)buf.base, buf.sz);
|
2019-03-25 15:41:37 +00:00
|
|
|
m_LastSave = llarp::time_now_ms();
|
2018-09-13 16:41:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
Profiling::BEncode(llarp_buffer_t* buf) const
|
2019-03-03 20:51:47 +00:00
|
|
|
{
|
|
|
|
absl::ReaderMutexLock lock(&m_ProfilesMutex);
|
|
|
|
return BEncodeNoLock(buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
Profiling::BEncodeNoLock(llarp_buffer_t* buf) const
|
2018-09-13 16:41:53 +00:00
|
|
|
{
|
|
|
|
if(!bencode_start_dict(buf))
|
|
|
|
return false;
|
2019-03-03 20:51:47 +00:00
|
|
|
|
2018-09-13 16:41:53 +00:00
|
|
|
auto itr = m_Profiles.begin();
|
|
|
|
while(itr != m_Profiles.end())
|
|
|
|
{
|
|
|
|
if(!itr->first.BEncode(buf))
|
|
|
|
return false;
|
|
|
|
if(!itr->second.BEncode(buf))
|
|
|
|
return false;
|
|
|
|
++itr;
|
|
|
|
}
|
|
|
|
return bencode_end(buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2019-02-02 23:12:42 +00:00
|
|
|
Profiling::DecodeKey(const llarp_buffer_t& k, llarp_buffer_t* buf)
|
2018-09-13 16:41:53 +00:00
|
|
|
{
|
|
|
|
if(k.sz != 32)
|
|
|
|
return false;
|
|
|
|
RouterProfile profile;
|
|
|
|
if(!profile.BDecode(buf))
|
|
|
|
return false;
|
|
|
|
RouterID pk = k.base;
|
2019-02-18 10:35:16 +00:00
|
|
|
return m_Profiles.emplace(pk, profile).second;
|
2018-09-13 16:41:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
Profiling::Load(const char* fname)
|
|
|
|
{
|
2019-03-03 15:01:05 +00:00
|
|
|
lock_t lock(&m_ProfilesMutex);
|
2018-09-13 16:41:53 +00:00
|
|
|
m_Profiles.clear();
|
2018-09-15 11:37:46 +00:00
|
|
|
if(!BDecodeReadFile(fname, *this))
|
|
|
|
{
|
|
|
|
llarp::LogWarn("failed to load router profiles from ", fname);
|
|
|
|
return false;
|
|
|
|
}
|
2019-04-12 12:05:43 +00:00
|
|
|
m_LastSave = llarp::time_now_ms();
|
2018-09-15 11:37:46 +00:00
|
|
|
return true;
|
2018-09-13 16:41:53 +00:00
|
|
|
}
|
|
|
|
|
2019-03-25 15:41:37 +00:00
|
|
|
bool
|
|
|
|
Profiling::ShouldSave(llarp_time_t now) const
|
|
|
|
{
|
|
|
|
auto dlt = now - m_LastSave;
|
|
|
|
return dlt > 60000;
|
|
|
|
}
|
2018-09-13 16:41:53 +00:00
|
|
|
} // namespace llarp
|