1
1
Fork 0
mirror of https://github.com/oxen-io/lokinet synced 2023-12-14 06:53:00 +01:00
lokinet/llarp/service/endpoint.cpp

270 lines
6.7 KiB
C++
Raw Normal View History

2018-07-18 05:10:21 +02:00
#include <llarp/dht/messages/findintro.hpp>
#include <llarp/messages/dht.hpp>
#include <llarp/service/endpoint.hpp>
#include "router.hpp"
namespace llarp
{
namespace service
{
Endpoint::Endpoint(const std::string& name, llarp_router* r)
2018-07-12 20:21:44 +02:00
: llarp_pathbuilder_context(r, r->dht, 2), m_Router(r), m_Name(name)
{
2018-07-19 00:50:05 +02:00
m_Tag.Zero();
}
bool
Endpoint::SetOption(const std::string& k, const std::string& v)
{
if(k == "keyfile")
{
m_Keyfile = v;
}
2018-07-18 05:10:21 +02:00
if(k == "tag")
{
m_Tag = v;
llarp::LogInfo("Setting tag to ", v);
2018-07-18 05:10:21 +02:00
}
if(k == "prefetch-tag")
{
m_PrefetchTags.insert(v);
}
return true;
}
void
2018-07-19 00:50:05 +02:00
Endpoint::Tick(llarp_time_t now)
{
2018-07-19 00:50:05 +02:00
if(ShouldPublishDescriptors(now))
{
2018-07-18 05:10:21 +02:00
std::list< Introduction > I;
if(!GetCurrentIntroductions(I))
{
2018-07-16 05:32:13 +02:00
llarp::LogWarn("could not publish descriptors for endpoint ", Name(),
" because we couldn't get any introductions");
return;
}
2018-07-19 00:50:05 +02:00
m_IntroSet.I = I;
m_IntroSet.topic = m_Tag;
2018-07-18 05:10:21 +02:00
if(!m_Identity.SignIntroSet(m_IntroSet, &m_Router->crypto))
{
2018-07-16 05:32:13 +02:00
llarp::LogWarn("failed to sign introset for endpoint ", Name());
return;
}
2018-07-17 08:17:13 +02:00
if(PublishIntroSet(m_Router))
{
2018-07-16 05:32:13 +02:00
llarp::LogInfo("publishing introset for endpoint ", Name());
}
else
{
2018-07-16 05:32:13 +02:00
llarp::LogWarn("failed to publish intro set for endpoint ", Name());
}
}
2018-07-18 05:10:21 +02:00
for(const auto& tag : m_PrefetchTags)
{
auto itr = m_PrefetchedTags.find(tag);
if(itr == m_PrefetchedTags.end())
{
2018-07-19 00:50:05 +02:00
itr = m_PrefetchedTags.emplace(tag, tag).first;
2018-07-18 05:10:21 +02:00
}
2018-07-19 00:50:05 +02:00
itr->second.Expire(now);
if(itr->second.ShouldRefresh(now))
2018-07-18 05:10:21 +02:00
{
auto path = PickRandomEstablishedPath();
if(path)
{
2018-07-19 00:50:05 +02:00
itr->second.pendingTX = GenTXID();
m_PendingLookups[itr->second.pendingTX] = &itr->second;
itr->second.SendRequestViaPath(path, m_Router);
2018-07-18 05:10:21 +02:00
}
}
}
}
uint64_t
Endpoint::GenTXID()
{
uint64_t txid = rand();
while(m_PendingLookups.find(txid) != m_PendingLookups.end())
++txid;
return txid;
}
2018-07-16 05:32:13 +02:00
std::string
Endpoint::Name() const
{
return m_Name + ":" + m_Identity.pub.Name();
}
bool
Endpoint::HandleGotIntroMessage(const llarp::dht::GotIntroMessage* msg)
{
auto crypto = &m_Router->crypto;
2018-07-18 05:10:21 +02:00
std::set< IntroSet > remote;
for(const auto& introset : msg->I)
{
2018-07-19 00:50:05 +02:00
if(!introset.VerifySignature(crypto))
{
2018-07-19 00:50:05 +02:00
llarp::LogInfo("invalid introset signature for ", introset,
" on endpoint ", Name());
if(m_Identity.pub == introset.A)
{
IntroSetPublishFail();
}
2018-07-19 00:50:05 +02:00
return false;
}
if(m_Identity.pub == introset.A)
{
llarp::LogInfo(
"got introset publish confirmation for hidden service endpoint ",
2018-07-16 05:32:13 +02:00
Name());
2018-07-17 08:17:13 +02:00
IntroSetPublished();
2018-07-18 05:10:21 +02:00
return true;
}
else
{
2018-07-18 05:10:21 +02:00
remote.insert(introset);
}
}
2018-07-18 05:10:21 +02:00
auto itr = m_PendingLookups.find(msg->T);
if(itr == m_PendingLookups.end())
{
llarp::LogWarn("invalid lookup response for hidden service endpoint ",
Name(), " txid=", msg->T);
return false;
}
bool result = itr->second->HandleResponse(remote);
m_PendingLookups.erase(itr);
return result;
}
bool
Endpoint::Start()
{
auto crypto = &m_Router->crypto;
if(m_Keyfile.size())
{
if(!m_Identity.EnsureKeys(m_Keyfile, crypto))
return false;
}
else
{
m_Identity.RegenerateKeys(crypto);
}
return true;
}
Endpoint::~Endpoint()
{
}
2018-07-12 20:21:44 +02:00
2018-07-18 05:10:21 +02:00
Endpoint::CachedTagResult::~CachedTagResult()
{
}
bool
Endpoint::CachedTagResult::HandleResponse(
2018-07-19 00:50:05 +02:00
const std::set< IntroSet >& introsets)
2018-07-18 05:10:21 +02:00
{
2018-07-19 00:50:05 +02:00
llarp::LogInfo("Tag result for ", tag.ToString(), " got ",
introsets.size(), " results");
lastModified = llarp_time_now_ms();
pendingTX = 0;
for(const auto& introset : introsets)
result.insert(introset);
2018-07-18 05:10:21 +02:00
return true;
}
2018-07-19 00:50:05 +02:00
void
Endpoint::CachedTagResult::Expire(llarp_time_t now)
{
auto itr = result.begin();
while(itr != result.end())
{
if(itr->HasExpiredIntros(now))
{
itr = result.erase(itr);
}
else
{
++itr;
}
}
}
2018-07-18 05:10:21 +02:00
llarp::routing::IMessage*
Endpoint::CachedTagResult::BuildRequestMessage()
{
llarp::routing::DHTMessage* msg = new llarp::routing::DHTMessage();
msg->M.push_back(new llarp::dht::FindIntroMessage(tag, pendingTX));
return msg;
}
bool
Endpoint::PublishIntroSet(llarp_router* r)
{
auto path = PickRandomEstablishedPath();
if(path)
{
m_CurrentPublishTX = rand();
llarp::routing::DHTMessage msg;
msg.M.push_back(new llarp::dht::PublishIntroMessage(
2018-07-19 00:50:05 +02:00
m_IntroSet, m_CurrentPublishTX, 3));
2018-07-18 05:10:21 +02:00
if(path->SendRoutingMessage(&msg, r))
{
m_LastPublishAttempt = llarp_time_now_ms();
llarp::LogInfo(Name(), " publishing introset");
return true;
}
}
llarp::LogWarn(Name(), " publish introset failed");
return false;
2018-07-18 05:10:21 +02:00
}
void
Endpoint::IntroSetPublishFail()
{
llarp::LogWarn("failed to publish introset for ", Name());
m_CurrentPublishTX = 0;
}
bool
2018-07-19 00:50:05 +02:00
Endpoint::ShouldPublishDescriptors(llarp_time_t now) const
2018-07-18 05:10:21 +02:00
{
2018-07-19 00:50:05 +02:00
if(m_IntroSet.HasExpiredIntros(now))
2018-07-18 05:10:21 +02:00
return m_CurrentPublishTX == 0
&& now - m_LastPublishAttempt >= INTROSET_PUBLISH_RETRY_INTERVAL;
return m_CurrentPublishTX == 0
&& now - m_LastPublish >= INTROSET_PUBLISH_INTERVAL;
}
void
Endpoint::IntroSetPublished()
{
m_CurrentPublishTX = 0;
m_LastPublish = llarp_time_now_ms();
llarp::LogInfo(Name(), " IntroSet publish confirmed");
}
2018-07-12 20:21:44 +02:00
Endpoint::OutboundContext::OutboundContext(Endpoint* parent)
: llarp_pathbuilder_context(parent->m_Router, parent->m_Router->dht, 2)
, m_Parent(parent)
{
}
Endpoint::OutboundContext::~OutboundContext()
{
}
bool
Endpoint::OutboundContext::HandleGotIntroMessage(
const llarp::dht::GotIntroMessage* msg)
{
// TODO: implement me
2018-07-19 00:50:05 +02:00
2018-07-12 20:21:44 +02:00
return false;
}
} // namespace service
2018-07-16 05:32:13 +02:00
} // namespace llarp