2018-06-12 16:45:12 +00:00
|
|
|
#include <deque>
|
2018-06-10 14:05:48 +00:00
|
|
|
#include <llarp/encrypted_frame.hpp>
|
|
|
|
#include <llarp/path.hpp>
|
2018-06-22 00:25:30 +00:00
|
|
|
#include "buffer.hpp"
|
2018-06-10 14:05:48 +00:00
|
|
|
#include "router.hpp"
|
|
|
|
|
|
|
|
namespace llarp
|
|
|
|
{
|
|
|
|
PathContext::PathContext(llarp_router* router)
|
|
|
|
: m_Router(router), m_AllowTransit(false)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
PathContext::~PathContext()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
PathContext::AllowTransit()
|
|
|
|
{
|
|
|
|
m_AllowTransit = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2018-06-18 22:03:50 +00:00
|
|
|
PathContext::AllowingTransit() const
|
2018-06-10 14:05:48 +00:00
|
|
|
{
|
2018-06-18 22:03:50 +00:00
|
|
|
return m_AllowTransit;
|
2018-06-10 14:05:48 +00:00
|
|
|
}
|
|
|
|
|
2018-06-12 16:45:12 +00:00
|
|
|
llarp_threadpool*
|
|
|
|
PathContext::Worker()
|
|
|
|
{
|
|
|
|
return m_Router->tp;
|
|
|
|
}
|
|
|
|
|
|
|
|
llarp_crypto*
|
|
|
|
PathContext::Crypto()
|
|
|
|
{
|
|
|
|
return &m_Router->crypto;
|
|
|
|
}
|
|
|
|
|
2018-06-15 14:33:38 +00:00
|
|
|
llarp_logic*
|
|
|
|
PathContext::Logic()
|
|
|
|
{
|
|
|
|
return m_Router->logic;
|
|
|
|
}
|
|
|
|
|
2018-06-12 16:45:12 +00:00
|
|
|
byte_t*
|
|
|
|
PathContext::EncryptionSecretKey()
|
|
|
|
{
|
|
|
|
return m_Router->encryption;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
PathContext::HopIsUs(const PubKey& k) const
|
|
|
|
{
|
|
|
|
return memcmp(k, m_Router->pubkey(), PUBKEYSIZE) == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
PathContext::ForwardLRCM(const RouterID& nextHop,
|
2018-06-18 22:03:50 +00:00
|
|
|
std::deque< EncryptedFrame >& frames)
|
2018-06-12 16:45:12 +00:00
|
|
|
{
|
2018-06-20 12:34:48 +00:00
|
|
|
llarp::Info("fowarding LRCM to ", nextHop);
|
2018-06-12 16:45:12 +00:00
|
|
|
LR_CommitMessage* msg = new LR_CommitMessage;
|
|
|
|
while(frames.size())
|
|
|
|
{
|
2018-06-21 12:55:02 +00:00
|
|
|
msg->frames.push_back(frames.front());
|
|
|
|
frames.pop_front();
|
2018-06-12 16:45:12 +00:00
|
|
|
}
|
2018-06-21 09:31:53 +00:00
|
|
|
return m_Router->SendToOrQueue(nextHop, msg);
|
2018-06-12 16:45:12 +00:00
|
|
|
}
|
2018-06-22 00:25:30 +00:00
|
|
|
template < typename Map_t, typename Key_t, typename CheckValue_t >
|
|
|
|
IHopHandler*
|
|
|
|
MapGet(Map_t& map, const Key_t& k, CheckValue_t check)
|
|
|
|
{
|
|
|
|
std::unique_lock< std::mutex > lock(map.first);
|
2018-06-22 12:45:46 +00:00
|
|
|
auto range = map.second.equal_range(k);
|
|
|
|
for(auto i = range.first; i != range.second; ++i)
|
2018-06-22 00:25:30 +00:00
|
|
|
{
|
2018-06-22 12:45:46 +00:00
|
|
|
if(check(i->second))
|
|
|
|
return i->second;
|
2018-06-22 00:25:30 +00:00
|
|
|
}
|
|
|
|
return nullptr;
|
|
|
|
}
|
2018-06-12 16:45:12 +00:00
|
|
|
|
2018-06-18 22:03:50 +00:00
|
|
|
template < typename Map_t, typename Key_t, typename CheckValue_t >
|
2018-06-12 16:45:12 +00:00
|
|
|
bool
|
2018-06-18 22:03:50 +00:00
|
|
|
MapHas(Map_t& map, const Key_t& k, CheckValue_t check)
|
2018-06-12 16:45:12 +00:00
|
|
|
{
|
|
|
|
std::unique_lock< std::mutex > lock(map.first);
|
2018-06-22 12:45:46 +00:00
|
|
|
auto range = map.second.equal_range(k);
|
|
|
|
for(auto i = range.first; i != range.second; ++i)
|
2018-06-18 22:03:50 +00:00
|
|
|
{
|
2018-06-22 12:45:46 +00:00
|
|
|
if(check(i->second))
|
2018-06-18 22:03:50 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
2018-06-12 16:45:12 +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)
|
|
|
|
{
|
|
|
|
std::unique_lock< std::mutex > lock(map.first);
|
2018-06-18 22:03:50 +00:00
|
|
|
map.second.emplace(k, v);
|
2018-06-12 16:45:12 +00:00
|
|
|
}
|
|
|
|
|
2018-06-22 12:45:46 +00:00
|
|
|
template < typename Map_t, typename Visit_t >
|
|
|
|
void
|
|
|
|
MapIter(Map_t& map, Visit_t v)
|
|
|
|
{
|
|
|
|
std::unique_lock< std::mutex > lock(map.first);
|
|
|
|
for(const auto& item : map.second)
|
|
|
|
v(item);
|
|
|
|
}
|
|
|
|
|
2018-06-22 00:25:30 +00:00
|
|
|
template < typename Map_t, typename Key_t, typename Check_t >
|
|
|
|
void
|
|
|
|
MapDel(Map_t& map, const Key_t& k, Check_t check)
|
|
|
|
{
|
|
|
|
std::unique_lock< std::mutex > lock(map.first);
|
2018-06-22 12:45:46 +00:00
|
|
|
auto range = map.second.equal_range(k);
|
|
|
|
for(auto i = range.first; i != range.second;)
|
2018-06-22 00:25:30 +00:00
|
|
|
{
|
2018-06-22 12:45:46 +00:00
|
|
|
if(check(i->second))
|
|
|
|
i = map.second.erase(i);
|
2018-06-22 00:25:30 +00:00
|
|
|
else
|
2018-06-22 12:45:46 +00:00
|
|
|
++i;
|
2018-06-22 00:25:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-19 17:11:24 +00:00
|
|
|
void
|
|
|
|
PathContext::AddOwnPath(Path* path)
|
|
|
|
{
|
2018-06-22 12:45:46 +00:00
|
|
|
MapPut(m_OurPaths, path->TXID(), path);
|
|
|
|
MapPut(m_OurPaths, path->RXID(), path);
|
2018-06-19 17:11:24 +00:00
|
|
|
}
|
|
|
|
|
2018-06-10 14:05:48 +00:00
|
|
|
bool
|
|
|
|
PathContext::HasTransitHop(const TransitHopInfo& info)
|
|
|
|
{
|
2018-06-22 12:45:46 +00:00
|
|
|
return MapHas(m_TransitPaths, info.txID, [info](TransitHop* hop) -> bool {
|
2018-06-22 00:25:30 +00:00
|
|
|
return info == hop->info;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
IHopHandler*
|
|
|
|
PathContext::GetByUpstream(const RouterID& remote, const PathID_t& id)
|
|
|
|
{
|
|
|
|
auto own = MapGet(m_OurPaths, id, [remote](const Path* p) -> bool {
|
|
|
|
return p->Upstream() == remote;
|
|
|
|
});
|
|
|
|
if(own)
|
|
|
|
return own;
|
2018-06-22 12:45:46 +00:00
|
|
|
|
2018-06-22 00:25:30 +00:00
|
|
|
return MapGet(m_TransitPaths, id, [remote](const TransitHop* hop) -> bool {
|
|
|
|
return hop->info.upstream == remote;
|
|
|
|
});
|
2018-06-18 22:03:50 +00:00
|
|
|
}
|
|
|
|
|
2018-06-22 12:45:46 +00:00
|
|
|
IHopHandler*
|
|
|
|
PathContext::GetByDownstream(const RouterID& remote, const PathID_t& id)
|
|
|
|
{
|
|
|
|
return MapGet(m_TransitPaths, id, [remote](const TransitHop* hop) -> bool {
|
|
|
|
return hop->info.downstream == remote;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2018-06-18 22:03:50 +00:00
|
|
|
const byte_t*
|
|
|
|
PathContext::OurRouterID() const
|
|
|
|
{
|
|
|
|
return m_Router->pubkey();
|
2018-06-12 16:45:12 +00:00
|
|
|
}
|
|
|
|
|
2018-06-22 00:25:30 +00:00
|
|
|
llarp_router*
|
|
|
|
PathContext::Router()
|
|
|
|
{
|
|
|
|
return m_Router;
|
|
|
|
}
|
|
|
|
|
2018-06-12 16:45:12 +00:00
|
|
|
void
|
2018-06-22 00:25:30 +00:00
|
|
|
PathContext::PutTransitHop(TransitHop* hop)
|
2018-06-12 16:45:12 +00:00
|
|
|
{
|
2018-06-22 00:25:30 +00:00
|
|
|
MapPut(m_TransitPaths, hop->info.txID, hop);
|
|
|
|
MapPut(m_TransitPaths, hop->info.rxID, hop);
|
2018-06-18 22:03:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
PathContext::ExpirePaths()
|
|
|
|
{
|
|
|
|
std::unique_lock< std::mutex > lock(m_TransitPaths.first);
|
|
|
|
auto now = llarp_time_now_ms();
|
|
|
|
auto& map = m_TransitPaths.second;
|
|
|
|
auto itr = map.begin();
|
2018-06-22 00:25:30 +00:00
|
|
|
std::set< TransitHop* > removePaths;
|
2018-06-18 22:03:50 +00:00
|
|
|
while(itr != map.end())
|
|
|
|
{
|
2018-06-22 00:25:30 +00:00
|
|
|
if(itr->second->Expired(now))
|
|
|
|
{
|
|
|
|
TransitHop* path = itr->second;
|
|
|
|
llarp::Info("transit path expired ", path);
|
|
|
|
removePaths.insert(path);
|
|
|
|
}
|
|
|
|
++itr;
|
|
|
|
}
|
|
|
|
for(auto& p : removePaths)
|
|
|
|
{
|
|
|
|
map.erase(p->info.txID);
|
|
|
|
map.erase(p->info.rxID);
|
|
|
|
delete p;
|
2018-06-18 22:03:50 +00:00
|
|
|
}
|
2018-06-12 16:45:12 +00:00
|
|
|
}
|
|
|
|
|
2018-06-22 00:25:30 +00:00
|
|
|
Path::Path(llarp_path_hops* h) : hops(h->numHops)
|
|
|
|
{
|
|
|
|
for(size_t idx = 0; idx < h->numHops; ++idx)
|
|
|
|
{
|
|
|
|
llarp_rc_copy(&hops[idx].router, &h->hops[idx].router);
|
2018-06-22 12:45:46 +00:00
|
|
|
hops[idx].txID.Randomize();
|
|
|
|
hops[idx].rxID.Randomize();
|
|
|
|
}
|
|
|
|
for(size_t idx = (h->numHops - 1); idx > 0; --idx)
|
|
|
|
{
|
|
|
|
hops[idx].txID = hops[idx - 1].rxID;
|
2018-06-22 00:25:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const PathID_t&
|
|
|
|
Path::TXID() const
|
|
|
|
{
|
2018-06-22 05:44:19 +00:00
|
|
|
return hops[0].txID;
|
2018-06-22 00:25:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const PathID_t&
|
|
|
|
Path::RXID() const
|
|
|
|
{
|
2018-06-22 05:44:19 +00:00
|
|
|
return hops[0].rxID;
|
2018-06-22 00:25:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
RouterID
|
|
|
|
Path::Upstream() const
|
|
|
|
{
|
|
|
|
return hops[0].router.pubkey;
|
|
|
|
}
|
|
|
|
|
2018-06-12 16:45:12 +00:00
|
|
|
bool
|
2018-06-22 00:25:30 +00:00
|
|
|
Path::HandleUpstream(llarp_buffer_t buf, const TunnelNonce& Y,
|
|
|
|
llarp_router* r)
|
2018-06-12 16:45:12 +00:00
|
|
|
{
|
2018-06-22 00:25:30 +00:00
|
|
|
for(const auto& hop : hops)
|
|
|
|
{
|
|
|
|
r->crypto.xchacha20(buf, hop.shared, Y);
|
|
|
|
}
|
|
|
|
RelayUpstreamMessage* msg = new RelayUpstreamMessage;
|
|
|
|
msg->X = buf;
|
|
|
|
msg->Y = Y;
|
2018-06-22 12:45:46 +00:00
|
|
|
msg->pathid = TXID();
|
2018-06-22 00:25:30 +00:00
|
|
|
return r->SendToOrQueue(Upstream(), msg);
|
2018-06-10 14:05:48 +00:00
|
|
|
}
|
|
|
|
|
2018-06-22 00:25:30 +00:00
|
|
|
bool
|
|
|
|
Path::Expired(llarp_time_t now) const
|
2018-06-10 14:05:48 +00:00
|
|
|
{
|
2018-06-22 00:25:30 +00:00
|
|
|
return now - buildStarted > hops[0].lifetime;
|
2018-06-10 14:05:48 +00:00
|
|
|
}
|
2018-06-19 17:11:24 +00:00
|
|
|
|
2018-06-22 00:25:30 +00:00
|
|
|
bool
|
|
|
|
Path::HandleDownstream(llarp_buffer_t buf, const TunnelNonce& Y,
|
|
|
|
llarp_router* r)
|
2018-06-20 12:34:48 +00:00
|
|
|
{
|
2018-06-22 13:59:28 +00:00
|
|
|
for(const auto& hop : hops)
|
2018-06-20 12:34:48 +00:00
|
|
|
{
|
2018-06-22 13:59:28 +00:00
|
|
|
r->crypto.xchacha20(buf, hop.shared, Y);
|
2018-06-20 12:34:48 +00:00
|
|
|
}
|
2018-06-22 00:25:30 +00:00
|
|
|
return HandleRoutingMessage(buf, r);
|
2018-06-20 12:34:48 +00:00
|
|
|
}
|
|
|
|
|
2018-06-22 00:25:30 +00:00
|
|
|
bool
|
2018-06-23 00:00:44 +00:00
|
|
|
Path::HandleHiddenServiceData(llarp_buffer_t buf)
|
2018-06-19 17:11:24 +00:00
|
|
|
{
|
2018-06-22 00:25:30 +00:00
|
|
|
// TODO: implement me
|
2018-06-23 00:00:44 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-06-22 00:25:30 +00:00
|
|
|
bool
|
|
|
|
Path::HandleRoutingMessage(llarp_buffer_t buf, llarp_router* r)
|
2018-06-19 17:11:24 +00:00
|
|
|
{
|
2018-06-22 13:59:28 +00:00
|
|
|
if(!m_InboundMessageParser.ParseMessageBuffer(buf, this))
|
|
|
|
{
|
|
|
|
llarp::Warn("Failed to parse inbound routing message");
|
|
|
|
return false;
|
|
|
|
}
|
2018-06-22 00:25:30 +00:00
|
|
|
return true;
|
2018-06-19 17:11:24 +00:00
|
|
|
}
|
|
|
|
|
2018-06-22 00:25:30 +00:00
|
|
|
bool
|
|
|
|
Path::SendRoutingMessage(const llarp::routing::IMessage* msg, llarp_router* r)
|
2018-06-19 17:11:24 +00:00
|
|
|
{
|
2018-06-22 00:25:30 +00:00
|
|
|
byte_t tmp[MAX_LINK_MSG_SIZE / 2];
|
|
|
|
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
|
|
|
|
if(!msg->BEncode(&buf))
|
|
|
|
return false;
|
|
|
|
// rewind
|
|
|
|
buf.sz = buf.cur - buf.base;
|
|
|
|
buf.cur = buf.base;
|
|
|
|
// make nonce
|
|
|
|
TunnelNonce N;
|
|
|
|
N.Randomize();
|
|
|
|
return HandleUpstream(buf, N, r);
|
2018-06-19 17:11:24 +00:00
|
|
|
}
|
|
|
|
|
2018-06-21 09:31:53 +00:00
|
|
|
} // namespace llarp
|