lokinet/llarp/path/path_context.cpp

363 lines
9.3 KiB
C++
Raw Normal View History

2019-06-17 23:19:39 +00:00
#include <path/path_context.hpp>
#include <messages/relay_commit.hpp>
#include <path/path.hpp>
#include <router/abstractrouter.hpp>
#include <router/i_outbound_message_handler.hpp>
2019-06-17 23:19:39 +00:00
namespace llarp
{
namespace path
{
static constexpr llarp_time_t DefaultPathBuildLimit = 500;
2019-06-17 23:19:39 +00:00
PathContext::PathContext(AbstractRouter* router)
: m_Router(router)
, m_AllowTransit(false)
, m_PathLimits(DefaultPathBuildLimit)
2019-06-17 23:19:39 +00:00
{
}
void
PathContext::AllowTransit()
{
m_AllowTransit = true;
}
bool
PathContext::AllowingTransit() const
{
return m_AllowTransit;
}
2019-07-09 13:47:24 +00:00
std::shared_ptr< thread::ThreadPool >
2019-06-17 23:19:39 +00:00
PathContext::Worker()
{
return m_Router->threadpool();
}
2019-12-30 20:15:19 +00:00
bool
PathContext::CheckPathLimitHitByIP(const llarp::Addr& ip)
{
2020-01-14 01:01:33 +00:00
#ifdef TESTNET
return false;
#else
2019-12-30 20:15:19 +00:00
llarp::Addr remote = ip;
2019-12-30 20:55:56 +00:00
// set port to zero
2019-12-30 20:15:19 +00:00
remote.port(0);
2019-12-30 20:55:56 +00:00
// try inserting remote address by ip into decaying hash set
// if it cannot insert it has hit a limit
2019-12-30 20:15:19 +00:00
return not m_PathLimits.Insert(remote);
2020-01-14 01:01:33 +00:00
#endif
2019-12-30 20:15:19 +00:00
}
2019-06-17 23:19:39 +00:00
std::shared_ptr< Logic >
PathContext::logic()
{
return m_Router->logic();
}
const SecretKey&
PathContext::EncryptionSecretKey()
{
return m_Router->encryption();
}
bool
PathContext::HopIsUs(const RouterID& k) const
{
return std::equal(m_Router->pubkey(), m_Router->pubkey() + PUBKEYSIZE,
k.begin());
}
PathContext::EndpointPathPtrSet
PathContext::FindOwnedPathsWithEndpoint(const RouterID& r)
{
EndpointPathPtrSet found;
2019-12-03 15:52:06 +00:00
m_OurPaths.ForEach([&](const Path_ptr& p) {
if(p->Endpoint() == r && p->IsReady())
found.insert(p);
2019-06-17 23:19:39 +00:00
});
return found;
}
bool
PathContext::ForwardLRCM(const RouterID& nextHop,
const std::array< EncryptedFrame, 8 >& frames,
SendStatusHandler handler)
2019-06-17 23:19:39 +00:00
{
if(handler == nullptr)
{
LogError("Calling ForwardLRCM without passing result handler");
return false;
}
2019-06-17 23:19:39 +00:00
auto msg = std::make_shared< const LR_CommitMessage >(frames);
LogDebug("forwarding LRCM to ", nextHop);
m_Router->SendToOrQueue(nextHop, msg.get(), handler);
2019-06-17 23:19:39 +00:00
return true;
}
2019-09-04 12:41:07 +00:00
template < typename Lock_t, typename Map_t, typename Key_t,
typename CheckValue_t, typename GetFunc_t >
2019-06-17 23:19:39 +00:00
HopHandler_ptr
MapGet(Map_t& map, const Key_t& k, CheckValue_t check, GetFunc_t get)
{
2019-09-04 12:41:07 +00:00
Lock_t lock(&map.first);
2019-06-17 23:19:39 +00:00
auto range = map.second.equal_range(k);
for(auto i = range.first; i != range.second; ++i)
{
if(check(i->second))
return get(i->second);
}
return nullptr;
}
2019-09-04 12:41:07 +00:00
template < typename Lock_t, typename Map_t, typename Key_t,
typename CheckValue_t >
2019-06-17 23:19:39 +00:00
bool
MapHas(Map_t& map, const Key_t& k, CheckValue_t check)
{
2019-09-04 12:41:07 +00:00
Lock_t lock(&map.first);
2019-06-17 23:19:39 +00:00
auto range = map.second.equal_range(k);
for(auto i = range.first; i != range.second; ++i)
{
if(check(i->second))
return true;
}
return false;
}
2019-09-04 12:41:07 +00:00
template < typename Lock_t, typename Map_t, typename Key_t,
typename Value_t >
2019-06-17 23:19:39 +00:00
void
MapPut(Map_t& map, const Key_t& k, const Value_t& v)
{
2019-09-04 12:41:07 +00:00
Lock_t lock(&map.first);
2019-06-17 23:19:39 +00:00
map.second.emplace(k, v);
}
2019-09-04 12:41:07 +00:00
template < typename Lock_t, typename Map_t, typename Visit_t >
2019-06-17 23:19:39 +00:00
void
MapIter(Map_t& map, Visit_t v)
{
2019-09-04 12:41:07 +00:00
Lock_t lock(map.first);
2019-06-17 23:19:39 +00:00
for(const auto& item : map.second)
v(item);
}
2019-09-04 12:41:07 +00:00
template < typename Lock_t, typename Map_t, typename Key_t,
typename Check_t >
2019-06-17 23:19:39 +00:00
void
MapDel(Map_t& map, const Key_t& k, Check_t check)
{
2019-09-04 12:41:07 +00:00
Lock_t lock(map.first);
2019-06-17 23:19:39 +00:00
auto range = map.second.equal_range(k);
for(auto i = range.first; i != range.second;)
{
if(check(i->second))
i = map.second.erase(i);
else
++i;
}
}
void
PathContext::AddOwnPath(PathSet_ptr set, Path_ptr path)
{
set->AddPath(path);
2019-12-03 15:52:06 +00:00
MapPut< SyncOwnedPathsMap_t::Lock_t >(m_OurPaths, path->TXID(), path);
MapPut< SyncOwnedPathsMap_t::Lock_t >(m_OurPaths, path->RXID(), path);
2019-06-17 23:19:39 +00:00
}
bool
PathContext::HasTransitHop(const TransitHopInfo& info)
{
2019-09-04 12:41:07 +00:00
return MapHas< SyncTransitMap_t::Lock_t >(
m_TransitPaths, info.txID,
[info](const std::shared_ptr< TransitHop >& hop) -> bool {
return info == hop->info;
});
2019-06-17 23:19:39 +00:00
}
HopHandler_ptr
PathContext::GetByUpstream(const RouterID& remote, const PathID_t& id)
{
2019-09-04 12:41:07 +00:00
auto own = MapGet< SyncOwnedPathsMap_t::Lock_t >(
2019-08-13 21:38:00 +00:00
m_OurPaths, id,
2019-12-03 15:52:06 +00:00
[](const Path_ptr) -> bool {
2019-08-13 21:38:00 +00:00
// TODO: is this right?
return true;
},
2019-12-03 15:52:06 +00:00
[](Path_ptr p) -> HopHandler_ptr { return p; });
2019-06-17 23:19:39 +00:00
if(own)
return own;
2019-09-04 12:41:07 +00:00
return MapGet< SyncTransitMap_t::Lock_t >(
2019-06-17 23:19:39 +00:00
m_TransitPaths, id,
[remote](const std::shared_ptr< TransitHop >& hop) -> bool {
return hop->info.upstream == remote;
},
[](const std::shared_ptr< TransitHop >& h) -> HopHandler_ptr {
return h;
});
}
bool
PathContext::TransitHopPreviousIsRouter(const PathID_t& path,
const RouterID& otherRouter)
{
2019-09-04 12:41:07 +00:00
SyncTransitMap_t::Lock_t lock(&m_TransitPaths.first);
2019-06-17 23:19:39 +00:00
auto itr = m_TransitPaths.second.find(path);
if(itr == m_TransitPaths.second.end())
return false;
return itr->second->info.downstream == otherRouter;
}
HopHandler_ptr
PathContext::GetByDownstream(const RouterID& remote, const PathID_t& id)
{
2019-09-04 12:41:07 +00:00
return MapGet< SyncTransitMap_t::Lock_t >(
2019-06-17 23:19:39 +00:00
m_TransitPaths, id,
[remote](const std::shared_ptr< TransitHop >& hop) -> bool {
return hop->info.downstream == remote;
},
[](const std::shared_ptr< TransitHop >& h) -> HopHandler_ptr {
return h;
});
}
PathSet_ptr
PathContext::GetLocalPathSet(const PathID_t& id)
{
auto& map = m_OurPaths;
2019-09-04 12:41:07 +00:00
SyncOwnedPathsMap_t::Lock_t lock(&map.first);
2019-06-17 23:19:39 +00:00
auto itr = map.second.find(id);
if(itr != map.second.end())
{
2019-12-03 15:52:06 +00:00
return itr->second->m_PathSet->GetSelf();
2019-06-17 23:19:39 +00:00
}
return nullptr;
}
const byte_t*
PathContext::OurRouterID() const
{
return m_Router->pubkey();
}
AbstractRouter*
PathContext::Router()
{
return m_Router;
}
2019-11-21 14:48:31 +00:00
TransitHop_ptr
2019-06-17 23:19:39 +00:00
PathContext::GetPathForTransfer(const PathID_t& id)
{
2019-11-21 14:48:31 +00:00
const RouterID us(OurRouterID());
2019-06-17 23:19:39 +00:00
auto& map = m_TransitPaths;
{
2019-09-04 12:41:07 +00:00
SyncTransitMap_t::Lock_t lock(&map.first);
2019-06-17 23:19:39 +00:00
auto range = map.second.equal_range(id);
for(auto i = range.first; i != range.second; ++i)
{
if(i->second->info.upstream == us)
return i->second;
}
}
return nullptr;
}
2019-09-05 17:39:09 +00:00
void
PathContext::PumpUpstream()
2019-09-05 17:39:09 +00:00
{
m_TransitPaths.ForEach([&](auto& ptr) { ptr->FlushUpstream(m_Router); });
2019-12-03 15:52:06 +00:00
m_OurPaths.ForEach([&](auto& ptr) { ptr->FlushUpstream(m_Router); });
}
void
PathContext::PumpDownstream()
{
m_TransitPaths.ForEach(
[&](auto& ptr) { ptr->FlushDownstream(m_Router); });
2019-12-03 15:52:06 +00:00
m_OurPaths.ForEach([&](auto& ptr) { ptr->FlushDownstream(m_Router); });
2019-09-05 17:39:09 +00:00
}
2019-06-17 23:19:39 +00:00
void
PathContext::PutTransitHop(std::shared_ptr< TransitHop > hop)
{
2019-09-04 12:41:07 +00:00
MapPut< SyncTransitMap_t::Lock_t >(m_TransitPaths, hop->info.txID, hop);
MapPut< SyncTransitMap_t::Lock_t >(m_TransitPaths, hop->info.rxID, hop);
2019-06-17 23:19:39 +00:00
}
void
PathContext::ExpirePaths(llarp_time_t now)
{
2019-12-30 20:58:30 +00:00
// decay limits
2019-12-30 20:15:19 +00:00
m_PathLimits.Decay(now);
2019-06-17 23:19:39 +00:00
{
2019-09-04 12:41:07 +00:00
SyncTransitMap_t::Lock_t lock(&m_TransitPaths.first);
2019-06-17 23:19:39 +00:00
auto& map = m_TransitPaths.second;
auto itr = map.begin();
while(itr != map.end())
{
if(itr->second->Expired(now))
{
m_Router->outboundMessageHandler().QueueRemoveEmptyPath(itr->first);
2019-06-17 23:19:39 +00:00
itr = map.erase(itr);
}
else
++itr;
}
}
2019-12-03 15:52:06 +00:00
{
SyncOwnedPathsMap_t::Lock_t lock(&m_OurPaths.first);
auto& map = m_OurPaths.second;
auto itr = map.begin();
while(itr != map.end())
{
if(itr->second->Expired(now))
{
itr = map.erase(itr);
}
else
++itr;
}
}
2019-06-17 23:19:39 +00:00
}
2019-11-05 16:58:53 +00:00
2019-06-17 23:19:39 +00:00
routing::MessageHandler_ptr
PathContext::GetHandler(const PathID_t& id)
{
routing::MessageHandler_ptr h = nullptr;
auto pathset = GetLocalPathSet(id);
if(pathset)
{
h = pathset->GetPathByID(id);
}
if(h)
return h;
const RouterID us(OurRouterID());
auto& map = m_TransitPaths;
{
2019-09-04 12:41:07 +00:00
SyncTransitMap_t::Lock_t lock(&map.first);
2019-06-17 23:19:39 +00:00
auto range = map.second.equal_range(id);
for(auto i = range.first; i != range.second; ++i)
{
if(i->second->info.upstream == us)
return i->second;
}
}
return nullptr;
}
2019-12-03 15:52:06 +00:00
void PathContext::RemovePathSet(PathSet_ptr)
2019-06-17 23:19:39 +00:00
{
}
} // namespace path
} // namespace llarp