lokinet/llarp/service/endpoint.hpp

466 lines
12 KiB
C++
Raw Normal View History

2018-07-09 17:32:11 +00:00
#ifndef LLARP_SERVICE_ENDPOINT_HPP
#define LLARP_SERVICE_ENDPOINT_HPP
#include <llarp.h>
#include <dht/messages/gotrouter.hpp>
2019-01-11 01:19:36 +00:00
#include <ev/ev.h>
2018-12-12 01:06:46 +00:00
#include <exit/session.hpp>
#include <net/ip_range_map.hpp>
#include <net/net.hpp>
2019-01-11 01:19:36 +00:00
#include <path/path.hpp>
#include <path/pathbuilder.hpp>
#include <service/address.hpp>
2018-12-12 02:15:08 +00:00
#include <service/handler.hpp>
#include <service/identity.hpp>
2019-04-19 16:02:32 +00:00
#include <service/pendingbuffer.hpp>
2018-12-12 02:15:08 +00:00
#include <service/protocol.hpp>
#include <service/sendcontext.hpp>
#include <service/session.hpp>
#include <service/tag_lookup_job.hpp>
#include <hook/ihook.hpp>
#include <util/compare_ptr.hpp>
2019-09-01 13:26:16 +00:00
#include <util/thread/logic.hpp>
2018-07-09 17:32:11 +00:00
2019-03-29 01:02:41 +00:00
// minimum time between introset shifts
2018-09-18 17:48:26 +00:00
#ifndef MIN_SHIFT_INTERVAL
#define MIN_SHIFT_INTERVAL (5 * 1000)
#endif
struct llarp_async_verify_rc;
2018-07-09 17:32:11 +00:00
namespace llarp
{
namespace service
{
struct AsyncKeyExchange;
struct Context;
struct EndpointState;
struct OutboundContext;
struct IConvoEventListener
{
~IConvoEventListener() = default;
/// called when we have obtained the introset
/// called with nullptr on not found or when we
/// talking to a snode
virtual void
FoundIntroSet(const IntroSet*) = 0;
/// called when we found the RC we need for alignment
virtual void
FoundRC(const RouterContact) = 0;
/// called when we have successfully built an aligned path
virtual void GotAlignedPath(path::Path_ptr) = 0;
/// called when we have established a session or conversation
virtual void
MadeConvo(const ConvoTag) = 0;
};
using ConvoEventListener_ptr = std::shared_ptr< IConvoEventListener >;
2018-08-30 18:48:43 +00:00
struct Endpoint : public path::Builder,
2018-08-09 19:02:17 +00:00
public ILookupHolder,
public IDataHandler
2018-07-09 17:32:11 +00:00
{
2018-07-18 03:10:21 +00:00
/// minimum interval for publishing introsets
static const llarp_time_t INTROSET_PUBLISH_INTERVAL =
2019-04-05 14:58:22 +00:00
path::default_lifetime / 8;
2018-07-18 03:10:21 +00:00
static const llarp_time_t INTROSET_PUBLISH_RETRY_INTERVAL = 5000;
static const size_t MAX_OUTBOUND_CONTEXT_COUNT = 4;
Endpoint(const std::string& nickname, AbstractRouter* r, Context* parent);
2019-07-30 23:42:13 +00:00
~Endpoint() override;
2018-07-09 17:32:11 +00:00
/// return true if we are ready to recv packets from the void
bool
IsReady() const;
2019-11-28 23:08:02 +00:00
void
QueueRecvData(RecvDataEvent ev) override;
/// return true if our introset has expired intros
bool
IntrosetIsStale() const;
/// construct parameters for notify hooks
2019-04-22 14:00:59 +00:00
virtual std::unordered_map< std::string, std::string >
NotifyParams() const;
2019-04-19 15:10:26 +00:00
util::StatusObject
ExtractStatus() const;
2019-02-08 19:43:25 +00:00
void
SetHandler(IDataHandler* h);
2018-08-16 14:34:15 +00:00
virtual bool
2018-07-09 17:32:11 +00:00
SetOption(const std::string& k, const std::string& v);
2019-07-30 23:42:13 +00:00
void
2019-04-23 16:13:22 +00:00
Tick(llarp_time_t now) override;
/// return true if we have a resolvable ip address
virtual bool
HasIfAddr() const
{
return false;
}
/// inject vpn io
/// return false if not supported
virtual bool
InjectVPN(llarp_vpn_io*, llarp_vpn_ifaddr_info)
{
return false;
}
/// get our ifaddr if it is set
2019-06-11 16:44:05 +00:00
virtual huint128_t
GetIfAddr() const
{
2019-07-01 13:44:25 +00:00
return {0};
}
2019-07-30 23:42:13 +00:00
void
2019-05-07 17:46:38 +00:00
ResetInternalState() override;
2018-08-09 19:02:17 +00:00
/// router's logic
/// use when sending any data on a path
2019-05-22 16:20:50 +00:00
std::shared_ptr< Logic >
2018-08-09 19:02:17 +00:00
RouterLogic();
/// endpoint's logic
/// use when writing any data to local network interfaces
2019-05-22 16:20:50 +00:00
std::shared_ptr< Logic >
2018-08-09 19:02:17 +00:00
EndpointLogic();
2018-07-19 04:58:39 +00:00
2019-04-23 16:13:22 +00:00
/// borrow endpoint's net loop for sending data to user on local network
/// interface
2019-04-08 12:01:52 +00:00
llarp_ev_loop_ptr
EndpointNetLoop();
/// crypto worker threadpool
2019-07-09 13:47:24 +00:00
std::shared_ptr< llarp::thread::ThreadPool >
CryptoWorker();
2018-07-19 04:58:39 +00:00
AbstractRouter*
Router();
2018-07-22 23:14:29 +00:00
virtual bool
LoadKeyFile();
2018-08-16 14:34:15 +00:00
virtual bool
2018-07-09 17:32:11 +00:00
Start();
2019-07-30 23:42:13 +00:00
std::string
2019-03-25 01:54:37 +00:00
Name() const override;
2018-07-16 03:32:13 +00:00
/// get a set of all the routers we use as exit node
std::set< RouterID >
GetExitRouters() const;
2018-07-18 03:10:21 +00:00
bool
2018-12-24 21:10:35 +00:00
ShouldPublishDescriptors(llarp_time_t now) const override;
2018-07-18 03:10:21 +00:00
2019-03-30 13:02:10 +00:00
void
HandlePathDied(path::Path_ptr p) override;
2019-03-30 13:02:10 +00:00
2018-07-18 03:10:21 +00:00
bool
PublishIntroSet(AbstractRouter* r) override;
2018-07-18 03:10:21 +00:00
2018-09-18 14:48:06 +00:00
bool
PublishIntroSetVia(AbstractRouter* r, path::Path_ptr p);
2018-09-18 14:48:06 +00:00
bool
2019-05-03 13:15:03 +00:00
HandleGotIntroMessage(
std::shared_ptr< const dht::GotIntroMessage > msg) override;
2018-08-10 21:34:11 +00:00
bool
2019-05-03 13:15:03 +00:00
HandleGotRouterMessage(
std::shared_ptr< const dht::GotRouterMessage > msg) override;
2018-08-10 21:34:11 +00:00
2018-07-12 18:21:44 +00:00
bool
HandleHiddenServiceFrame(path::Path_ptr p,
const service::ProtocolFrame& msg);
2018-07-12 18:21:44 +00:00
2019-07-01 13:44:25 +00:00
// virtual huint128_t
// ObtainIPForAddr(const AlignedBuffer< 32 >& addr, bool serviceNode) = 0;
2018-10-23 18:06:55 +00:00
2019-07-01 13:44:25 +00:00
// virtual bool
// HasServiceAddress(const AlignedBuffer< 32 >& addr) const = 0;
2018-08-10 03:51:38 +00: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 18:21:44 +00: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-09-18 17:48:26 +00:00
bool
2019-06-28 14:12:20 +00:00
HandleDataMessage(path::Path_ptr path, const PathID_t from,
2019-05-03 13:15:03 +00:00
std::shared_ptr< ProtocolMessage > msg) override;
2018-08-09 19:02:17 +00:00
/// handle packet io from service node or hidden service to frontend
virtual bool
HandleInboundPacket(const ConvoTag tag, const llarp_buffer_t& pkt,
ProtocolType t) = 0;
2019-07-01 13:44:25 +00:00
// virtual bool
// HandleWriteIPPacket(const llarp_buffer_t& pkt,
// std::function< huint128_t(void) > getFromIP) = 0;
2018-11-29 13:12:35 +00:00
bool
2019-05-03 13:15:03 +00:00
ProcessDataMessage(std::shared_ptr< ProtocolMessage > msg);
2018-09-18 17:48:26 +00:00
2018-08-10 21:34:11 +00:00
/// ensure that we know a router, looks up if it doesn't
void
EnsureRouterIsKnown(const RouterID& router);
/// lookup a router via closest path
bool
2019-05-03 13:15:03 +00:00
LookupRouterAnon(RouterID router, RouterLookupHandler handler);
2019-04-25 17:15:56 +00:00
/// called on event loop pump
virtual void
Pump(llarp_time_t now);
/// stop this endpoint
bool
Stop() override;
const Identity&
2018-11-21 14:30:14 +00:00
GetIdentity() const
2018-07-22 23:14:29 +00:00
{
return m_Identity;
2018-07-22 23:14:29 +00:00
}
2018-07-19 04:58:39 +00:00
2018-08-04 02:59:32 +00:00
void
2018-12-24 21:10:35 +00:00
PutLookup(IServiceLookup* lookup, uint64_t txid) override;
2018-08-04 02:59:32 +00:00
void
HandlePathBuilt(path::Path_ptr path) override;
2018-08-22 15:52:10 +00:00
bool
EnsureConvo(const AlignedBuffer< 32 > addr, bool snode,
ConvoEventListener_ptr ev);
2018-11-29 13:12:35 +00:00
bool
SendTo(const ConvoTag tag, const llarp_buffer_t& pkt, ProtocolType t);
;
2018-08-22 15:52:10 +00:00
bool
HandleDataDrop(path::Path_ptr p, const PathID_t& dst, uint64_t s);
bool
CheckPathIsDead(path::Path_ptr p, llarp_time_t latency);
2019-04-30 16:49:34 +00:00
using PendingBufferQueue = std::deque< PendingBuffer >;
2018-08-22 15:52:10 +00:00
bool
ShouldBundleRC() const override;
/// return true if we have a convotag as an exit session
/// or as a hidden service session
/// set addr and issnode
///
/// return false if we don't have either
bool
GetEndpointWithConvoTag(const ConvoTag t, AlignedBuffer< 32 >& addr,
bool& issnode) const;
2019-03-08 17:00:13 +00:00
bool
HasConvoTag(const ConvoTag& t) const override;
2019-03-08 14:36:24 +00:00
bool
ShouldBuildMore(llarp_time_t now) const override;
2018-07-12 18:21:44 +00:00
// passed a sendto context when we have a path established otherwise
// nullptr if the path was not made before the timeout
using PathEnsureHook = std::function< void(Address, OutboundContext*) >;
2018-07-12 18:21:44 +00:00
/// return false if we have already called this function before for this
/// address
bool
2019-07-01 13:44:25 +00:00
EnsurePathToService(const Address remote, PathEnsureHook h,
2018-10-23 18:06:55 +00:00
uint64_t timeoutMS, bool lookupOnRandomPath = false);
2018-07-12 18:21:44 +00:00
using SNodeEnsureHook =
2019-07-01 13:44:25 +00:00
std::function< void(const RouterID, exit::BaseSession_ptr) >;
2018-11-29 13:12:35 +00:00
/// ensure a path to a service node by public key
void
2019-07-01 13:44:25 +00:00
EnsurePathToSNode(const RouterID remote, SNodeEnsureHook h);
2018-11-29 13:12:35 +00:00
/// return true if this endpoint is trying to lookup this router right now
bool
HasPendingRouterLookup(const RouterID remote) const;
2018-11-29 13:12:35 +00:00
bool
2019-07-01 13:44:25 +00:00
HasPathToSNode(const RouterID remote) const;
2018-11-29 13:12:35 +00:00
2018-08-09 19:02:17 +00:00
void
PutSenderFor(const ConvoTag& tag, const ServiceInfo& info,
bool inbound) override;
bool
HasInboundConvo(const Address& addr) const override;
2018-08-09 19:02:17 +00:00
bool
GetCachedSessionKeyFor(const ConvoTag& remote,
SharedSecret& secret) const override;
2018-08-09 19:02:17 +00:00
void
PutCachedSessionKeyFor(const ConvoTag& remote,
2018-12-24 21:10:35 +00:00
const SharedSecret& secret) override;
2018-08-09 19:02:17 +00:00
bool
2018-12-24 21:10:35 +00:00
GetSenderFor(const ConvoTag& remote, ServiceInfo& si) const override;
2018-08-09 19:02:17 +00:00
void
2018-12-24 21:10:35 +00:00
PutIntroFor(const ConvoTag& remote, const Introduction& intro) override;
2018-08-09 19:02:17 +00:00
bool
2018-12-24 21:10:35 +00:00
GetIntroFor(const ConvoTag& remote, Introduction& intro) const override;
2018-08-09 19:02:17 +00:00
2019-03-08 16:00:45 +00:00
void
RemoveConvoTag(const ConvoTag& remote) override;
2019-09-19 20:28:12 +00:00
void
MarkConvoTagActive(const ConvoTag& remote) override;
2019-02-21 16:45:33 +00:00
void
PutReplyIntroFor(const ConvoTag& remote,
const Introduction& intro) override;
bool
GetReplyIntroFor(const ConvoTag& remote,
Introduction& intro) const override;
2018-08-09 19:02:17 +00:00
bool
GetConvoTagsForService(const Address& si,
2018-12-24 21:10:35 +00:00
std::set< ConvoTag >& tag) const override;
2018-08-09 19:02:17 +00:00
void
PutNewOutboundContext(const IntroSet& introset);
2019-04-19 16:02:32 +00:00
uint64_t
GetSeqNoForConvo(const ConvoTag& tag);
2019-07-30 23:42:13 +00:00
bool
2019-05-10 16:19:33 +00:00
SelectHop(llarp_nodedb* db, const std::set< RouterID >& prev,
RouterContact& cur, size_t hop, path::PathRole roles) override;
2018-07-18 03:10:21 +00:00
virtual void
IntroSetPublishFail();
virtual void
IntroSetPublished();
uint64_t
GenTXID();
const std::set< RouterID >&
SnodeBlacklist() const;
2018-09-18 14:48:06 +00:00
protected:
bool
SendToServiceOrQueue(const service::Address& addr,
const llarp_buffer_t& payload, ProtocolType t);
bool
SendToSNodeOrQueue(const RouterID& addr, const llarp_buffer_t& payload);
/// parent context that owns this endpoint
Context* const context;
2019-06-11 16:44:05 +00:00
virtual bool
SupportsV6() const = 0;
void
2019-11-05 16:58:53 +00:00
RegenAndPublishIntroSet(bool forceRebuild = false);
2018-07-18 03:10:21 +00:00
IServiceLookup*
GenerateLookupByTag(const Tag& tag);
void
PrefetchServicesByTag(const Tag& tag);
/// spawn a new process that contains a network isolated process
/// return true if we set up isolation and the event loop is up
2019-05-22 16:20:50 +00:00
/// otherwise return false
virtual bool
SpawnIsolatedNetwork()
{
return false;
}
2018-08-09 19:02:17 +00:00
2018-08-16 14:34:15 +00:00
bool
NetworkIsIsolated() const;
/// this runs in the isolated network process
void
IsolatedNetworkMainLoop();
2018-07-18 03:10:21 +00:00
private:
void
HandleVerifyGotRouter(dht::GotRouterMessage_constptr msg,
llarp_async_verify_rc* j);
2018-08-10 21:34:11 +00:00
bool
2018-10-15 15:43:41 +00:00
OnLookup(const service::Address& addr, const IntroSet* i,
const RouterID& endpoint); /* */
2018-08-10 21:34:11 +00:00
2018-08-09 19:02:17 +00:00
bool
2018-08-18 14:01:21 +00:00
DoNetworkIsolation(bool failed);
2018-08-09 19:02:17 +00:00
2018-08-16 14:34:15 +00:00
virtual bool
SetupNetworking()
{
// XXX: override me
return true;
}
2018-08-18 14:01:21 +00:00
virtual bool
IsolationFailed()
{
// XXX: override me
return false;
}
protected:
IDataHandler* m_DataHandler = nullptr;
2018-08-09 19:02:17 +00:00
Identity m_Identity;
net::IPRangeMap< exit::BaseSession_ptr > m_ExitMap;
hooks::Backend_ptr m_OnUp;
hooks::Backend_ptr m_OnDown;
hooks::Backend_ptr m_OnReady;
2018-07-09 17:32:11 +00:00
private:
2019-11-28 23:08:02 +00:00
void
FlushRecvData();
friend struct EndpointUtil;
// clang-format off
const IntroSet& introSet() const;
IntroSet& introSet();
2019-05-07 08:29:47 +00:00
using ConvoMap = std::unordered_map< ConvoTag, Session, ConvoTag::Hash >;
const ConvoMap& Sessions() const;
ConvoMap& Sessions();
// clang-format on
2019-05-07 08:29:47 +00:00
std::unique_ptr< EndpointState > m_state;
2019-11-28 23:08:02 +00:00
thread::Queue< RecvDataEvent > m_RecvQueue;
2018-07-09 17:32:11 +00:00
};
2019-04-23 16:13:22 +00:00
using Endpoint_ptr = std::shared_ptr< Endpoint >;
2018-07-09 17:32:11 +00:00
} // namespace service
} // namespace llarp
2018-08-16 14:34:15 +00:00
#endif