snode stubs (initial)

pull/90/head
Jeff Becker 6 years ago
parent 90a2545bb1
commit 85f9f46362
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05

@ -19,7 +19,7 @@ namespace llarp
struct Endpoint struct Endpoint
{ {
Endpoint(const llarp::PubKey& remoteIdent, Endpoint(const llarp::PubKey& remoteIdent,
const llarp::PathID_t& beginPath, bool rewriteDst, huint32_t ip, const llarp::PathID_t& beginPath, bool rewriteIP, huint32_t ip,
llarp::handlers::ExitEndpoint* parent); llarp::handlers::ExitEndpoint* parent);
~Endpoint(); ~Endpoint();

@ -3,20 +3,24 @@
#include <llarp/pathbuilder.hpp> #include <llarp/pathbuilder.hpp>
#include <llarp/ip.hpp> #include <llarp/ip.hpp>
#include <llarp/messages/transfer_traffic.hpp> #include <llarp/messages/transfer_traffic.hpp>
#include <llarp/messages/exit.hpp>
#include <deque> #include <deque>
namespace llarp namespace llarp
{ {
namespace exit namespace exit
{ {
/// a persisiting exit session with an exit router /// a persisiting exit session with an exit router
struct BaseSession : public llarp::path::Builder struct BaseSession : public llarp::path::Builder
{ {
static constexpr size_t MaxUpstreamQueueLength = 256;
BaseSession(const llarp::RouterID& exitRouter, BaseSession(const llarp::RouterID& exitRouter,
std::function< bool(llarp_buffer_t) > writepkt, std::function< bool(llarp_buffer_t) > writepkt,
llarp_router* r, size_t numpaths, size_t hoplen); llarp_router* r, size_t numpaths, size_t hoplen);
~BaseSession(); virtual ~BaseSession();
bool bool
SelectHop(llarp_nodedb* db, const RouterContact& prev, RouterContact& cur, SelectHop(llarp_nodedb* db, const RouterContact& prev, RouterContact& cur,
@ -34,10 +38,16 @@ namespace llarp
bool bool
FlushUpstreamTraffic(); FlushUpstreamTraffic();
bool
IsReady() const;
protected: protected:
llarp::RouterID m_ExitRouter; llarp::RouterID m_ExitRouter;
std::function< bool(llarp_buffer_t) > m_WritePacket; std::function< bool(llarp_buffer_t) > m_WritePacket;
virtual void
PopulateRequest(llarp::routing::ObtainExitMessage & msg) const = 0;
bool bool
HandleTrafficDrop(llarp::path::Path* p, const llarp::PathID_t& path, HandleTrafficDrop(llarp::path::Path* p, const llarp::PathID_t& path,
@ -55,6 +65,42 @@ namespace llarp
llarp::SecretKey m_ExitIdentity; llarp::SecretKey m_ExitIdentity;
}; };
struct ExitSession final : public BaseSession
{
ExitSession(const llarp::RouterID& snodeRouter,
std::function< bool(llarp_buffer_t) > writepkt,
llarp_router* r, size_t numpaths, size_t hoplen) : BaseSession(snodeRouter, writepkt, r,numpaths, hoplen) {};
~ExitSession() {};
protected:
virtual void
PopulateRequest(llarp::routing::ObtainExitMessage & msg) const override
{
// TODO: set expiration time
msg.X = 0;
msg.E = 1;
}
};
struct SNodeSession final : public BaseSession
{
SNodeSession(const llarp::RouterID& snodeRouter,
std::function< bool(llarp_buffer_t) > writepkt,
llarp_router* r, size_t numpaths, size_t hoplen) : BaseSession(snodeRouter, writepkt, r,numpaths, hoplen) {};
~SNodeSession() {};
protected:
void
PopulateRequest(llarp::routing::ObtainExitMessage & msg) const override
{
// TODO: set expiration time
msg.X = 0;
msg.E = 0;
}
};
} // namespace exit } // namespace exit
} // namespace llarp } // namespace llarp

@ -0,0 +1,31 @@
#ifndef LLARP_HANDLERS_NULL_HPP
#define LLARP_HANDLERS_NULL_HPP
#include <llarp/service/endpoint.hpp>
namespace llarp
{
namespace handlers
{
struct NullEndpoint final : public llarp::service::Endpoint
{
NullEndpoint(const std::string & name, llarp_router *r) : llarp::service::Endpoint(name, r) {};
bool HandleWriteIPPacket(llarp_buffer_t, std::function<huint32_t(void)>) override
{
return true;
}
huint32_t ObtainIPForAddr(const byte_t*, bool) override
{
return {0};
}
bool HasAddress(const byte_t *) const override
{
return false;
}
};
}
}
#endif

@ -49,7 +49,7 @@ namespace llarp
/// overrides Endpoint /// overrides Endpoint
/// handle inbound traffic /// handle inbound traffic
bool bool
ProcessDataMessage(service::ProtocolMessage* msg); HandleWriteIPPacket(llarp_buffer_t buf, std::function<huint32_t(void)> getFromIP) override;
/// queue outbound packet to the world /// queue outbound packet to the world
bool bool
@ -109,14 +109,14 @@ namespace llarp
} }
bool bool
HasAddress(const byte_t* addr) const HasAddress(const byte_t* addr) const override
{ {
return m_AddrToIP.find(addr) != m_AddrToIP.end(); return m_AddrToIP.find(addr) != m_AddrToIP.end();
} }
/// get ip address for key unconditionally /// get ip address for key unconditionally
huint32_t huint32_t
ObtainIPForAddr(const byte_t* addr); ObtainIPForAddr(const byte_t* addr, bool serviceNode) override;
protected: protected:
using PacketQueue_t = llarp::util::CoDelQueue< using PacketQueue_t = llarp::util::CoDelQueue<
@ -150,6 +150,9 @@ namespace llarp
AlignedBuffer< 32 >::Hash > AlignedBuffer< 32 >::Hash >
m_AddrToIP; m_AddrToIP;
/// maps key to true if key is a service node, maps key to false if key is a hidden service
std::unordered_map<AlignedBuffer<32>, bool, AlignedBuffer<32>::Hash> m_SNodes;
private: private:
bool bool
QueueInboundPacketForExit(llarp_buffer_t buf) QueueInboundPacketForExit(llarp_buffer_t buf)

@ -110,18 +110,10 @@ namespace llarp
HasPathToService(const Address& remote) const; HasPathToService(const Address& remote) const;
virtual huint32_t virtual huint32_t
ObtainIPForAddr(const byte_t* addr) ObtainIPForAddr(const byte_t* addr, bool serviceNode) = 0;
{
(void)addr;
return {0};
}
virtual bool virtual bool
HasAddress(const byte_t* addr) const HasAddress(const byte_t* addr) const = 0;
{
(void)addr;
return false;
}
/// return true if we have a pending job to build to a hidden service but /// return true if we have a pending job to build to a hidden service but
/// it's not done yet /// it's not done yet
@ -136,16 +128,11 @@ namespace llarp
bool bool
HandleDataMessage(const PathID_t&, ProtocolMessage* msg); HandleDataMessage(const PathID_t&, ProtocolMessage* msg);
virtual bool virtual
ProcessDataMessage(ProtocolMessage* msg) bool HandleWriteIPPacket(llarp_buffer_t pkt, std::function<huint32_t(void)> getFromIP) = 0;
{
#ifdef TESTNET bool
llarp::LogInfo("Got message from ", msg->sender.Addr()); ProcessDataMessage(ProtocolMessage* msg);
#else
(void)msg;
#endif
return true;
}
bool bool
HandleDataMessage(const PathID_t&); HandleDataMessage(const PathID_t&);
@ -167,7 +154,10 @@ namespace llarp
HandlePathBuilt(path::Path* path); HandlePathBuilt(path::Path* path);
bool bool
SendToOrQueue(const byte_t* addr, llarp_buffer_t payload, ProtocolType t); SendToServiceOrQueue(const byte_t* addr, llarp_buffer_t payload, ProtocolType t);
bool
SendToSNodeOrQueue(const byte_t * addr, llarp_buffer_t payload);
struct PendingBuffer struct PendingBuffer
{ {
@ -339,6 +329,15 @@ namespace llarp
EnsurePathToService(const Address& remote, PathEnsureHook h, EnsurePathToService(const Address& remote, PathEnsureHook h,
uint64_t timeoutMS, bool lookupOnRandomPath = false); uint64_t timeoutMS, bool lookupOnRandomPath = false);
using SNodeEnsureHook = std::function<void(RouterID, llarp::exit::BaseSession *)>;
/// ensure a path to a service node by public key
void
EnsurePathToSNode(const RouterID & remote);
bool
HasPathToSNode(const RouterID &remote) const;
void void
PutSenderFor(const ConvoTag& tag, const ServiceInfo& info); PutSenderFor(const ConvoTag& tag, const ServiceInfo& info);
@ -446,6 +445,10 @@ namespace llarp
Sessions m_DeadSessions; Sessions m_DeadSessions;
using SNodeSessions = std::unordered_multimap<RouterID, std::unique_ptr<llarp::exit::BaseSession>, RouterID::Hash>;
SNodeSessions m_SNodeSessions;
std::unordered_map< Address, ServiceInfo, Address::Hash > std::unordered_map< Address, ServiceInfo, Address::Hash >
m_AddressToService; m_AddressToService;

@ -104,31 +104,31 @@ namespace llarp
if(!pkt.Load(buf)) if(!pkt.Load(buf))
return false; return false;
huint32_t src; huint32_t src;
if(m_RewriteSource) if(m_RewriteSource)
src = m_Parent->GetIfAddr(); src = m_Parent->GetIfAddr();
else else
src = pkt.src(); src = pkt.src();
pkt.UpdateIPv4PacketOnDst(src, m_IP); pkt.UpdateIPv4PacketOnDst(src, m_IP);
if(m_DownstreamQueue.size() == 0) if(m_DownstreamQueue.size() == 0)
m_DownstreamQueue.emplace_back(); m_DownstreamQueue.emplace_back();
auto pktbuf = pkt.Buffer(); auto pktbuf = pkt.Buffer();
auto & msg = m_DownstreamQueue.back(); auto & msg = m_DownstreamQueue.back();
if(msg.Size() + pktbuf.sz > llarp::routing::ExitPadSize) if(msg.Size() + pktbuf.sz > llarp::routing::ExitPadSize)
{ {
m_DownstreamQueue.emplace_back(); m_DownstreamQueue.emplace_back();
return m_DownstreamQueue.back().PutBuffer(pktbuf); return m_DownstreamQueue.back().PutBuffer(pktbuf);
} }
else else
return msg.PutBuffer(pktbuf); return msg.PutBuffer(pktbuf);
} }
bool bool
Endpoint::FlushInboundTraffic() Endpoint::FlushInboundTraffic()
{ {
auto path = GetCurrentPath(); auto path = GetCurrentPath();
bool sent = m_DownstreamQueue.size() == 0; bool sent = m_DownstreamQueue.size() == 0 && path;
if(path) if(path)
{ {
for(auto & msg : m_DownstreamQueue) for(auto & msg : m_DownstreamQueue)

@ -56,10 +56,7 @@ namespace llarp
llarp::routing::ObtainExitMessage obtain; llarp::routing::ObtainExitMessage obtain;
obtain.S = p->NextSeqNo(); obtain.S = p->NextSeqNo();
obtain.T = llarp_randint(); obtain.T = llarp_randint();
// TODO: set expiratation PopulateRequest(obtain);
obtain.X = 0;
// TODO: distinguish between service node traffic
obtain.E = 1;
if(!obtain.Sign(&router->crypto, m_ExitIdentity)) if(!obtain.Sign(&router->crypto, m_ExitIdentity))
{ {
llarp::LogError("Failed to sign exit request"); llarp::LogError("Failed to sign exit request");
@ -103,6 +100,9 @@ namespace llarp
bool bool
BaseSession::QueueUpstreamTraffic(llarp::net::IPv4Packet pkt, const size_t N) BaseSession::QueueUpstreamTraffic(llarp::net::IPv4Packet pkt, const size_t N)
{ {
// queue overflow
if(m_UpstreamQueue.size() >= MaxUpstreamQueueLength)
return false;
if(m_UpstreamQueue.size() == 0) if(m_UpstreamQueue.size() == 0)
m_UpstreamQueue.emplace_back(); m_UpstreamQueue.emplace_back();
auto & back = m_UpstreamQueue.back(); auto & back = m_UpstreamQueue.back();
@ -117,6 +117,12 @@ namespace llarp
return back.PutBuffer(buf); return back.PutBuffer(buf);
} }
bool
BaseSession::IsReady() const
{
return AvailablePaths(llarp::path::ePathRoleExit) > 0;
}
bool bool
BaseSession::FlushUpstreamTraffic() BaseSession::FlushUpstreamTraffic()
{ {

@ -41,7 +41,7 @@ namespace llarp
llarp::LogError(Name(), " bad exit router key: ", v); llarp::LogError(Name(), " bad exit router key: ", v);
return false; return false;
} }
m_Exit.reset(new llarp::exit::BaseSession( m_Exit.reset(new llarp::exit::ExitSession(
exitRouter, exitRouter,
std::bind(&TunEndpoint::QueueInboundPacketForExit, this, std::bind(&TunEndpoint::QueueInboundPacketForExit, this,
std::placeholders::_1), std::placeholders::_1),
@ -344,6 +344,7 @@ namespace llarp
TunEndpoint::FlushSend() TunEndpoint::FlushSend()
{ {
m_UserToNetworkPktQueue.Process([&](net::IPv4Packet &pkt) { m_UserToNetworkPktQueue.Process([&](net::IPv4Packet &pkt) {
std::function<bool(llarp_buffer_t)> sendFunc;
auto itr = m_IPToAddr.find(pkt.dst()); auto itr = m_IPToAddr.find(pkt.dst());
if(itr == m_IPToAddr.end()) if(itr == m_IPToAddr.end())
{ {
@ -351,21 +352,30 @@ namespace llarp
{ {
pkt.UpdateIPv4PacketOnDst({0}, pkt.dst()); pkt.UpdateIPv4PacketOnDst({0}, pkt.dst());
m_Exit->QueueUpstreamTraffic(std::move(pkt), llarp::routing::ExitPadSize); m_Exit->QueueUpstreamTraffic(std::move(pkt), llarp::routing::ExitPadSize);
return true;
} }
else else
{
llarp::LogWarn(Name(), " has no endpoint for ", pkt.dst()); llarp::LogWarn(Name(), " has no endpoint for ", pkt.dst());
return true; return true;
}
} }
if(m_SNodes.at(itr->second))
{
sendFunc = std::bind(&TunEndpoint::SendToSNodeOrQueue, this, itr->second.data(), std::placeholders::_1);
}
else
{
sendFunc = std::bind(&TunEndpoint::SendToServiceOrQueue, this, itr->second.data(), std::placeholders::_1, service::eProtocolTraffic);
}
// prepare packet for insertion into network // prepare packet for insertion into network
// this includes clearing IP addresses, recalculating checksums, etc // this includes clearing IP addresses, recalculating checksums, etc
pkt.UpdateIPv4PacketOnSrc(); pkt.UpdateIPv4PacketOnSrc();
if(!SendToOrQueue(itr->second.data(), pkt.Buffer(), if(sendFunc && sendFunc(pkt.Buffer()))
service::eProtocolTraffic)) return true;
{ llarp::LogWarn(Name(), " did not flush packets");
llarp::LogWarn(Name(), " did not flush packets");
}
return true; return true;
}); });
if(m_Exit) if(m_Exit)
@ -373,14 +383,13 @@ namespace llarp
} }
bool bool
TunEndpoint::ProcessDataMessage(service::ProtocolMessage *msg) TunEndpoint::HandleWriteIPPacket(llarp_buffer_t buf, std::function<huint32_t(void)> getFromIP)
{ {
// llarp::LogInfo("got packet from ", msg->sender.Addr()); // llarp::LogInfo("got packet from ", msg->sender.Addr());
auto themIP = ObtainIPForAddr(msg->sender.Addr().data()); auto themIP = getFromIP();
// llarp::LogInfo("themIP ", themIP); // llarp::LogInfo("themIP ", themIP);
auto usIP = m_OurIP; auto usIP = m_OurIP;
auto buf = llarp::Buffer(msg->payload); return m_NetworkToUserPktQueue.EmplaceIf(
if(m_NetworkToUserPktQueue.EmplaceIf(
[buf, themIP, usIP](net::IPv4Packet &pkt) -> bool { [buf, themIP, usIP](net::IPv4Packet &pkt) -> bool {
// load // load
if(!pkt.Load(buf)) if(!pkt.Load(buf))
@ -402,11 +411,7 @@ namespace llarp
// update packet to use proper addresses, recalc checksums // update packet to use proper addresses, recalc checksums
pkt.UpdateIPv4PacketOnDst(themIP, usIP); pkt.UpdateIPv4PacketOnDst(themIP, usIP);
return true; return true;
})) });
llarp::LogDebug(Name(), " handle data message ", msg->payload.size(),
" bytes from ", themIP);
return true;
} }
huint32_t huint32_t
@ -416,7 +421,7 @@ namespace llarp
} }
huint32_t huint32_t
TunEndpoint::ObtainIPForAddr(const byte_t *a) TunEndpoint::ObtainIPForAddr(const byte_t *a, bool snode)
{ {
llarp_time_t now = Now(); llarp_time_t now = Now();
huint32_t nextIP = {0}; huint32_t nextIP = {0};
@ -443,6 +448,7 @@ namespace llarp
{ {
m_AddrToIP[ident] = nextIP; m_AddrToIP[ident] = nextIP;
m_IPToAddr[nextIP] = ident; m_IPToAddr[nextIP] = ident;
m_SNodes[ident] = snode;
llarp::LogInfo(Name(), " mapped ", ident, " to ", nextIP); llarp::LogInfo(Name(), " mapped ", ident, " to ", nextIP);
MarkIPActive(nextIP); MarkIPActive(nextIP);
return nextIP; return nextIP;
@ -471,6 +477,7 @@ namespace llarp
// remap address // remap address
m_IPToAddr[oldest.first] = ident; m_IPToAddr[oldest.first] = ident;
m_AddrToIP[ident] = oldest.first; m_AddrToIP[ident] = oldest.first;
m_SNodes[ident] = snode;
nextIP = oldest.first; nextIP = oldest.first;
// mark ip active // mark ip active

@ -1,4 +1,5 @@
#include <llarp/handlers/tun.hpp> #include <llarp/handlers/tun.hpp>
#include <llarp/handlers/null.hpp>
#include <llarp/service/context.hpp> #include <llarp/service/context.hpp>
#include <llarp/service/endpoint.hpp> #include <llarp/service/endpoint.hpp>
#include "router.hpp" #include "router.hpp"
@ -107,7 +108,7 @@ namespace llarp
{ {
if(itr->second->HasAddress(addr.data())) if(itr->second->HasAddress(addr.data()))
{ {
ip = itr->second->ObtainIPForAddr(addr.data()); ip = itr->second->ObtainIPForAddr(addr.data(), false);
return true; return true;
} }
++itr; ++itr;
@ -115,7 +116,7 @@ namespace llarp
itr = m_Endpoints.find("default"); itr = m_Endpoints.find("default");
if(itr != m_Endpoints.end()) if(itr != m_Endpoints.end())
{ {
ip = itr->second->ObtainIPForAddr(addr.data()); ip = itr->second->ObtainIPForAddr(addr.data(), false);
return true; return true;
} }
return false; return false;
@ -151,7 +152,7 @@ namespace llarp
llarp::LogError("No tunnel endpoint found"); llarp::LogError("No tunnel endpoint found");
return zero; return zero;
} }
return tunEndpoint->ObtainIPForAddr(addr.data()); return tunEndpoint->ObtainIPForAddr(addr.data(), false);
} }
bool bool
@ -273,7 +274,7 @@ namespace llarp
{"null", {"null",
[](const std::string &nick, [](const std::string &nick,
llarp_router *r) -> llarp::service::Endpoint * { llarp_router *r) -> llarp::service::Endpoint * {
return new llarp::service::Endpoint(nick, r); return new llarp::handlers::NullEndpoint(nick, r);
}}}; }}};
{ {

@ -197,7 +197,7 @@ namespace llarp
continue; continue;
byte_t tmp[1024] = {0}; byte_t tmp[1024] = {0};
auto buf = StackBuffer< decltype(tmp) >(tmp); auto buf = StackBuffer< decltype(tmp) >(tmp);
if(!SendToOrQueue(introset.A.Addr().data(), buf, eProtocolText)) if(!SendToServiceOrQueue(introset.A.Addr().data(), buf, eProtocolText))
{ {
llarp::LogWarn(Name(), " failed to send/queue data to ", llarp::LogWarn(Name(), " failed to send/queue data to ",
introset.A.Addr(), " for tag ", tag.ToString()); introset.A.Addr(), " for tag ", tag.ToString());
@ -783,6 +783,22 @@ namespace llarp
return ProcessDataMessage(msg); return ProcessDataMessage(msg);
} }
bool
Endpoint::ProcessDataMessage(ProtocolMessage *msg)
{
if(msg->proto == eProtocolTraffic)
{
auto buf = llarp::Buffer(msg->payload);
return HandleWriteIPPacket(buf, std::bind(&Endpoint::ObtainIPForAddr, this, msg->sender.Addr().data(), false));
}
else if (msg->proto == eProtocolText)
{
// TODO: implement me (?)
return true;
}
return false;
}
bool bool
Endpoint::HandleHiddenServiceFrame(path::Path* p, Endpoint::HandleHiddenServiceFrame(path::Path* p,
const ProtocolFrame* frame) const ProtocolFrame* frame)
@ -1030,8 +1046,41 @@ namespace llarp
&& GetPathByRouter(remoteIntro.router) != nullptr; && GetPathByRouter(remoteIntro.router) != nullptr;
} }
void
Endpoint::EnsurePathToSNode(const RouterID & snode)
{
auto range = m_SNodeSessions.equal_range(snode);
if(range.first == range.second)
{
auto themIP = ObtainIPForAddr(snode, true);
m_SNodeSessions.emplace(std::make_pair(snode, std::unique_ptr<llarp::exit::BaseSession>(new llarp::exit::SNodeSession(snode, std::bind(&Endpoint::HandleWriteIPPacket, this, std::placeholders::_1, [themIP]() -> huint32_t {return themIP;}), m_Router, 2, numHops))));
}
}
bool
Endpoint::SendToSNodeOrQueue(const byte_t * addr, llarp_buffer_t buf)
{
llarp::net::IPv4Packet pkt;
if(!pkt.Load(buf))
return false;
auto range = m_SNodeSessions.equal_range(addr);
auto itr = range.first;
while(itr != range.second)
{
if(itr->second->IsReady())
{
if(itr->second->QueueUpstreamTraffic(pkt, llarp::routing::ExitPadSize))
{
return true;
}
}
++itr;
}
return false;
}
bool bool
Endpoint::SendToOrQueue(const byte_t* addr, llarp_buffer_t data, Endpoint::SendToServiceOrQueue(const byte_t* addr, llarp_buffer_t data,
ProtocolType t) ProtocolType t)
{ {
service::Address remote(addr); service::Address remote(addr);

Loading…
Cancel
Save