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
{
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);
~Endpoint();

@ -3,20 +3,24 @@
#include <llarp/pathbuilder.hpp>
#include <llarp/ip.hpp>
#include <llarp/messages/transfer_traffic.hpp>
#include <llarp/messages/exit.hpp>
#include <deque>
namespace llarp
{
namespace exit
{
/// a persisiting exit session with an exit router
struct BaseSession : public llarp::path::Builder
{
static constexpr size_t MaxUpstreamQueueLength = 256;
BaseSession(const llarp::RouterID& exitRouter,
std::function< bool(llarp_buffer_t) > writepkt,
llarp_router* r, size_t numpaths, size_t hoplen);
~BaseSession();
virtual ~BaseSession();
bool
SelectHop(llarp_nodedb* db, const RouterContact& prev, RouterContact& cur,
@ -34,10 +38,16 @@ namespace llarp
bool
FlushUpstreamTraffic();
bool
IsReady() const;
protected:
llarp::RouterID m_ExitRouter;
std::function< bool(llarp_buffer_t) > m_WritePacket;
virtual void
PopulateRequest(llarp::routing::ObtainExitMessage & msg) const = 0;
bool
HandleTrafficDrop(llarp::path::Path* p, const llarp::PathID_t& path,
@ -55,6 +65,42 @@ namespace llarp
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 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
/// handle inbound traffic
bool
ProcessDataMessage(service::ProtocolMessage* msg);
HandleWriteIPPacket(llarp_buffer_t buf, std::function<huint32_t(void)> getFromIP) override;
/// queue outbound packet to the world
bool
@ -109,14 +109,14 @@ namespace llarp
}
bool
HasAddress(const byte_t* addr) const
HasAddress(const byte_t* addr) const override
{
return m_AddrToIP.find(addr) != m_AddrToIP.end();
}
/// get ip address for key unconditionally
huint32_t
ObtainIPForAddr(const byte_t* addr);
ObtainIPForAddr(const byte_t* addr, bool serviceNode) override;
protected:
using PacketQueue_t = llarp::util::CoDelQueue<
@ -150,6 +150,9 @@ namespace llarp
AlignedBuffer< 32 >::Hash >
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:
bool
QueueInboundPacketForExit(llarp_buffer_t buf)

@ -110,18 +110,10 @@ namespace llarp
HasPathToService(const Address& remote) const;
virtual huint32_t
ObtainIPForAddr(const byte_t* addr)
{
(void)addr;
return {0};
}
ObtainIPForAddr(const byte_t* addr, bool serviceNode) = 0;
virtual bool
HasAddress(const byte_t* addr) const
{
(void)addr;
return false;
}
HasAddress(const byte_t* addr) const = 0;
/// return true if we have a pending job to build to a hidden service but
/// it's not done yet
@ -136,16 +128,11 @@ namespace llarp
bool
HandleDataMessage(const PathID_t&, ProtocolMessage* msg);
virtual bool
ProcessDataMessage(ProtocolMessage* msg)
{
#ifdef TESTNET
llarp::LogInfo("Got message from ", msg->sender.Addr());
#else
(void)msg;
#endif
return true;
}
virtual
bool HandleWriteIPPacket(llarp_buffer_t pkt, std::function<huint32_t(void)> getFromIP) = 0;
bool
ProcessDataMessage(ProtocolMessage* msg);
bool
HandleDataMessage(const PathID_t&);
@ -167,7 +154,10 @@ namespace llarp
HandlePathBuilt(path::Path* path);
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
{
@ -339,6 +329,15 @@ namespace llarp
EnsurePathToService(const Address& remote, PathEnsureHook h,
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
PutSenderFor(const ConvoTag& tag, const ServiceInfo& info);
@ -446,6 +445,10 @@ namespace llarp
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 >
m_AddressToService;

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

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

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

@ -1,4 +1,5 @@
#include <llarp/handlers/tun.hpp>
#include <llarp/handlers/null.hpp>
#include <llarp/service/context.hpp>
#include <llarp/service/endpoint.hpp>
#include "router.hpp"
@ -107,7 +108,7 @@ namespace llarp
{
if(itr->second->HasAddress(addr.data()))
{
ip = itr->second->ObtainIPForAddr(addr.data());
ip = itr->second->ObtainIPForAddr(addr.data(), false);
return true;
}
++itr;
@ -115,7 +116,7 @@ namespace llarp
itr = m_Endpoints.find("default");
if(itr != m_Endpoints.end())
{
ip = itr->second->ObtainIPForAddr(addr.data());
ip = itr->second->ObtainIPForAddr(addr.data(), false);
return true;
}
return false;
@ -151,7 +152,7 @@ namespace llarp
llarp::LogError("No tunnel endpoint found");
return zero;
}
return tunEndpoint->ObtainIPForAddr(addr.data());
return tunEndpoint->ObtainIPForAddr(addr.data(), false);
}
bool
@ -273,7 +274,7 @@ namespace llarp
{"null",
[](const std::string &nick,
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;
byte_t tmp[1024] = {0};
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 ",
introset.A.Addr(), " for tag ", tag.ToString());
@ -783,6 +783,22 @@ namespace llarp
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
Endpoint::HandleHiddenServiceFrame(path::Path* p,
const ProtocolFrame* frame)
@ -1030,8 +1046,41 @@ namespace llarp
&& 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
Endpoint::SendToOrQueue(const byte_t* addr, llarp_buffer_t data,
Endpoint::SendToServiceOrQueue(const byte_t* addr, llarp_buffer_t data,
ProtocolType t)
{
service::Address remote(addr);

Loading…
Cancel
Save