2019-01-11 01:19:36 +00:00
|
|
|
#include <path/path.hpp>
|
2019-01-10 19:41:51 +00:00
|
|
|
|
2018-12-12 02:52:51 +00:00
|
|
|
#include <messages/dht.hpp>
|
|
|
|
#include <messages/discard.hpp>
|
2019-02-11 19:45:42 +00:00
|
|
|
#include <messages/exit.hpp>
|
|
|
|
#include <messages/path_latency.hpp>
|
|
|
|
#include <messages/relay_commit.hpp>
|
|
|
|
#include <messages/transfer_traffic.hpp>
|
2019-01-11 01:19:36 +00:00
|
|
|
#include <path/pathbuilder.hpp>
|
2019-02-11 19:45:42 +00:00
|
|
|
#include <profiling.hpp>
|
|
|
|
#include <router/abstractrouter.hpp>
|
2019-01-10 19:41:51 +00:00
|
|
|
#include <util/buffer.hpp>
|
|
|
|
#include <util/endian.hpp>
|
2018-12-12 02:52:51 +00:00
|
|
|
|
2018-06-12 16:45:12 +00:00
|
|
|
#include <deque>
|
2018-06-10 14:05:48 +00:00
|
|
|
|
|
|
|
namespace llarp
|
|
|
|
{
|
2018-06-25 15:12:08 +00:00
|
|
|
namespace path
|
2018-06-10 14:05:48 +00:00
|
|
|
{
|
2019-02-24 23:46:37 +00:00
|
|
|
std::ostream&
|
|
|
|
TransitHopInfo::print(std::ostream& stream, int level, int spaces) const
|
|
|
|
{
|
|
|
|
Printer printer(stream, level, spaces);
|
|
|
|
printer.printAttribute("tx", txID);
|
|
|
|
printer.printAttribute("rx", rxID);
|
|
|
|
printer.printAttribute("upstream", upstream);
|
|
|
|
printer.printAttribute("downstream", downstream);
|
|
|
|
|
|
|
|
return stream;
|
|
|
|
}
|
|
|
|
|
2019-02-11 19:45:42 +00:00
|
|
|
PathContext::PathContext(AbstractRouter* router)
|
2018-06-25 15:12:08 +00:00
|
|
|
: m_Router(router), m_AllowTransit(false)
|
|
|
|
{
|
|
|
|
}
|
2018-06-10 14:05:48 +00:00
|
|
|
|
2018-06-25 15:12:08 +00:00
|
|
|
PathContext::~PathContext()
|
|
|
|
{
|
|
|
|
}
|
2018-06-10 14:05:48 +00:00
|
|
|
|
2018-06-25 15:12:08 +00:00
|
|
|
void
|
|
|
|
PathContext::AllowTransit()
|
|
|
|
{
|
|
|
|
m_AllowTransit = true;
|
|
|
|
}
|
2018-06-10 14:05:48 +00:00
|
|
|
|
2018-06-25 15:12:08 +00:00
|
|
|
bool
|
|
|
|
PathContext::AllowingTransit() const
|
|
|
|
{
|
|
|
|
return m_AllowTransit;
|
|
|
|
}
|
2018-06-10 14:05:48 +00:00
|
|
|
|
2018-06-25 15:12:08 +00:00
|
|
|
llarp_threadpool*
|
|
|
|
PathContext::Worker()
|
|
|
|
{
|
2019-02-11 19:45:42 +00:00
|
|
|
return m_Router->threadpool();
|
2018-06-25 15:12:08 +00:00
|
|
|
}
|
2018-06-12 16:45:12 +00:00
|
|
|
|
2019-02-11 19:45:42 +00:00
|
|
|
Crypto*
|
2018-06-25 15:12:08 +00:00
|
|
|
PathContext::Crypto()
|
|
|
|
{
|
2019-01-29 02:16:31 +00:00
|
|
|
return m_Router->crypto();
|
2018-06-25 15:12:08 +00:00
|
|
|
}
|
2018-06-12 16:45:12 +00:00
|
|
|
|
2019-02-11 19:45:42 +00:00
|
|
|
Logic*
|
2018-06-25 15:12:08 +00:00
|
|
|
PathContext::Logic()
|
|
|
|
{
|
2019-01-29 02:16:31 +00:00
|
|
|
return m_Router->logic();
|
2018-06-25 15:12:08 +00:00
|
|
|
}
|
2018-06-15 14:33:38 +00:00
|
|
|
|
2019-02-11 19:45:42 +00:00
|
|
|
const SecretKey&
|
2018-06-25 15:12:08 +00:00
|
|
|
PathContext::EncryptionSecretKey()
|
|
|
|
{
|
2019-02-11 19:45:42 +00:00
|
|
|
return m_Router->encryption();
|
2018-06-25 15:12:08 +00:00
|
|
|
}
|
2018-06-12 16:45:12 +00:00
|
|
|
|
2018-06-25 15:12:08 +00:00
|
|
|
bool
|
2018-12-10 17:22:59 +00:00
|
|
|
PathContext::HopIsUs(const RouterID& k) const
|
2018-06-25 15:12:08 +00:00
|
|
|
{
|
2019-01-02 01:03:53 +00:00
|
|
|
return std::equal(m_Router->pubkey(), m_Router->pubkey() + PUBKEYSIZE,
|
|
|
|
k.begin());
|
2018-06-25 15:12:08 +00:00
|
|
|
}
|
2018-06-12 16:45:12 +00:00
|
|
|
|
2018-06-25 15:12:08 +00:00
|
|
|
bool
|
|
|
|
PathContext::ForwardLRCM(const RouterID& nextHop,
|
2018-08-30 18:48:43 +00:00
|
|
|
const std::array< EncryptedFrame, 8 >& frames)
|
2018-06-25 15:12:08 +00:00
|
|
|
{
|
2019-02-11 19:45:42 +00:00
|
|
|
LogDebug("forwarding LRCM to ", nextHop);
|
2018-09-19 16:36:12 +00:00
|
|
|
LR_CommitMessage msg;
|
|
|
|
msg.frames = frames;
|
|
|
|
return m_Router->SendToOrQueue(nextHop, &msg);
|
2018-06-25 15:12:08 +00:00
|
|
|
}
|
|
|
|
template < typename Map_t, typename Key_t, typename CheckValue_t,
|
|
|
|
typename GetFunc_t >
|
|
|
|
IHopHandler*
|
|
|
|
MapGet(Map_t& map, const Key_t& k, CheckValue_t check, GetFunc_t get)
|
2018-06-22 00:25:30 +00:00
|
|
|
{
|
2019-03-03 15:01:05 +00:00
|
|
|
util::Lock lock(&map.first);
|
2018-06-25 15:12:08 +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;
|
2018-06-22 00:25:30 +00:00
|
|
|
}
|
2018-06-12 16:45:12 +00:00
|
|
|
|
2018-06-25 15:12:08 +00:00
|
|
|
template < typename Map_t, typename Key_t, typename CheckValue_t >
|
|
|
|
bool
|
|
|
|
MapHas(Map_t& map, const Key_t& k, CheckValue_t check)
|
2018-06-18 22:03:50 +00:00
|
|
|
{
|
2019-03-03 15:01:05 +00:00
|
|
|
util::Lock lock(&map.first);
|
2018-06-25 15:12:08 +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;
|
2018-06-18 22:03:50 +00:00
|
|
|
}
|
2018-06-12 16:45:12 +00:00
|
|
|
|
2018-06-25 15:12:08 +00:00
|
|
|
template < typename Map_t, typename Key_t, typename Value_t >
|
|
|
|
void
|
|
|
|
MapPut(Map_t& map, const Key_t& k, const Value_t& v)
|
|
|
|
{
|
2019-03-03 15:01:05 +00:00
|
|
|
util::Lock lock(&map.first);
|
2019-02-18 10:35:16 +00:00
|
|
|
map.second.emplace(k, v);
|
2018-06-25 15:12:08 +00:00
|
|
|
}
|
2018-06-12 16:45:12 +00:00
|
|
|
|
2018-06-25 15:12:08 +00:00
|
|
|
template < typename Map_t, typename Visit_t >
|
|
|
|
void
|
|
|
|
MapIter(Map_t& map, Visit_t v)
|
2018-06-22 00:25:30 +00:00
|
|
|
{
|
2018-08-12 17:22:29 +00:00
|
|
|
util::Lock lock(map.first);
|
2018-06-25 15:12:08 +00:00
|
|
|
for(const auto& item : map.second)
|
|
|
|
v(item);
|
2018-06-22 00:25:30 +00:00
|
|
|
}
|
|
|
|
|
2018-06-25 15:12:08 +00:00
|
|
|
template < typename Map_t, typename Key_t, typename Check_t >
|
|
|
|
void
|
|
|
|
MapDel(Map_t& map, const Key_t& k, Check_t check)
|
|
|
|
{
|
2018-08-12 17:22:29 +00:00
|
|
|
util::Lock lock(map.first);
|
2018-06-25 15:12:08 +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;
|
|
|
|
}
|
|
|
|
}
|
2018-06-19 17:11:24 +00:00
|
|
|
|
2018-06-25 15:12:08 +00:00
|
|
|
void
|
|
|
|
PathContext::AddOwnPath(PathSet* set, Path* path)
|
|
|
|
{
|
|
|
|
set->AddPath(path);
|
|
|
|
MapPut(m_OurPaths, path->TXID(), set);
|
|
|
|
MapPut(m_OurPaths, path->RXID(), set);
|
|
|
|
}
|
2018-06-22 00:25:30 +00:00
|
|
|
|
2018-06-25 15:12:08 +00:00
|
|
|
bool
|
|
|
|
PathContext::HasTransitHop(const TransitHopInfo& info)
|
|
|
|
{
|
2018-10-21 13:07:33 +00:00
|
|
|
return MapHas(m_TransitPaths, info.txID,
|
|
|
|
[info](const std::shared_ptr< TransitHop >& hop) -> bool {
|
|
|
|
return info == hop->info;
|
|
|
|
});
|
2018-06-25 15:12:08 +00:00
|
|
|
}
|
2018-06-22 12:45:46 +00:00
|
|
|
|
2018-06-25 15:12:08 +00:00
|
|
|
IHopHandler*
|
|
|
|
PathContext::GetByUpstream(const RouterID& remote, const PathID_t& id)
|
|
|
|
{
|
2019-04-22 17:38:29 +00:00
|
|
|
auto own = MapGet(
|
|
|
|
m_OurPaths, id,
|
|
|
|
[](ABSL_ATTRIBUTE_UNUSED const PathSet* s) -> bool {
|
|
|
|
// TODO: is this right?
|
|
|
|
return true;
|
|
|
|
},
|
|
|
|
[remote, id](PathSet* p) -> IHopHandler* {
|
|
|
|
return p->GetByUpstream(remote, id);
|
|
|
|
});
|
2018-06-25 15:12:08 +00:00
|
|
|
if(own)
|
|
|
|
return own;
|
|
|
|
|
2019-04-22 17:38:29 +00:00
|
|
|
return MapGet(
|
|
|
|
m_TransitPaths, id,
|
|
|
|
[remote](const std::shared_ptr< TransitHop >& hop) -> bool {
|
|
|
|
return hop->info.upstream == remote;
|
|
|
|
},
|
|
|
|
[](const std::shared_ptr< TransitHop >& h) -> IHopHandler* {
|
|
|
|
return h.get();
|
|
|
|
});
|
2018-06-25 15:12:08 +00:00
|
|
|
}
|
2018-06-12 16:45:12 +00:00
|
|
|
|
2018-12-13 16:14:44 +00:00
|
|
|
bool
|
|
|
|
PathContext::TransitHopPreviousIsRouter(const PathID_t& path,
|
|
|
|
const RouterID& otherRouter)
|
|
|
|
{
|
2019-03-03 15:01:05 +00:00
|
|
|
util::Lock lock(&m_TransitPaths.first);
|
2018-12-13 16:14:44 +00:00
|
|
|
auto itr = m_TransitPaths.second.find(path);
|
|
|
|
if(itr == m_TransitPaths.second.end())
|
|
|
|
return false;
|
|
|
|
return itr->second->info.downstream == otherRouter;
|
|
|
|
}
|
|
|
|
|
2018-06-25 15:12:08 +00:00
|
|
|
IHopHandler*
|
|
|
|
PathContext::GetByDownstream(const RouterID& remote, const PathID_t& id)
|
|
|
|
{
|
2019-04-22 17:38:29 +00:00
|
|
|
return MapGet(
|
|
|
|
m_TransitPaths, id,
|
|
|
|
[remote](const std::shared_ptr< TransitHop >& hop) -> bool {
|
|
|
|
return hop->info.downstream == remote;
|
|
|
|
},
|
|
|
|
[](const std::shared_ptr< TransitHop >& h) -> IHopHandler* {
|
|
|
|
return h.get();
|
|
|
|
});
|
2018-06-25 15:12:08 +00:00
|
|
|
}
|
2018-06-22 00:25:30 +00:00
|
|
|
|
2018-07-09 17:32:11 +00:00
|
|
|
PathSet*
|
|
|
|
PathContext::GetLocalPathSet(const PathID_t& id)
|
|
|
|
{
|
|
|
|
auto& map = m_OurPaths;
|
2019-03-03 15:01:05 +00:00
|
|
|
util::Lock lock(&map.first);
|
2018-07-09 17:32:11 +00:00
|
|
|
auto itr = map.second.find(id);
|
|
|
|
if(itr != map.second.end())
|
|
|
|
{
|
|
|
|
return itr->second;
|
|
|
|
}
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2018-06-25 15:12:08 +00:00
|
|
|
const byte_t*
|
|
|
|
PathContext::OurRouterID() const
|
|
|
|
{
|
|
|
|
return m_Router->pubkey();
|
|
|
|
}
|
2018-06-18 22:03:50 +00:00
|
|
|
|
2019-02-11 19:45:42 +00:00
|
|
|
AbstractRouter*
|
2018-06-25 15:12:08 +00:00
|
|
|
PathContext::Router()
|
|
|
|
{
|
|
|
|
return m_Router;
|
|
|
|
}
|
|
|
|
|
2018-10-09 17:09:45 +00:00
|
|
|
IHopHandler*
|
|
|
|
PathContext::GetPathForTransfer(const PathID_t& id)
|
2018-10-06 16:37:54 +00:00
|
|
|
{
|
|
|
|
RouterID us(OurRouterID());
|
|
|
|
auto& map = m_TransitPaths;
|
|
|
|
{
|
2019-03-03 15:01:05 +00:00
|
|
|
util::Lock lock(&map.first);
|
2018-10-06 16:37:54 +00:00
|
|
|
auto range = map.second.equal_range(id);
|
|
|
|
for(auto i = range.first; i != range.second; ++i)
|
|
|
|
{
|
|
|
|
if(i->second->info.upstream == us)
|
2018-10-21 13:07:33 +00:00
|
|
|
return i->second.get();
|
2018-10-06 16:37:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return nullptr;
|
|
|
|
}
|
2018-10-09 17:09:45 +00:00
|
|
|
|
2018-06-25 15:12:08 +00:00
|
|
|
void
|
2018-10-21 13:07:33 +00:00
|
|
|
PathContext::PutTransitHop(std::shared_ptr< TransitHop > hop)
|
2018-06-25 15:12:08 +00:00
|
|
|
{
|
|
|
|
MapPut(m_TransitPaths, hop->info.txID, hop);
|
|
|
|
MapPut(m_TransitPaths, hop->info.rxID, hop);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2018-10-29 16:48:36 +00:00
|
|
|
PathContext::ExpirePaths(llarp_time_t now)
|
2018-06-25 15:12:08 +00:00
|
|
|
{
|
2019-03-03 15:01:05 +00:00
|
|
|
util::Lock lock(&m_TransitPaths.first);
|
2018-06-25 15:12:08 +00:00
|
|
|
auto& map = m_TransitPaths.second;
|
|
|
|
auto itr = map.begin();
|
|
|
|
while(itr != map.end())
|
|
|
|
{
|
|
|
|
if(itr->second->Expired(now))
|
|
|
|
{
|
2018-10-21 13:07:33 +00:00
|
|
|
itr = map.erase(itr);
|
2018-06-25 15:12:08 +00:00
|
|
|
}
|
2018-10-21 13:07:33 +00:00
|
|
|
else
|
|
|
|
++itr;
|
2018-06-25 15:12:08 +00:00
|
|
|
}
|
2018-10-21 13:07:33 +00:00
|
|
|
|
2018-06-25 15:12:08 +00:00
|
|
|
for(auto& builder : m_PathBuilders)
|
2018-06-22 00:25:30 +00:00
|
|
|
{
|
2018-08-17 19:49:58 +00:00
|
|
|
if(builder)
|
|
|
|
builder->ExpirePaths(now);
|
2018-06-22 00:25:30 +00:00
|
|
|
}
|
|
|
|
}
|
2018-06-25 15:12:08 +00:00
|
|
|
|
|
|
|
void
|
2018-10-29 16:48:36 +00:00
|
|
|
PathContext::BuildPaths(llarp_time_t now)
|
2018-06-22 00:25:30 +00:00
|
|
|
{
|
2018-06-25 15:12:08 +00:00
|
|
|
for(auto& builder : m_PathBuilders)
|
|
|
|
{
|
2018-10-29 16:48:36 +00:00
|
|
|
if(builder->ShouldBuildMore(now))
|
2018-06-25 15:12:08 +00:00
|
|
|
{
|
2018-12-10 15:31:58 +00:00
|
|
|
builder->BuildOne();
|
2018-06-25 15:12:08 +00:00
|
|
|
}
|
|
|
|
}
|
2018-06-18 22:03:50 +00:00
|
|
|
}
|
2018-06-12 16:45:12 +00:00
|
|
|
|
2018-06-29 16:02:39 +00:00
|
|
|
void
|
2018-10-29 16:48:36 +00:00
|
|
|
PathContext::TickPaths(llarp_time_t now)
|
2018-06-29 16:02:39 +00:00
|
|
|
{
|
|
|
|
for(auto& builder : m_PathBuilders)
|
|
|
|
builder->Tick(now, m_Router);
|
|
|
|
}
|
|
|
|
|
2018-08-10 21:34:11 +00:00
|
|
|
routing::IMessageHandler*
|
|
|
|
PathContext::GetHandler(const PathID_t& id)
|
|
|
|
{
|
|
|
|
routing::IMessageHandler* h = nullptr;
|
|
|
|
auto pathset = GetLocalPathSet(id);
|
|
|
|
if(pathset)
|
|
|
|
{
|
|
|
|
h = pathset->GetPathByID(id);
|
|
|
|
}
|
|
|
|
if(h)
|
|
|
|
return h;
|
|
|
|
RouterID us(OurRouterID());
|
|
|
|
auto& map = m_TransitPaths;
|
|
|
|
{
|
2019-03-03 15:01:05 +00:00
|
|
|
util::Lock lock(&map.first);
|
2018-08-12 17:22:29 +00:00
|
|
|
auto range = map.second.equal_range(id);
|
|
|
|
for(auto i = range.first; i != range.second; ++i)
|
|
|
|
{
|
|
|
|
if(i->second->info.upstream == us)
|
2018-10-21 13:07:33 +00:00
|
|
|
return i->second.get();
|
2018-08-12 17:22:29 +00:00
|
|
|
}
|
2018-08-10 21:34:11 +00:00
|
|
|
}
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2018-06-25 15:12:08 +00:00
|
|
|
void
|
2018-08-30 18:48:43 +00:00
|
|
|
PathContext::AddPathBuilder(Builder* ctx)
|
2018-06-22 00:25:30 +00:00
|
|
|
{
|
2018-06-25 15:12:08 +00:00
|
|
|
m_PathBuilders.push_back(ctx);
|
2018-06-22 12:45:46 +00:00
|
|
|
}
|
2018-06-25 15:12:08 +00:00
|
|
|
|
2018-08-18 14:01:21 +00:00
|
|
|
void
|
|
|
|
PathContext::RemovePathSet(PathSet* set)
|
|
|
|
{
|
2019-03-03 15:01:05 +00:00
|
|
|
util::Lock lock(&m_OurPaths.first);
|
2018-08-18 14:01:21 +00:00
|
|
|
auto& map = m_OurPaths.second;
|
|
|
|
auto itr = map.begin();
|
|
|
|
while(itr != map.end())
|
|
|
|
{
|
|
|
|
if(itr->second == set)
|
|
|
|
itr = map.erase(itr);
|
|
|
|
else
|
|
|
|
++itr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2018-08-30 18:48:43 +00:00
|
|
|
PathContext::RemovePathBuilder(Builder* ctx)
|
2018-08-18 14:01:21 +00:00
|
|
|
{
|
|
|
|
m_PathBuilders.remove(ctx);
|
|
|
|
RemovePathSet(ctx);
|
|
|
|
}
|
|
|
|
|
2019-02-24 23:46:37 +00:00
|
|
|
std::ostream&
|
|
|
|
TransitHop::print(std::ostream& stream, int level, int spaces) const
|
|
|
|
{
|
|
|
|
Printer printer(stream, level, spaces);
|
|
|
|
printer.printAttribute("TransitHop", info);
|
|
|
|
printer.printAttribute("started", started);
|
|
|
|
printer.printAttribute("lifetime", lifetime);
|
|
|
|
|
|
|
|
return stream;
|
|
|
|
}
|
|
|
|
|
2018-06-25 15:12:08 +00:00
|
|
|
PathHopConfig::PathHopConfig()
|
2018-06-22 12:45:46 +00:00
|
|
|
{
|
2018-06-22 00:25:30 +00:00
|
|
|
}
|
|
|
|
|
2018-06-25 15:12:08 +00:00
|
|
|
PathHopConfig::~PathHopConfig()
|
|
|
|
{
|
|
|
|
}
|
2018-06-22 00:25:30 +00:00
|
|
|
|
2018-11-14 18:02:27 +00:00
|
|
|
Path::Path(const std::vector< RouterContact >& h, PathSet* parent,
|
|
|
|
PathRole startingRoles)
|
|
|
|
: m_PathSet(parent), _role(startingRoles)
|
2018-06-25 15:12:08 +00:00
|
|
|
{
|
2018-09-06 11:46:19 +00:00
|
|
|
hops.resize(h.size());
|
2018-08-30 18:48:43 +00:00
|
|
|
size_t hsz = h.size();
|
|
|
|
for(size_t idx = 0; idx < hsz; ++idx)
|
2018-06-25 15:12:08 +00:00
|
|
|
{
|
2018-08-30 18:48:43 +00:00
|
|
|
hops[idx].rc = h[idx];
|
2018-06-25 15:12:08 +00:00
|
|
|
hops[idx].txID.Randomize();
|
|
|
|
hops[idx].rxID.Randomize();
|
|
|
|
}
|
2018-06-29 16:02:39 +00:00
|
|
|
|
2018-08-30 18:48:43 +00:00
|
|
|
for(size_t idx = 0; idx < hsz - 1; ++idx)
|
2018-06-26 14:52:19 +00:00
|
|
|
{
|
|
|
|
hops[idx].txID = hops[idx + 1].rxID;
|
|
|
|
}
|
2018-07-11 16:11:19 +00:00
|
|
|
// initialize parts of the introduction
|
2018-08-30 18:48:43 +00:00
|
|
|
intro.router = hops[hsz - 1].rc.pubkey;
|
2018-10-06 16:37:54 +00:00
|
|
|
intro.pathID = hops[hsz - 1].txID;
|
2018-10-29 16:48:36 +00:00
|
|
|
EnterState(ePathBuilding, parent->Now());
|
2018-06-25 15:12:08 +00:00
|
|
|
}
|
2018-06-22 00:25:30 +00:00
|
|
|
|
2018-06-25 15:12:08 +00:00
|
|
|
void
|
|
|
|
Path::SetBuildResultHook(BuildResultHookFunc func)
|
|
|
|
{
|
|
|
|
m_BuiltHook = func;
|
|
|
|
}
|
2018-06-22 00:25:30 +00:00
|
|
|
|
2018-07-23 07:38:29 +00:00
|
|
|
RouterID
|
|
|
|
Path::Endpoint() const
|
|
|
|
{
|
2018-08-30 18:48:43 +00:00
|
|
|
return hops[hops.size() - 1].rc.pubkey;
|
2018-07-23 07:38:29 +00:00
|
|
|
}
|
|
|
|
|
2018-12-10 17:22:59 +00:00
|
|
|
PubKey
|
|
|
|
Path::EndpointPubKey() const
|
|
|
|
{
|
|
|
|
return hops[hops.size() - 1].rc.pubkey;
|
|
|
|
}
|
|
|
|
|
2018-12-18 19:03:50 +00:00
|
|
|
PathID_t
|
2018-06-25 15:12:08 +00:00
|
|
|
Path::TXID() const
|
2018-06-22 00:25:30 +00:00
|
|
|
{
|
2018-06-25 15:12:08 +00:00
|
|
|
return hops[0].txID;
|
2018-06-22 00:25:30 +00:00
|
|
|
}
|
2018-06-10 14:05:48 +00:00
|
|
|
|
2018-12-18 19:03:50 +00:00
|
|
|
PathID_t
|
2018-06-25 15:12:08 +00:00
|
|
|
Path::RXID() const
|
|
|
|
{
|
|
|
|
return hops[0].rxID;
|
|
|
|
}
|
2018-06-19 17:11:24 +00:00
|
|
|
|
2018-07-11 16:11:19 +00:00
|
|
|
bool
|
|
|
|
Path::IsReady() const
|
|
|
|
{
|
2018-09-13 13:07:00 +00:00
|
|
|
return intro.latency > 0 && _status == ePathEstablished;
|
2018-07-11 16:11:19 +00:00
|
|
|
}
|
|
|
|
|
2019-03-08 17:26:29 +00:00
|
|
|
bool
|
|
|
|
Path::IsEndpoint(const RouterID& r, const PathID_t& id) const
|
|
|
|
{
|
|
|
|
return hops[hops.size() - 1].rc.pubkey == r
|
|
|
|
&& hops[hops.size() - 1].txID == id;
|
|
|
|
}
|
|
|
|
|
2018-06-25 15:12:08 +00:00
|
|
|
RouterID
|
|
|
|
Path::Upstream() const
|
|
|
|
{
|
2018-08-30 18:48:43 +00:00
|
|
|
return hops[0].rc.pubkey;
|
2018-06-25 15:12:08 +00:00
|
|
|
}
|
|
|
|
|
2019-03-11 13:58:31 +00:00
|
|
|
std::string
|
|
|
|
Path::HopsString() const
|
|
|
|
{
|
|
|
|
std::stringstream ss;
|
|
|
|
for(const auto& hop : hops)
|
|
|
|
ss << RouterID(hop.rc.pubkey) << " -> ";
|
|
|
|
return ss.str();
|
|
|
|
}
|
|
|
|
|
2018-09-14 14:50:37 +00:00
|
|
|
void
|
2018-10-29 16:48:36 +00:00
|
|
|
Path::EnterState(PathStatus st, llarp_time_t now)
|
2018-09-14 14:50:37 +00:00
|
|
|
{
|
2019-04-13 14:32:07 +00:00
|
|
|
if(st == ePathExpired && _status == ePathBuilding)
|
2018-09-14 14:50:37 +00:00
|
|
|
{
|
2019-04-13 14:32:07 +00:00
|
|
|
_status = st;
|
2018-09-26 13:04:25 +00:00
|
|
|
m_PathSet->HandlePathBuildTimeout(this);
|
2018-09-14 14:50:37 +00:00
|
|
|
}
|
|
|
|
else if(st == ePathBuilding)
|
|
|
|
{
|
2019-02-11 19:45:42 +00:00
|
|
|
LogInfo("path ", Name(), " is building");
|
2018-10-29 16:48:36 +00:00
|
|
|
buildStarted = now;
|
2018-09-14 14:50:37 +00:00
|
|
|
}
|
2019-02-05 17:55:23 +00:00
|
|
|
else if(st == ePathEstablished && _status == ePathBuilding)
|
|
|
|
{
|
2019-02-11 19:45:42 +00:00
|
|
|
LogInfo("path ", Name(), " is built, took ", now - buildStarted, " ms");
|
2019-02-05 17:55:23 +00:00
|
|
|
}
|
2019-03-30 13:02:10 +00:00
|
|
|
else if(st == ePathTimeout && _status == ePathEstablished)
|
|
|
|
{
|
2019-03-30 13:12:48 +00:00
|
|
|
LogInfo("path ", Name(), " died");
|
|
|
|
_status = st;
|
2019-03-30 13:02:10 +00:00
|
|
|
m_PathSet->HandlePathDied(this);
|
|
|
|
}
|
2019-04-13 14:32:07 +00:00
|
|
|
else if(st == ePathEstablished && _status == ePathTimeout)
|
|
|
|
{
|
|
|
|
LogInfo("path ", Name(), " reanimated");
|
|
|
|
}
|
2018-09-14 14:50:37 +00:00
|
|
|
_status = st;
|
|
|
|
}
|
|
|
|
|
2019-02-11 17:14:43 +00:00
|
|
|
util::StatusObject
|
|
|
|
PathHopConfig::ExtractStatus() const
|
2019-02-08 19:43:25 +00:00
|
|
|
{
|
2019-02-11 17:14:43 +00:00
|
|
|
util::StatusObject obj{{"lifetime", lifetime},
|
|
|
|
{"router", rc.pubkey.ToHex()},
|
|
|
|
{"txid", txID.ToHex()},
|
|
|
|
{"rxid", rxID.ToHex()}};
|
|
|
|
return obj;
|
|
|
|
}
|
2019-02-08 19:43:25 +00:00
|
|
|
|
2019-02-11 17:14:43 +00:00
|
|
|
util::StatusObject
|
|
|
|
Path::ExtractStatus() const
|
|
|
|
{
|
|
|
|
auto now = llarp::time_now_ms();
|
|
|
|
|
|
|
|
util::StatusObject obj{{"intro", intro.ExtractStatus()},
|
|
|
|
{"lastRecvMsg", m_LastRecvMessage},
|
|
|
|
{"lastLatencyTest", m_LastLatencyTestTime},
|
|
|
|
{"buildStarted", buildStarted},
|
|
|
|
{"expired", Expired(now)},
|
|
|
|
{"expiresSoon", ExpiresSoon(now)},
|
|
|
|
{"expiresAt", ExpireTime()},
|
|
|
|
{"ready", IsReady()},
|
|
|
|
{"hasExit", SupportsAnyRoles(ePathRoleExit)}};
|
|
|
|
|
|
|
|
std::vector< util::StatusObject > hopsObj;
|
|
|
|
std::transform(hops.begin(), hops.end(), std::back_inserter(hopsObj),
|
|
|
|
[](const auto& hop) -> util::StatusObject {
|
|
|
|
return hop.ExtractStatus();
|
|
|
|
});
|
|
|
|
obj.Put("hops", hopsObj);
|
2019-02-08 19:43:25 +00:00
|
|
|
|
|
|
|
switch(_status)
|
|
|
|
{
|
|
|
|
case ePathBuilding:
|
2019-02-11 17:14:43 +00:00
|
|
|
obj.Put("status", "building");
|
2019-02-08 19:43:25 +00:00
|
|
|
break;
|
|
|
|
case ePathEstablished:
|
2019-02-11 17:14:43 +00:00
|
|
|
obj.Put("status", "established");
|
2019-02-08 19:43:25 +00:00
|
|
|
break;
|
|
|
|
case ePathTimeout:
|
2019-02-11 17:14:43 +00:00
|
|
|
obj.Put("status", "timeout");
|
2019-02-08 19:43:25 +00:00
|
|
|
break;
|
|
|
|
case ePathExpired:
|
2019-02-11 17:14:43 +00:00
|
|
|
obj.Put("status", "expired");
|
2019-02-08 19:43:25 +00:00
|
|
|
break;
|
|
|
|
default:
|
2019-02-11 17:14:43 +00:00
|
|
|
obj.Put("status", "unknown");
|
2019-02-08 19:43:25 +00:00
|
|
|
break;
|
|
|
|
}
|
2019-02-11 17:14:43 +00:00
|
|
|
return obj;
|
2019-02-08 19:43:25 +00:00
|
|
|
}
|
|
|
|
|
2018-06-29 16:02:39 +00:00
|
|
|
void
|
2019-02-11 19:45:42 +00:00
|
|
|
Path::Tick(llarp_time_t now, AbstractRouter* r)
|
2018-06-29 16:02:39 +00:00
|
|
|
{
|
2018-07-23 07:38:29 +00:00
|
|
|
if(Expired(now))
|
|
|
|
return;
|
2018-09-13 12:27:28 +00:00
|
|
|
|
2018-09-13 16:41:53 +00:00
|
|
|
if(_status == ePathBuilding)
|
|
|
|
{
|
2019-02-05 17:55:23 +00:00
|
|
|
if(now >= buildStarted)
|
2018-09-13 16:41:53 +00:00
|
|
|
{
|
2019-02-05 17:55:23 +00:00
|
|
|
auto dlt = now - buildStarted;
|
2019-04-05 14:58:22 +00:00
|
|
|
if(dlt >= path::build_timeout)
|
2019-02-05 17:55:23 +00:00
|
|
|
{
|
2019-02-11 19:45:42 +00:00
|
|
|
r->routerProfiling().MarkPathFail(this);
|
2019-04-13 14:32:07 +00:00
|
|
|
EnterState(ePathExpired, now);
|
2019-02-05 17:55:23 +00:00
|
|
|
return;
|
|
|
|
}
|
2018-09-13 16:41:53 +00:00
|
|
|
}
|
|
|
|
}
|
2018-09-13 12:27:28 +00:00
|
|
|
// check to see if this path is dead
|
2018-09-24 14:44:23 +00:00
|
|
|
if(_status == ePathEstablished)
|
2018-09-13 12:27:28 +00:00
|
|
|
{
|
2019-04-25 23:21:19 +00:00
|
|
|
const auto dlt = now - m_LastLatencyTestTime;
|
2019-04-05 14:58:22 +00:00
|
|
|
if(dlt > path::latency_interval && m_LastLatencyTestID == 0)
|
2019-02-06 13:51:05 +00:00
|
|
|
{
|
2019-02-11 19:45:42 +00:00
|
|
|
routing::PathLatencyMessage latency;
|
|
|
|
latency.T = randint();
|
2019-02-06 13:51:05 +00:00
|
|
|
m_LastLatencyTestID = latency.T;
|
|
|
|
m_LastLatencyTestTime = now;
|
2019-04-22 17:38:29 +00:00
|
|
|
SendRoutingMessage(latency, r);
|
2019-03-25 15:41:37 +00:00
|
|
|
return;
|
2019-02-06 13:51:05 +00:00
|
|
|
}
|
2018-11-21 12:31:36 +00:00
|
|
|
if(SupportsAnyRoles(ePathRoleExit | ePathRoleSVC))
|
2018-11-17 18:40:13 +00:00
|
|
|
{
|
|
|
|
if(m_LastRecvMessage && now > m_LastRecvMessage
|
2019-04-05 14:58:22 +00:00
|
|
|
&& now - m_LastRecvMessage > path::alive_timeout)
|
2018-11-17 18:40:13 +00:00
|
|
|
{
|
2018-11-21 12:31:36 +00:00
|
|
|
// TODO: send close exit message
|
2019-02-11 19:45:42 +00:00
|
|
|
// r->routerProfiling().MarkPathFail(this);
|
2018-11-17 18:40:13 +00:00
|
|
|
// EnterState(ePathTimeout, now);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2019-03-27 20:25:54 +00:00
|
|
|
if(m_LastRecvMessage && now > m_LastRecvMessage)
|
2018-09-13 16:41:53 +00:00
|
|
|
{
|
2019-04-25 23:21:19 +00:00
|
|
|
const auto delay = now - m_LastRecvMessage;
|
|
|
|
if(m_CheckForDead && m_CheckForDead(this, delay))
|
2018-10-04 16:48:26 +00:00
|
|
|
{
|
2019-02-11 19:45:42 +00:00
|
|
|
r->routerProfiling().MarkPathFail(this);
|
2018-10-29 16:48:36 +00:00
|
|
|
EnterState(ePathTimeout, now);
|
2018-10-04 16:48:26 +00:00
|
|
|
}
|
2018-09-13 16:41:53 +00:00
|
|
|
}
|
2019-04-05 14:58:22 +00:00
|
|
|
else if(dlt >= path::alive_timeout && m_LastRecvMessage == 0)
|
2018-09-14 14:50:37 +00:00
|
|
|
{
|
2019-04-10 12:56:14 +00:00
|
|
|
if(m_CheckForDead && m_CheckForDead(this, dlt))
|
|
|
|
{
|
|
|
|
r->routerProfiling().MarkPathFail(this);
|
|
|
|
EnterState(ePathTimeout, now);
|
|
|
|
}
|
2018-09-14 14:50:37 +00:00
|
|
|
}
|
2018-09-13 12:27:28 +00:00
|
|
|
}
|
2018-06-29 16:02:39 +00:00
|
|
|
}
|
|
|
|
|
2018-06-25 15:12:08 +00:00
|
|
|
bool
|
2019-02-01 01:58:06 +00:00
|
|
|
Path::HandleUpstream(const llarp_buffer_t& buf, const TunnelNonce& Y,
|
2019-01-29 02:16:31 +00:00
|
|
|
AbstractRouter* r)
|
2018-06-20 12:34:48 +00:00
|
|
|
{
|
2018-07-28 22:20:32 +00:00
|
|
|
TunnelNonce n = Y;
|
2018-06-25 15:12:08 +00:00
|
|
|
for(const auto& hop : hops)
|
|
|
|
{
|
2019-01-29 02:16:31 +00:00
|
|
|
r->crypto()->xchacha20(buf, hop.shared, n);
|
2018-07-28 22:20:32 +00:00
|
|
|
n ^= hop.nonceXOR;
|
2018-06-25 15:12:08 +00:00
|
|
|
}
|
2018-09-02 18:25:42 +00:00
|
|
|
RelayUpstreamMessage msg;
|
|
|
|
msg.X = buf;
|
|
|
|
msg.Y = Y;
|
|
|
|
msg.pathid = TXID();
|
|
|
|
if(r->SendToOrQueue(Upstream(), &msg))
|
2018-08-10 21:34:11 +00:00
|
|
|
return true;
|
2019-02-11 19:45:42 +00:00
|
|
|
LogError("send to ", Upstream(), " failed");
|
2018-08-10 21:34:11 +00:00
|
|
|
return false;
|
2018-06-20 12:34:48 +00:00
|
|
|
}
|
|
|
|
|
2018-06-25 15:12:08 +00:00
|
|
|
bool
|
|
|
|
Path::Expired(llarp_time_t now) const
|
|
|
|
{
|
2019-04-13 14:32:07 +00:00
|
|
|
if(_status == ePathEstablished || _status == ePathTimeout)
|
2018-12-20 15:03:48 +00:00
|
|
|
return now >= ExpireTime();
|
2018-09-13 13:07:00 +00:00
|
|
|
else if(_status == ePathBuilding)
|
|
|
|
return false;
|
2018-06-25 15:12:08 +00:00
|
|
|
else
|
|
|
|
return true;
|
|
|
|
}
|
2018-06-23 00:00:44 +00:00
|
|
|
|
2018-09-13 13:07:00 +00:00
|
|
|
std::string
|
|
|
|
Path::Name() const
|
|
|
|
{
|
|
|
|
std::stringstream ss;
|
|
|
|
ss << "TX=" << TXID() << " RX=" << RXID();
|
2019-03-22 14:10:30 +00:00
|
|
|
if(m_PathSet)
|
|
|
|
ss << " on " << m_PathSet->Name();
|
2018-09-13 13:07:00 +00:00
|
|
|
return ss.str();
|
|
|
|
}
|
|
|
|
|
2018-06-25 15:12:08 +00:00
|
|
|
bool
|
2019-02-01 01:58:06 +00:00
|
|
|
Path::HandleDownstream(const llarp_buffer_t& buf, const TunnelNonce& Y,
|
2019-01-29 02:16:31 +00:00
|
|
|
AbstractRouter* r)
|
2018-06-22 13:59:28 +00:00
|
|
|
{
|
2018-07-28 22:20:32 +00:00
|
|
|
TunnelNonce n = Y;
|
2018-06-25 15:12:08 +00:00
|
|
|
for(const auto& hop : hops)
|
|
|
|
{
|
2018-07-28 22:20:32 +00:00
|
|
|
n ^= hop.nonceXOR;
|
2019-01-29 02:16:31 +00:00
|
|
|
r->crypto()->xchacha20(buf, hop.shared, n);
|
2018-06-25 15:12:08 +00:00
|
|
|
}
|
2019-03-25 15:41:37 +00:00
|
|
|
if(!HandleRoutingMessage(buf, r))
|
|
|
|
return false;
|
|
|
|
m_LastRecvMessage = r->Now();
|
|
|
|
return true;
|
2018-06-25 15:12:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2019-01-29 02:16:31 +00:00
|
|
|
Path::HandleRoutingMessage(const llarp_buffer_t& buf, AbstractRouter* r)
|
2018-06-25 15:12:08 +00:00
|
|
|
{
|
2018-12-27 14:32:37 +00:00
|
|
|
if(!r->ParseRoutingMessageBuffer(buf, this, RXID()))
|
2018-06-25 15:12:08 +00:00
|
|
|
{
|
2019-02-11 19:45:42 +00:00
|
|
|
LogWarn("Failed to parse inbound routing message");
|
2018-06-25 15:12:08 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-11-14 12:23:08 +00:00
|
|
|
bool
|
|
|
|
Path::HandleUpdateExitVerifyMessage(
|
2019-04-22 17:38:29 +00:00
|
|
|
const routing::UpdateExitVerifyMessage& msg, AbstractRouter* r)
|
2018-11-14 12:23:08 +00:00
|
|
|
{
|
|
|
|
(void)r;
|
2019-04-22 17:38:29 +00:00
|
|
|
if(m_UpdateExitTX && msg.T == m_UpdateExitTX)
|
2018-11-14 12:23:08 +00:00
|
|
|
{
|
|
|
|
if(m_ExitUpdated)
|
|
|
|
return m_ExitUpdated(this);
|
|
|
|
}
|
2019-04-22 17:38:29 +00:00
|
|
|
if(m_CloseExitTX && msg.T == m_CloseExitTX)
|
2018-11-14 12:23:08 +00:00
|
|
|
{
|
|
|
|
if(m_ExitClosed)
|
|
|
|
return m_ExitClosed(this);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-06-25 15:12:08 +00:00
|
|
|
bool
|
2019-04-22 17:38:29 +00:00
|
|
|
Path::SendRoutingMessage(const routing::IMessage& msg, AbstractRouter* r)
|
2018-06-25 15:12:08 +00:00
|
|
|
{
|
2019-02-02 23:12:42 +00:00
|
|
|
std::array< byte_t, MAX_LINK_MSG_SIZE / 2 > tmp;
|
|
|
|
llarp_buffer_t buf(tmp);
|
2019-02-11 19:45:42 +00:00
|
|
|
// should help prevent bad paths with uninitialized members
|
|
|
|
// FIXME: Why would we get uninitialized IMessages?
|
2019-04-22 17:38:29 +00:00
|
|
|
if(msg.version != LLARP_PROTO_VERSION)
|
2019-01-02 04:33:03 +00:00
|
|
|
return false;
|
2019-04-22 17:38:29 +00:00
|
|
|
if(!msg.BEncode(&buf))
|
2018-08-10 21:34:11 +00:00
|
|
|
{
|
2019-02-11 19:45:42 +00:00
|
|
|
LogError("Bencode failed");
|
|
|
|
DumpBuffer(buf);
|
2018-06-25 15:12:08 +00:00
|
|
|
return false;
|
2018-08-10 21:34:11 +00:00
|
|
|
}
|
2018-06-25 15:12:08 +00:00
|
|
|
// make nonce
|
|
|
|
TunnelNonce N;
|
|
|
|
N.Randomize();
|
2018-07-23 22:36:46 +00:00
|
|
|
buf.sz = buf.cur - buf.base;
|
|
|
|
// pad smaller messages
|
2019-04-05 14:58:22 +00:00
|
|
|
if(buf.sz < pad_size)
|
2018-07-23 22:36:46 +00:00
|
|
|
{
|
|
|
|
// randomize padding
|
2019-04-05 14:58:22 +00:00
|
|
|
r->crypto()->randbytes(buf.cur, pad_size - buf.sz);
|
|
|
|
buf.sz = pad_size;
|
2018-07-23 22:36:46 +00:00
|
|
|
}
|
|
|
|
buf.cur = buf.base;
|
2018-06-25 15:12:08 +00:00
|
|
|
return HandleUpstream(buf, N, r);
|
|
|
|
}
|
|
|
|
|
2018-06-26 16:23:43 +00:00
|
|
|
bool
|
2019-04-22 17:38:29 +00:00
|
|
|
Path::HandlePathTransferMessage(
|
|
|
|
ABSL_ATTRIBUTE_UNUSED const routing::PathTransferMessage& msg,
|
|
|
|
ABSL_ATTRIBUTE_UNUSED AbstractRouter* r)
|
2018-06-26 16:23:43 +00:00
|
|
|
{
|
2019-02-11 19:45:42 +00:00
|
|
|
LogWarn("unwarranted path transfer message on tx=", TXID(),
|
|
|
|
" rx=", RXID());
|
2018-06-26 16:23:43 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-09-11 15:28:36 +00:00
|
|
|
bool
|
2019-04-22 17:38:29 +00:00
|
|
|
Path::HandleDataDiscardMessage(const routing::DataDiscardMessage& msg,
|
2019-02-11 19:45:42 +00:00
|
|
|
AbstractRouter* r)
|
2018-09-11 15:28:36 +00:00
|
|
|
{
|
2018-11-16 14:21:23 +00:00
|
|
|
MarkActive(r->Now());
|
2018-09-11 15:28:36 +00:00
|
|
|
if(m_DropHandler)
|
2019-04-22 17:38:29 +00:00
|
|
|
return m_DropHandler(this, msg.P, msg.S);
|
2018-09-11 15:28:36 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-06-25 15:12:08 +00:00
|
|
|
bool
|
2019-04-22 17:38:29 +00:00
|
|
|
Path::HandlePathConfirmMessage(
|
|
|
|
ABSL_ATTRIBUTE_UNUSED const routing::PathConfirmMessage& msg,
|
|
|
|
AbstractRouter* r)
|
2018-06-25 15:12:08 +00:00
|
|
|
{
|
2018-10-29 16:48:36 +00:00
|
|
|
auto now = r->Now();
|
2018-09-13 13:07:00 +00:00
|
|
|
if(_status == ePathBuilding)
|
2018-06-25 15:12:08 +00:00
|
|
|
{
|
2018-07-11 16:11:19 +00:00
|
|
|
// finish initializing introduction
|
|
|
|
intro.expiresAt = buildStarted + hops[0].lifetime;
|
|
|
|
|
2019-02-11 19:45:42 +00:00
|
|
|
r->routerProfiling().MarkPathSuccess(this);
|
2018-09-14 14:50:37 +00:00
|
|
|
|
2018-08-23 14:35:29 +00:00
|
|
|
// persist session with upstream router until the path is done
|
|
|
|
r->PersistSessionUntil(Upstream(), intro.expiresAt);
|
2018-11-16 14:21:23 +00:00
|
|
|
MarkActive(now);
|
2018-08-23 14:35:29 +00:00
|
|
|
// send path latency test
|
2019-02-11 19:45:42 +00:00
|
|
|
routing::PathLatencyMessage latency;
|
|
|
|
latency.T = randint();
|
2018-06-26 16:23:43 +00:00
|
|
|
m_LastLatencyTestID = latency.T;
|
2018-10-29 16:48:36 +00:00
|
|
|
m_LastLatencyTestTime = now;
|
2019-04-22 17:38:29 +00:00
|
|
|
return SendRoutingMessage(latency, r);
|
2018-06-25 15:12:08 +00:00
|
|
|
}
|
2019-02-11 19:45:42 +00:00
|
|
|
LogWarn("got unwarranted path confirm message on tx=", RXID(),
|
|
|
|
" rx=", RXID());
|
2018-06-22 00:25:30 +00:00
|
|
|
return false;
|
2018-06-25 15:12:08 +00:00
|
|
|
}
|
|
|
|
|
2018-08-02 00:48:43 +00:00
|
|
|
bool
|
2019-04-22 17:38:29 +00:00
|
|
|
Path::HandleHiddenServiceFrame(const service::ProtocolFrame& frame)
|
2018-08-02 00:48:43 +00:00
|
|
|
{
|
2018-11-16 14:21:23 +00:00
|
|
|
MarkActive(m_PathSet->Now());
|
2018-11-16 14:22:52 +00:00
|
|
|
return m_DataHandler && m_DataHandler(this, frame);
|
2018-08-02 00:48:43 +00:00
|
|
|
}
|
|
|
|
|
2018-06-25 15:12:08 +00:00
|
|
|
bool
|
2019-04-22 17:38:29 +00:00
|
|
|
Path::HandlePathLatencyMessage(const routing::PathLatencyMessage& msg,
|
2019-02-11 19:45:42 +00:00
|
|
|
AbstractRouter* r)
|
2018-06-25 15:12:08 +00:00
|
|
|
{
|
2018-10-29 16:48:36 +00:00
|
|
|
auto now = r->Now();
|
2018-11-16 14:21:23 +00:00
|
|
|
MarkActive(now);
|
2019-04-22 17:38:29 +00:00
|
|
|
if(msg.L == m_LastLatencyTestID)
|
2018-06-26 16:23:43 +00:00
|
|
|
{
|
2019-02-05 17:55:23 +00:00
|
|
|
intro.latency = now - m_LastLatencyTestTime;
|
2018-07-03 13:54:43 +00:00
|
|
|
m_LastLatencyTestID = 0;
|
2019-02-05 17:55:23 +00:00
|
|
|
EnterState(ePathEstablished, now);
|
|
|
|
if(m_BuiltHook)
|
|
|
|
m_BuiltHook(this);
|
|
|
|
m_BuiltHook = nullptr;
|
2019-03-07 22:53:36 +00:00
|
|
|
LogDebug("path latency is now ", intro.latency, " for ", Name());
|
2018-07-23 07:38:29 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-02-11 19:45:42 +00:00
|
|
|
LogWarn("unwarranted path latency message via ", Upstream());
|
2018-07-23 07:38:29 +00:00
|
|
|
return false;
|
2018-06-26 16:23:43 +00:00
|
|
|
}
|
2018-06-25 15:12:08 +00:00
|
|
|
}
|
2018-06-19 17:11:24 +00:00
|
|
|
|
2018-06-25 15:12:08 +00:00
|
|
|
bool
|
2019-04-22 17:38:29 +00:00
|
|
|
Path::HandleDHTMessage(const dht::IMessage& msg, AbstractRouter* r)
|
2018-06-25 15:12:08 +00:00
|
|
|
{
|
2019-03-25 15:41:37 +00:00
|
|
|
MarkActive(r->Now());
|
2019-02-11 19:45:42 +00:00
|
|
|
routing::DHTMessage reply;
|
2019-04-22 17:38:29 +00:00
|
|
|
if(!msg.HandleMessage(r->dht(), reply.M))
|
2018-09-02 18:25:42 +00:00
|
|
|
return false;
|
|
|
|
if(reply.M.size())
|
2019-04-22 17:38:29 +00:00
|
|
|
return SendRoutingMessage(reply, r);
|
2018-09-02 18:25:42 +00:00
|
|
|
return true;
|
2018-06-25 15:12:08 +00:00
|
|
|
}
|
2018-07-09 17:32:11 +00:00
|
|
|
|
2018-11-12 16:43:40 +00:00
|
|
|
bool
|
2019-04-22 17:38:29 +00:00
|
|
|
Path::HandleCloseExitMessage(const routing::CloseExitMessage& msg,
|
2019-02-11 19:45:42 +00:00
|
|
|
AbstractRouter* r)
|
2018-11-12 16:43:40 +00:00
|
|
|
{
|
2018-11-14 18:02:27 +00:00
|
|
|
/// allows exits to close from their end
|
2018-11-21 12:31:36 +00:00
|
|
|
if(SupportsAnyRoles(ePathRoleExit | ePathRoleSVC))
|
2018-11-14 18:02:27 +00:00
|
|
|
{
|
2019-04-22 17:38:29 +00:00
|
|
|
if(msg.Verify(r->crypto(), EndpointPubKey()))
|
2018-11-14 18:02:27 +00:00
|
|
|
{
|
2019-02-11 19:45:42 +00:00
|
|
|
LogInfo(Name(), " had its exit closed");
|
2018-11-14 18:02:27 +00:00
|
|
|
_role &= ~ePathRoleExit;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
2019-02-11 19:45:42 +00:00
|
|
|
LogError(Name(), " CXM from exit with bad signature");
|
2018-11-14 18:02:27 +00:00
|
|
|
}
|
|
|
|
else
|
2019-02-11 19:45:42 +00:00
|
|
|
LogError(Name(), " unwarranted CXM");
|
2018-11-12 16:43:40 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-11-14 19:34:17 +00:00
|
|
|
bool
|
2019-04-22 17:38:29 +00:00
|
|
|
Path::SendExitRequest(const routing::ObtainExitMessage& msg,
|
2019-02-11 19:45:42 +00:00
|
|
|
AbstractRouter* r)
|
2018-11-14 19:34:17 +00:00
|
|
|
{
|
2019-02-11 19:45:42 +00:00
|
|
|
LogInfo(Name(), " sending exit request to ", Endpoint());
|
2019-04-22 17:38:29 +00:00
|
|
|
m_ExitObtainTX = msg.T;
|
2018-11-14 19:34:17 +00:00
|
|
|
return SendRoutingMessage(msg, r);
|
|
|
|
}
|
|
|
|
|
2018-12-24 16:09:05 +00:00
|
|
|
bool
|
2019-04-22 17:38:29 +00:00
|
|
|
Path::SendExitClose(const routing::CloseExitMessage& msg, AbstractRouter* r)
|
2018-12-24 16:09:05 +00:00
|
|
|
{
|
2019-02-11 19:45:42 +00:00
|
|
|
LogInfo(Name(), " closing exit to ", Endpoint());
|
2018-12-24 16:09:05 +00:00
|
|
|
// mark as not exit anymore
|
|
|
|
_role &= ~ePathRoleExit;
|
|
|
|
return SendRoutingMessage(msg, r);
|
|
|
|
}
|
|
|
|
|
2018-11-12 16:43:40 +00:00
|
|
|
bool
|
2019-04-22 17:38:29 +00:00
|
|
|
Path::HandleObtainExitMessage(const routing::ObtainExitMessage& msg,
|
2019-02-11 19:45:42 +00:00
|
|
|
AbstractRouter* r)
|
2018-11-12 16:43:40 +00:00
|
|
|
{
|
|
|
|
(void)msg;
|
|
|
|
(void)r;
|
2019-02-11 19:45:42 +00:00
|
|
|
LogError(Name(), " got unwarranted OXM");
|
2018-11-12 16:43:40 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2019-04-22 17:38:29 +00:00
|
|
|
Path::HandleUpdateExitMessage(const routing::UpdateExitMessage& msg,
|
2019-02-11 19:45:42 +00:00
|
|
|
AbstractRouter* r)
|
2018-11-12 16:43:40 +00:00
|
|
|
{
|
|
|
|
(void)msg;
|
|
|
|
(void)r;
|
2019-02-11 19:45:42 +00:00
|
|
|
LogError(Name(), " got unwarranted UXM");
|
2018-11-12 16:43:40 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2019-04-22 17:38:29 +00:00
|
|
|
Path::HandleRejectExitMessage(const routing::RejectExitMessage& msg,
|
2019-02-11 19:45:42 +00:00
|
|
|
AbstractRouter* r)
|
2018-11-12 16:43:40 +00:00
|
|
|
{
|
2019-04-22 17:38:29 +00:00
|
|
|
if(m_ExitObtainTX && msg.T == m_ExitObtainTX)
|
2018-11-14 18:02:27 +00:00
|
|
|
{
|
2019-04-22 17:38:29 +00:00
|
|
|
if(!msg.Verify(r->crypto(), EndpointPubKey()))
|
2018-11-14 18:02:27 +00:00
|
|
|
{
|
2019-02-11 19:45:42 +00:00
|
|
|
LogError(Name(), "RXM invalid signature");
|
2018-11-14 18:02:27 +00:00
|
|
|
return false;
|
|
|
|
}
|
2019-02-11 19:45:42 +00:00
|
|
|
LogInfo(Name(), " ", Endpoint(), " Rejected exit");
|
2018-11-16 14:21:23 +00:00
|
|
|
MarkActive(r->Now());
|
2019-04-22 17:38:29 +00:00
|
|
|
return InformExitResult(msg.B);
|
2018-11-14 18:02:27 +00:00
|
|
|
}
|
2019-02-11 19:45:42 +00:00
|
|
|
LogError(Name(), " got unwarranted RXM");
|
2018-11-12 16:43:40 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2019-04-22 17:38:29 +00:00
|
|
|
Path::HandleGrantExitMessage(const routing::GrantExitMessage& msg,
|
2019-02-11 19:45:42 +00:00
|
|
|
AbstractRouter* r)
|
2018-11-12 16:43:40 +00:00
|
|
|
{
|
2019-04-22 17:38:29 +00:00
|
|
|
if(m_ExitObtainTX && msg.T == m_ExitObtainTX)
|
2018-11-14 18:02:27 +00:00
|
|
|
{
|
2019-04-22 17:38:29 +00:00
|
|
|
if(!msg.Verify(r->crypto(), EndpointPubKey()))
|
2018-11-14 18:02:27 +00:00
|
|
|
{
|
2019-02-11 19:45:42 +00:00
|
|
|
LogError(Name(), " GXM signature failed");
|
2018-11-14 18:02:27 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
// we now can send exit traffic
|
|
|
|
_role |= ePathRoleExit;
|
2019-02-11 19:45:42 +00:00
|
|
|
LogInfo(Name(), " ", Endpoint(), " Granted exit");
|
2018-11-16 14:21:23 +00:00
|
|
|
MarkActive(r->Now());
|
2018-11-14 18:02:27 +00:00
|
|
|
return InformExitResult(0);
|
|
|
|
}
|
2019-02-11 19:45:42 +00:00
|
|
|
LogError(Name(), " got unwarranted GXM");
|
2018-11-12 16:43:40 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-11-14 18:02:27 +00:00
|
|
|
bool
|
|
|
|
Path::InformExitResult(llarp_time_t B)
|
|
|
|
{
|
|
|
|
bool result = true;
|
|
|
|
for(const auto& hook : m_ObtainedExitHooks)
|
|
|
|
result &= hook(this, B);
|
|
|
|
m_ObtainedExitHooks.clear();
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2018-11-12 16:43:40 +00:00
|
|
|
bool
|
|
|
|
Path::HandleTransferTrafficMessage(
|
2019-04-22 17:38:29 +00:00
|
|
|
const routing::TransferTrafficMessage& msg, AbstractRouter* r)
|
2018-11-12 16:43:40 +00:00
|
|
|
{
|
2018-11-14 18:02:27 +00:00
|
|
|
// check if we can handle exit data
|
2018-11-21 12:31:36 +00:00
|
|
|
if(!SupportsAnyRoles(ePathRoleExit | ePathRoleSVC))
|
2018-11-14 18:02:27 +00:00
|
|
|
return false;
|
2018-11-16 14:21:23 +00:00
|
|
|
MarkActive(r->Now());
|
2018-11-14 18:02:27 +00:00
|
|
|
// handle traffic if we have a handler
|
2018-11-28 17:58:46 +00:00
|
|
|
if(!m_ExitTrafficHandler)
|
|
|
|
return false;
|
2019-04-22 17:38:29 +00:00
|
|
|
bool sent = msg.X.size() > 0;
|
|
|
|
for(const auto& pkt : msg.X)
|
2018-11-29 21:19:20 +00:00
|
|
|
{
|
|
|
|
if(pkt.size() <= 8)
|
|
|
|
return false;
|
|
|
|
uint64_t counter = bufbe64toh(pkt.data());
|
2018-12-02 18:07:07 +00:00
|
|
|
m_ExitTrafficHandler(
|
2019-02-02 23:12:42 +00:00
|
|
|
this, llarp_buffer_t(pkt.data() + 8, pkt.size() - 8), counter);
|
2018-11-29 21:19:20 +00:00
|
|
|
}
|
2018-11-28 17:58:46 +00:00
|
|
|
return sent;
|
2018-11-12 16:43:40 +00:00
|
|
|
}
|
|
|
|
|
2018-06-25 15:12:08 +00:00
|
|
|
} // namespace path
|
2018-06-21 09:31:53 +00:00
|
|
|
} // namespace llarp
|