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

334 lines
8.5 KiB
C++
Raw Normal View History

2018-07-09 19:32:11 +02:00
#ifndef LLARP_SERVICE_ENDPOINT_HPP
#define LLARP_SERVICE_ENDPOINT_HPP
2018-07-19 06:58:39 +02:00
#include <llarp/codel.hpp>
2018-07-09 19:32:11 +02:00
#include <llarp/pathbuilder.hpp>
#include <llarp/service/Identity.hpp>
#include <llarp/service/handler.hpp>
2018-07-19 06:58:39 +02:00
#include <llarp/service/protocol.hpp>
2018-07-09 19:32:11 +02:00
namespace llarp
{
namespace service
{
2018-08-09 21:02:17 +02:00
struct Endpoint : public llarp_pathbuilder_context,
public ILookupHolder,
public IDataHandler
2018-07-09 19:32:11 +02:00
{
2018-07-18 05:10:21 +02:00
/// minimum interval for publishing introsets
static const llarp_time_t INTROSET_PUBLISH_INTERVAL =
DEFAULT_PATH_LIFETIME / 4;
static const llarp_time_t INTROSET_PUBLISH_RETRY_INTERVAL = 5000;
2018-07-09 19:32:11 +02:00
Endpoint(const std::string& nickname, llarp_router* r);
~Endpoint();
void
SetHandler(IDataHandler* h);
2018-07-09 19:32:11 +02:00
bool
SetOption(const std::string& k, const std::string& v);
void
2018-07-19 00:50:05 +02:00
Tick(llarp_time_t now);
2018-08-09 21:02:17 +02:00
/// router's logic
2018-07-19 06:58:39 +02:00
llarp_logic*
2018-08-09 21:02:17 +02:00
RouterLogic();
/// endpoint's logic
llarp_logic*
EndpointLogic();
2018-07-19 06:58:39 +02:00
llarp_crypto*
Crypto();
llarp_threadpool*
Worker();
2018-07-23 01:14:29 +02:00
llarp_router*
Router()
{
return m_Router;
}
2018-07-09 19:32:11 +02:00
bool
Start();
2018-07-16 05:32:13 +02:00
std::string
Name() const;
2018-07-18 05:10:21 +02:00
bool
2018-07-19 00:50:05 +02:00
ShouldPublishDescriptors(llarp_time_t now) const;
2018-07-18 05:10:21 +02:00
bool
PublishIntroSet(llarp_router* r);
bool
HandleGotIntroMessage(const llarp::dht::GotIntroMessage* msg);
2018-08-10 23:34:11 +02:00
bool
HandleGotRouterMessage(const llarp::dht::GotRouterMessage* msg);
2018-07-12 20:21:44 +02:00
bool
HandleHiddenServiceFrame(const llarp::service::ProtocolFrame* msg);
2018-07-12 20:21:44 +02:00
/// return true if we have an established path to a hidden service
bool
HasPathToService(const Address& remote) const;
2018-08-10 05:51:38 +02:00
/// return true if we have a pending job to build to a hidden service but
/// it's not done yet
bool
HasPendingPathToService(const Address& remote) const;
2018-07-12 20:21:44 +02:00
/// return false if we don't have a path to the service
/// return true if we did and we removed it
bool
ForgetPathToService(const Address& remote);
2018-08-09 21:02:17 +02:00
virtual void
HandleDataMessage(ProtocolMessage* msg)
{
// override me in subclass
}
2018-08-10 23:34:11 +02:00
/// ensure that we know a router, looks up if it doesn't
void
EnsureRouterIsKnown(const RouterID& router);
2018-07-23 01:14:29 +02:00
Identity*
GetIdentity()
{
return &m_Identity;
}
2018-07-19 06:58:39 +02:00
2018-08-04 04:59:32 +02:00
void
PutLookup(IServiceLookup* lookup, uint64_t txid);
void
HandlePathBuilt(path::Path* path);
2018-07-12 20:21:44 +02:00
/// context needed to initiate an outbound hidden service session
struct OutboundContext : public llarp_pathbuilder_context
{
OutboundContext(const IntroSet& introSet, Endpoint* parent);
2018-07-12 20:21:44 +02:00
~OutboundContext();
/// the remote hidden service's curren intro set
IntroSet currentIntroSet;
2018-07-23 01:14:29 +02:00
/// the current selected intro
Introduction selectedIntro;
/// update the current selected intro to be a new best introduction
void
ShiftIntroduction();
2018-07-12 20:21:44 +02:00
/// tick internal state
/// return true to remove otherwise don't remove
bool
Tick(llarp_time_t now);
2018-07-12 20:21:44 +02:00
/// encrypt asynchronously and send to remote endpoint from us
2018-07-19 06:58:39 +02:00
void
AsyncEncryptAndSendTo(llarp_buffer_t D, ProtocolType protocol);
2018-07-12 20:21:44 +02:00
/// issues a lookup to find the current intro set of the remote service
void
UpdateIntroSet();
void
HandlePathBuilt(path::Path* path);
bool
SelectHop(llarp_nodedb* db, llarp_rc* prev, llarp_rc* cur, size_t hop);
bool
HandleHiddenServiceFrame(const ProtocolFrame* frame);
2018-08-04 04:59:32 +02:00
void
PutLookup(IServiceLookup* lookup, uint64_t txid);
std::string
Name() const;
2018-07-12 20:21:44 +02:00
private:
2018-08-10 23:34:11 +02:00
bool
OnIntroSetUpdate(const IntroSet* i);
2018-07-19 06:58:39 +02:00
void
2018-08-09 21:02:17 +02:00
EncryptAndSendTo(llarp_buffer_t payload);
2018-07-19 06:58:39 +02:00
void
2018-07-23 01:14:29 +02:00
AsyncGenIntro(llarp_buffer_t payload);
/// send a fully encrypted hidden service frame
2018-07-19 06:58:39 +02:00
void
2018-07-23 01:14:29 +02:00
Send(ProtocolFrame& f);
2018-07-19 06:58:39 +02:00
uint64_t sequenceNo = 0;
2018-07-12 20:21:44 +02:00
llarp::SharedSecret sharedKey;
Endpoint* m_Parent;
2018-08-04 04:59:32 +02:00
uint64_t m_UpdateIntrosetTX = 0;
2018-07-12 20:21:44 +02:00
};
// passed a sendto context when we have a path established otherwise
// nullptr if the path was not made before the timeout
typedef std::function< void(OutboundContext*) > PathEnsureHook;
/// return false if we have already called this function before for this
/// address
bool
EnsurePathToService(const Address& remote, PathEnsureHook h,
uint64_t timeoutMS);
virtual bool
HandleAuthenticatedDataFrom(const Address& remote, llarp_buffer_t data)
{
/// TODO: imlement me
return true;
}
2018-08-09 21:02:17 +02:00
void
PutSenderFor(const ConvoTag& tag, const ServiceInfo& info);
bool
GetCachedSessionKeyFor(const ConvoTag& remote,
SharedSecret& secret) const;
void
PutCachedSessionKeyFor(const ConvoTag& remote,
const SharedSecret& secret);
bool
GetSenderFor(const ConvoTag& remote, ServiceInfo& si) const;
void
PutIntroFor(const ConvoTag& remote, const Introduction& intro);
bool
GetIntroFor(const ConvoTag& remote, Introduction& intro) const;
bool
GetConvoTagsForService(const ServiceInfo& si,
std::set< ConvoTag >& tag) const;
void
PutNewOutboundContext(const IntroSet& introset);
2018-07-18 05:10:21 +02:00
protected:
virtual void
IntroSetPublishFail();
virtual void
IntroSetPublished();
IServiceLookup*
GenerateLookupByTag(const Tag& tag);
void
PrefetchServicesByTag(const Tag& tag);
2018-08-09 21:02:17 +02:00
uint64_t
GetSeqNoForConvo(const ConvoTag& tag);
bool
IsolateNetwork();
2018-07-18 05:10:21 +02:00
private:
2018-08-10 23:34:11 +02:00
bool
OnOutboundLookup(const IntroSet* i); /* */
2018-08-09 21:02:17 +02:00
static bool
SetupIsolatedNetwork(void* user);
bool
DoNetworkIsolation();
2018-07-18 05:10:21 +02:00
uint64_t
GenTXID();
protected:
IDataHandler* m_DataHandler = nullptr;
2018-08-09 21:02:17 +02:00
Identity m_Identity;
2018-07-09 19:32:11 +02:00
private:
llarp_router* m_Router;
2018-08-09 21:02:17 +02:00
llarp_threadpool* m_IsolatedWorker = nullptr;
llarp_logic* m_IsolatedLogic = nullptr;
2018-07-09 19:32:11 +02:00
std::string m_Keyfile;
std::string m_Name;
2018-08-09 21:02:17 +02:00
std::string m_NetNS;
2018-07-12 20:21:44 +02:00
std::unordered_map< Address, OutboundContext*, Address::Hash >
m_RemoteSessions;
2018-07-23 01:14:29 +02:00
std::unordered_map< Address, PathEnsureHook, Address::Hash >
m_PendingServiceLookups;
2018-08-10 23:34:11 +02:00
std::unordered_map< RouterID, uint64_t, RouterID::Hash > m_PendingRouters;
2018-07-18 05:10:21 +02:00
uint64_t m_CurrentPublishTX = 0;
llarp_time_t m_LastPublish = 0;
llarp_time_t m_LastPublishAttempt = 0;
/// our introset
service::IntroSet m_IntroSet;
/// pending remote service lookups by id
2018-07-18 05:10:21 +02:00
std::unordered_map< uint64_t, service::IServiceLookup* > m_PendingLookups;
/// prefetch remote address list
std::set< Address > m_PrefetchAddrs;
2018-07-18 05:10:21 +02:00
/// hidden service tag
Tag m_Tag;
/// prefetch descriptors for these hidden service tags
std::set< Tag > m_PrefetchTags;
2018-08-09 21:02:17 +02:00
/// on initialize functions
std::list< std::function< bool(void) > > m_OnInit;
struct Session
{
SharedSecret sharedKey;
ServiceInfo remote;
Introduction intro;
llarp_time_t lastUsed = 0;
uint64_t seqno = 0;
};
/// sessions
std::unordered_map< ConvoTag, Session, ConvoTag::Hash > m_Sessions;
2018-07-18 05:10:21 +02:00
struct CachedTagResult : public IServiceLookup
{
2018-07-19 06:58:39 +02:00
const static llarp_time_t TTL = 10000;
llarp_time_t lastRequest = 0;
2018-08-04 04:59:32 +02:00
llarp_time_t lastModified = 0;
2018-07-18 05:10:21 +02:00
std::set< IntroSet > result;
Tag tag;
2018-08-04 04:59:32 +02:00
CachedTagResult(Endpoint* p, const Tag& t, uint64_t tx)
: IServiceLookup(p, tx), tag(t)
2018-07-18 05:10:21 +02:00
{
}
~CachedTagResult();
2018-07-19 00:50:05 +02:00
void
Expire(llarp_time_t now);
2018-07-18 05:10:21 +02:00
bool
ShouldRefresh(llarp_time_t now) const
{
2018-07-19 06:58:39 +02:00
if(now <= lastRequest)
return false;
2018-08-04 04:59:32 +02:00
return (now - lastRequest) > TTL;
2018-07-18 05:10:21 +02:00
}
llarp::routing::IMessage*
BuildRequestMessage();
bool
HandleResponse(const std::set< IntroSet >& results);
};
std::unordered_map< Tag, CachedTagResult, Tag::Hash > m_PrefetchedTags;
2018-07-09 19:32:11 +02:00
};
} // namespace service
} // namespace llarp
#endif