initial mempipe implementation

pull/783/head
Jeff Becker 5 years ago
parent d6f2a1954f
commit c1f33bb1ac
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05

@ -147,7 +147,7 @@ extern "C"
int flags; /* ifr.ifr_flags on Unix */
char if_name[IF_NAMESIZE];
#if defined(Windows)
int idx; /* needed to set ipv6 address */
int idx; /* needed to set ipv6 address */
#endif
#if defined(FreeBSD)
int mode;

@ -178,10 +178,12 @@ set(LIB_SRC
iwp/linklayer.cpp
iwp/outermessage.cpp
iwp/iwp.cpp
link/factory.cpp
link/i_link_manager.cpp
link/link_manager.cpp
link/server.cpp
link/session.cpp
mempipe/mempipe.cpp
messages/dht_immediate.cpp
messages/discard.cpp
messages/link_intro.cpp

@ -33,6 +33,11 @@ namespace llarp
void
RouterConfig::fromSection(string_view key, string_view val)
{
if(key == "default-protocol")
{
m_DefaultLinkProto = tostr(val);
LogInfo("overriding default link protocol to '", val, "'");
}
if(key == "netid")
{
if(val.size() <= NetID::size())
@ -194,9 +199,8 @@ namespace llarp
}
void
IwpConfig::fromSection(string_view key, string_view val)
LinksConfig::fromSection(string_view key, string_view val)
{
// try IPv4 first
uint16_t proto = 0;
std::set< std::string > parsed_opts;
@ -215,7 +219,7 @@ namespace llarp
parsed_opts.insert(v);
}
} while(idx != std::string::npos);
std::set< std::string > opts;
/// for each option
for(const auto &item : parsed_opts)
{
@ -229,15 +233,20 @@ namespace llarp
proto = port;
}
}
else
{
opts.insert(item);
}
}
if(key == "*")
{
m_OutboundPort = proto;
m_OutboundLink = {"*", AF_INET, fromEnv(proto, "OUTBOUND_PORT"),
std::move(opts)};
}
else
{
m_servers.emplace_back(tostr(key), AF_INET, proto);
m_InboundLinks.emplace_back(tostr(key), AF_INET, proto, std::move(opts));
}
}
@ -434,7 +443,7 @@ namespace llarp
connect = find_section< ConnectConfig >(parser, "connect");
netdb = find_section< NetdbConfig >(parser, "netdb");
dns = find_section< DnsConfig >(parser, "dns");
iwp_links = find_section< IwpConfig >(parser, "bind");
links = find_section< LinksConfig >(parser, "bind");
services = find_section< ServicesConfig >(parser, "services");
system = find_section< SystemConfig >(parser, "system");
metrics = find_section< MetricsConfig >(parser, "metrics");

@ -128,6 +128,8 @@ namespace llarp
int m_workerThreads = 1;
int m_numNetThreads = 1;
std::string m_DefaultLinkProto = "utp";
public:
// clang-format off
size_t minConnectedRouters() const { return fromEnv(m_minConnectedRouters, "MIN_CONNECTED_ROUTERS"); }
@ -143,6 +145,7 @@ namespace llarp
const AddressInfo& addrInfo() const { return m_addrInfo; }
int workerThreads() const { return fromEnv(m_workerThreads, "WORKER_THREADS"); }
int numNetThreads() const { return fromEnv(m_numNetThreads, "NUM_NET_THREADS"); }
std::string defaultLinkProto() const { return fromEnv(m_DefaultLinkProto, "LINK_PROTO"); }
// clang-format on
void
@ -194,20 +197,27 @@ namespace llarp
fromSection(string_view key, string_view val);
};
class IwpConfig
class LinksConfig
{
public:
using Servers = std::vector< std::tuple< std::string, int, uint16_t > >;
static constexpr int Interface = 0;
static constexpr int AddressFamily = 1;
static constexpr int Port = 2;
static constexpr int Options = 3;
private:
uint16_t m_OutboundPort = 0;
using ServerOptions = std::set< std::string >;
using LinkInfo = std::tuple< std::string, int, uint16_t, ServerOptions >;
using Links = std::vector< LinkInfo >;
Servers m_servers;
private:
LinkInfo m_OutboundLink;
Links m_InboundLinks;
public:
// clang-format off
uint16_t outboundPort() const { return fromEnv(m_OutboundPort, "OUTBOUND_PORT"); }
const Servers& servers() const { return m_servers; }
const LinkInfo& outboundLink() const { return m_OutboundLink; }
const Links& inboundLinks() const { return m_InboundLinks; }
// clang-format on
void
@ -306,7 +316,7 @@ namespace llarp
ConnectConfig connect;
NetdbConfig netdb;
DnsConfig dns;
IwpConfig iwp_links;
LinksConfig links;
ServicesConfig services;
SystemConfig system;
MetricsConfig metrics;

@ -633,16 +633,17 @@ namespace libuv
Loop::CloseAll()
{
llarp::LogInfo("Closing all handles");
uv_walk(m_Impl.get(),
[](uv_handle_t* h, void*) {
if(uv_is_closing(h))
return;
if(h->data && uv_is_active(h))
{
static_cast< glue* >(h->data)->Close();
}
},
nullptr);
uv_walk(
m_Impl.get(),
[](uv_handle_t* h, void*) {
if(uv_is_closing(h))
return;
if(h->data && uv_is_active(h))
{
static_cast< glue* >(h->data)->Close();
}
},
nullptr);
}
void

@ -0,0 +1,52 @@
#include <link/factory.hpp>
#include <utp/utp.hpp>
#include <mempipe/mempipe.hpp>
namespace llarp
{
LinkFactory::LinkType
LinkFactory::TypeFromName(string_view str)
{
if(str == "utp")
return LinkType::eLinkUTP;
if(str == "iwp")
return LinkType::eLinkIWP;
if(str == "mempipe")
return LinkType::eLinkMempipe;
return LinkType::eLinkUnknown;
}
std::string
LinkFactory::NameFromType(LinkFactory::LinkType tp)
{
switch(tp)
{
case LinkType::eLinkUTP:
return "utp";
case LinkType::eLinkIWP:
return "iwp";
case LinkType::eLinkMempipe:
return "mempipe";
default:
return "unspec";
}
}
LinkFactory::Factory
LinkFactory::Obtain(LinkFactory::LinkType tp, bool permitInbound)
{
switch(tp)
{
case LinkType::eLinkUTP:
if(permitInbound)
return llarp::utp::NewInboundLink;
return llarp::utp::NewOutboundLink;
case LinkType::eLinkMempipe:
if(permitInbound)
return llarp::mempipe::NewInboundLink;
return llarp::mempipe::NewOutboundLink;
default:
return nullptr;
}
}
} // namespace llarp

@ -0,0 +1,43 @@
#ifndef LLARP_LINK_FACTORY_HPP
#define LLARP_LINK_FACTORY_HPP
#include <util/string_view.hpp>
#include <functional>
#include <link/server.hpp>
namespace llarp
{
/// LinkFactory is responsible for returning std::functions that create the
/// link layer types
struct LinkFactory
{
enum class LinkType
{
eLinkUTP,
eLinkIWP,
eLinkMempipe,
eLinkUnknown
};
using Factory = std::function< LinkLayer_ptr(
const SecretKey&, GetRCFunc, LinkMessageHandler, SignBufferFunc,
SessionEstablishedHandler, SessionRenegotiateHandler, TimeoutHandler,
SessionClosedHandler) >;
/// get link type by name string
/// if invalid returns eLinkUnspec
static LinkType
TypeFromName(string_view name);
/// turns a link type into a string representation
static std::string
NameFromType(LinkType t);
/// obtain a link factory of a certain type
static Factory
Obtain(LinkType t, bool permitInbound);
};
} // namespace llarp
#endif

@ -103,7 +103,7 @@ namespace llarp
llarp_ev_udp_sendto(&m_udp, to, pkt);
}
bool
virtual bool
Configure(llarp_ev_loop_ptr loop, const std::string& ifname, int af,
uint16_t port);
@ -125,7 +125,7 @@ namespace llarp
virtual bool
Start(std::shared_ptr< llarp::Logic > l);
void
virtual void
Stop();
virtual const char*
@ -140,11 +140,11 @@ namespace llarp
void
KeepAliveSessionTo(const RouterID& remote);
bool
virtual bool
SendTo(const RouterID& remote, const llarp_buffer_t& buf,
ILinkSession::CompletionHandler completed);
bool
virtual bool
GetOurAddressInfo(AddressInfo& addr) const;
bool
@ -200,6 +200,12 @@ namespace llarp
SessionClosedHandler SessionClosed;
SessionRenegotiateHandler SessionRenegotiate;
std::shared_ptr< Logic >
logic()
{
return m_Logic;
}
bool
operator<(const ILinkLayer& other) const
{

@ -0,0 +1,534 @@
#include <mempipe/mempipe.hpp>
#include <messages/discard.hpp>
#include <util/logic.hpp>
#include <util/time.hpp>
namespace llarp
{
namespace mempipe
{
struct MemLink;
struct MemSession;
struct MempipeContext
{
using Nodes_t =
std::unordered_map< RouterID, LinkLayer_ptr, RouterID::Hash >;
Nodes_t _nodes;
using SendEvent = std::tuple< RouterID, RouterID, std::vector< byte_t >,
ILinkSession::CompletionHandler >;
std::deque< SendEvent > _sendQueue;
/// (src, dst, session, hook)
using NodeConnection_t = std::tuple< RouterID, RouterID >;
struct NodeConnectionHash
{
size_t
operator()(const NodeConnection_t con) const
{
const auto& a = std::get< 0 >(con);
const auto& b = std::get< 1 >(con);
auto op = std::bit_xor< size_t >();
return std::accumulate(a.begin(), a.end(),
std::accumulate(b.begin(), b.end(), 0, op),
op);
}
};
using NodeConnections_t =
std::unordered_map< NodeConnection_t, std::shared_ptr< MemSession >,
NodeConnectionHash >;
NodeConnections_t _connections;
mutable util::Mutex _access;
void
AddNode(LinkLayer_ptr ptr) LOCKS_EXCLUDED(_access);
void
RemoveNode(LinkLayer_ptr ptr) LOCKS_EXCLUDED(_access);
LinkLayer_ptr
FindNode(const RouterID pk) LOCKS_EXCLUDED(_access);
/// connect src to dst
void
ConnectNode(const RouterID src, const RouterID dst,
const std::shared_ptr< MemSession >& ptr)
LOCKS_EXCLUDED(_access);
/// remote both src and dst as connected
void
DisconnectNode(const RouterID src, const RouterID dst)
LOCKS_EXCLUDED(_access);
bool
HasConnection(const RouterID src, const RouterID dst) const
LOCKS_EXCLUDED(_access);
void
InboundConnection(const RouterID to,
const std::shared_ptr< MemSession >& obsession);
void
CallLater(std::function< void(void) > f)
{
m_Logic->call_later(10, f);
}
bool
SendTo(const RouterID src, const RouterID dst,
const std::vector< byte_t > msg,
ILinkSession::CompletionHandler delivery) LOCKS_EXCLUDED(_access);
void
Pump() LOCKS_EXCLUDED(_access);
void
Start()
{
m_Run.store(true);
m_Thread = new std::thread{[&]() {
m_Logic = std::make_shared< Logic >();
while(m_Run.load())
{
Pump();
m_Logic->tick(time_now_ms());
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
m_Logic = nullptr;
}};
}
~MempipeContext()
{
m_Run.store(false);
if(m_Thread)
{
m_Thread->join();
delete m_Thread;
}
}
std::atomic< bool > m_Run;
std::shared_ptr< Logic > m_Logic = nullptr;
std::thread* m_Thread = nullptr;
};
using Globals_ptr = std::unique_ptr< MempipeContext >;
Globals_ptr _globals;
struct MemSession : public ILinkSession,
public std::enable_shared_from_this< MemSession >
{
MemSession(LinkLayer_ptr _local, LinkLayer_ptr _remote)
: remote(std::move(_remote)), parent(std::move(_local))
{
}
LinkLayer_ptr remote;
LinkLayer_ptr parent;
util::Mutex _access;
std::deque< std::vector< byte_t > > m_recvQueue;
std::deque< std::tuple< std::vector< byte_t >, CompletionHandler > >
m_sendQueue;
llarp_time_t lastRecv = 0;
PubKey
GetPubKey() const override
{
return remote->GetOurRC().pubkey;
}
bool
SendKeepAlive() override
{
std::array< byte_t, 128 > pkt;
DiscardMessage msg;
llarp_buffer_t buf{pkt};
if(!msg.BEncode(&buf))
return false;
buf.sz = buf.cur - buf.base;
buf.cur = buf.base;
return SendMessageBuffer(buf, nullptr);
}
void
Recv(const std::vector< byte_t > msg) LOCKS_EXCLUDED(_access)
{
util::Lock lock(&_access);
m_recvQueue.emplace_back(std::move(msg));
lastRecv = parent->Now();
}
void
OnLinkEstablished(ILinkLayer*) override
{
return;
}
bool
TimedOut(llarp_time_t now) const override
{
return now >= lastRecv && now - lastRecv > 5000;
}
void
PumpWrite() LOCKS_EXCLUDED(_access)
{
std::deque< std::tuple< std::vector< byte_t >, CompletionHandler > > q;
{
util::Lock lock(&_access);
if(m_sendQueue.size())
q = std::move(m_sendQueue);
}
const RouterID src = parent->GetOurRC().pubkey;
const RouterID dst = GetPubKey();
while(q.size())
{
const auto& f = q.front();
_globals->SendTo(src, dst, std::get< 0 >(f), std::get< 1 >(f));
q.pop_front();
}
}
void
PumpRead() LOCKS_EXCLUDED(_access)
{
std::deque< std::vector< byte_t > > q;
{
util::Lock lock(&_access);
if(m_recvQueue.size())
q = std::move(m_recvQueue);
}
while(q.size())
{
const llarp_buffer_t buf{q.front()};
parent->HandleMessage(this, buf);
q.pop_front();
}
}
void Tick(llarp_time_t) override
{
}
void
Pump() override
{
PumpRead();
PumpWrite();
}
void
Close() override
{
auto self = shared_from_this();
_globals->CallLater([=]() { self->Disconnected(); });
}
RouterContact
GetRemoteRC() const override
{
return remote->GetOurRC();
}
bool
ShouldPing() const override
{
return true;
}
bool
SendMessageBuffer(const llarp_buffer_t& pkt,
ILinkSession::CompletionHandler completed) override
{
if(completed == nullptr)
completed = [](ILinkSession::DeliveryStatus) {};
auto self = shared_from_this();
std::vector< byte_t > buf(pkt.sz);
std::copy_n(pkt.base, pkt.sz, buf.begin());
return _globals->SendTo(parent->GetOurRC().pubkey, GetRemoteRC().pubkey,
buf, [=](ILinkSession::DeliveryStatus status) {
self->parent->logic()->call_later(
10, std::bind(completed, status));
});
}
void
Start() override
{
auto self = shared_from_this();
_globals->CallLater(
[=]() { _globals->InboundConnection(self->GetPubKey(), self); });
}
bool
IsEstablished() const override
{
return _globals->HasConnection(parent->GetOurRC().pubkey, GetPubKey());
}
void
Disconnected()
{
_globals->DisconnectNode(parent->GetOurRC().pubkey, GetPubKey());
}
bool
RenegotiateSession() override
{
return true;
}
ILinkLayer*
GetLinkLayer() const override
{
return parent.get();
}
util::StatusObject
ExtractStatus() const override
{
return {};
}
llarp::Addr
GetRemoteEndpoint() const override
{
return {};
}
size_t
SendQueueBacklog() const override
{
return m_sendQueue.size();
}
};
struct MemLink : public ILinkLayer,
public std::enable_shared_from_this< MemLink >
{
MemLink(const SecretKey& routerEncSecret, GetRCFunc getrc,
LinkMessageHandler h, SignBufferFunc sign,
SessionEstablishedHandler est, SessionRenegotiateHandler reneg,
TimeoutHandler timeout, SessionClosedHandler closed,
bool permitInbound)
: ILinkLayer(routerEncSecret, getrc, h, sign, est, reneg, timeout,
closed)
, allowInbound(permitInbound)
{
}
const bool allowInbound;
bool
KeyGen(SecretKey& k) override
{
k.Zero();
return true;
}
const char*
Name() const override
{
return "mempipe";
}
uint16_t
Rank() const override
{
return 100;
}
void
RecvFrom(const llarp::Addr&, const void*, size_t) override
{
}
bool
Configure(llarp_ev_loop_ptr, const std::string&, int, uint16_t) override
{
if(_globals == nullptr)
_globals = std::make_unique< MempipeContext >();
return _globals != nullptr;
}
std::shared_ptr< ILinkSession >
NewOutboundSession(const RouterContact& rc,
const AddressInfo& ai) override
{
if(ai.dialect != Name())
return nullptr;
auto remote = _globals->FindNode(rc.pubkey);
if(remote == nullptr)
return nullptr;
return std::make_shared< MemSession >(shared_from_this(), remote);
}
bool
Start(std::shared_ptr< Logic > l) override
{
if(!ILinkLayer::Start(l))
return false;
_globals->AddNode(shared_from_this());
return true;
}
void
Stop() override
{
_globals->RemoveNode(shared_from_this());
}
};
LinkLayer_ptr
NewOutboundLink(const SecretKey& routerEncSecret, GetRCFunc getrc,
LinkMessageHandler h, SignBufferFunc sign,
SessionEstablishedHandler est,
SessionRenegotiateHandler reneg, TimeoutHandler timeout,
SessionClosedHandler closed)
{
return std::make_shared< MemLink >(routerEncSecret, getrc, h, sign, est,
reneg, timeout, closed, false);
}
LinkLayer_ptr
NewInboundLink(const SecretKey& routerEncSecret, GetRCFunc getrc,
LinkMessageHandler h, SignBufferFunc sign,
SessionEstablishedHandler est,
SessionRenegotiateHandler reneg, TimeoutHandler timeout,
SessionClosedHandler closed)
{
return std::make_shared< MemLink >(routerEncSecret, getrc, h, sign, est,
reneg, timeout, closed, true);
}
void
MempipeContext::AddNode(LinkLayer_ptr ptr)
{
util::Lock lock(&_access);
_nodes.emplace(RouterID(ptr->GetOurRC().pubkey), ptr);
}
bool
MempipeContext::SendTo(const RouterID src, const RouterID dst,
const std::vector< byte_t > msg,
ILinkSession::CompletionHandler delivery)
{
util::Lock lock(&_access);
_sendQueue.emplace_back(std::move(src), std::move(dst), std::move(msg),
std::move(delivery));
return true;
}
void
MempipeContext::InboundConnection(const RouterID to,
const std::shared_ptr< MemSession >& ob)
{
std::shared_ptr< MemSession > other;
{
util::Lock lock(&_access);
auto itr = _nodes.find(to);
if(itr != _nodes.end())
{
other = std::make_shared< MemSession >(itr->second, ob->parent);
}
}
if(other)
{
ConnectNode(other->GetPubKey(), ob->GetPubKey(), other);
ConnectNode(ob->GetPubKey(), other->GetPubKey(), ob);
}
else
{
ob->Disconnected();
}
}
void
MempipeContext::ConnectNode(const RouterID src, const RouterID dst,
const std::shared_ptr< MemSession >& session)
{
util::Lock lock(&_access);
_connections.emplace(std::make_pair(std::make_tuple(src, dst), session));
}
void
MempipeContext::DisconnectNode(const RouterID src, const RouterID dst)
{
util::Lock lock(&_access);
_connections.erase({src, dst});
}
LinkLayer_ptr
MempipeContext::FindNode(const RouterID rid)
{
util::Lock lock(&_access);
auto itr = _nodes.find(rid);
if(itr == _nodes.end())
return nullptr;
return itr->second;
}
bool
MempipeContext::HasConnection(const RouterID src, const RouterID dst) const
{
util::Lock lock(&_access);
return _connections.find({src, dst}) != _connections.end();
}
void
MempipeContext::RemoveNode(LinkLayer_ptr node)
{
util::Lock lock(&_access);
const RouterID pk = node->GetOurRC().pubkey;
_nodes.erase(pk);
auto itr = _connections.begin();
while(itr != _connections.end())
{
if(std::get< 0 >(itr->first) == pk || std::get< 1 >(itr->first) == pk)
{
auto s = itr->second->shared_from_this();
itr->second->GetLinkLayer()->logic()->call_later(
1, [s]() { s->Disconnected(); });
}
++itr;
}
}
void
MempipeContext::Pump()
{
std::deque< SendEvent > q;
{
util::Lock lock(&_access);
q = std::move(_sendQueue);
}
while(q.size())
{
const auto& f = q.front();
{
util::Lock lock(&_access);
auto itr = _connections.find({std::get< 0 >(f), std::get< 1 >(f)});
ILinkSession::DeliveryStatus status =
ILinkSession::DeliveryStatus::eDeliveryDropped;
if(itr != _connections.end())
{
status = ILinkSession::DeliveryStatus::eDeliverySuccess;
itr->second->Recv(std::get< 2 >(f));
}
CallLater(std::bind(std::get< 3 >(f), status));
}
q.pop_front();
}
}
} // namespace mempipe
} // namespace llarp

@ -0,0 +1,25 @@
#ifndef LLARP_MEMPIPE_MEMPIPE_HPP
#define LLARP_MEMPIPE_MEMPIPE_HPP
#include <memory>
#include <link/server.hpp>
namespace llarp
{
namespace mempipe
{
LinkLayer_ptr
NewInboundLink(const SecretKey& routerEncSecret, GetRCFunc getrc,
LinkMessageHandler h, SignBufferFunc sign,
SessionEstablishedHandler est,
SessionRenegotiateHandler reneg, TimeoutHandler timeout,
SessionClosedHandler closed);
LinkLayer_ptr
NewOutboundLink(const SecretKey& routerEncSecret, GetRCFunc getrc,
LinkMessageHandler h, SignBufferFunc sign,
SessionEstablishedHandler est,
SessionRenegotiateHandler reneg, TimeoutHandler timeout,
SessionClosedHandler closed);
} // namespace mempipe
} // namespace llarp
#endif

@ -103,8 +103,8 @@ namespace llarp
}
bool
Path::HandleLRSM(uint64_t status,
std::array< EncryptedFrame, 8 >& frames, AbstractRouter* r)
Path::HandleLRSM(uint64_t status, std::array< EncryptedFrame, 8 >& frames,
AbstractRouter* r)
{
uint64_t currentStatus = status;

@ -164,14 +164,15 @@ namespace llarp
HopHandler_ptr
PathContext::GetByUpstream(const RouterID& remote, const PathID_t& id)
{
auto own = MapGet(m_OurPaths, id,
[](const PathSet_ptr) -> bool {
// TODO: is this right?
return true;
},
[remote, id](PathSet_ptr p) -> HopHandler_ptr {
return p->GetByUpstream(remote, id);
});
auto own = MapGet(
m_OurPaths, id,
[](const PathSet_ptr) -> bool {
// TODO: is this right?
return true;
},
[remote, id](PathSet_ptr p) -> HopHandler_ptr {
return p->GetByUpstream(remote, id);
});
if(own)
return own;

@ -368,9 +368,17 @@ namespace llarp
// reset netid in our rc
_rc.netID = llarp::NetID();
}
const auto linktypename = conf->router.defaultLinkProto();
_defaultLinkType = LinkFactory::TypeFromName(linktypename);
if(_defaultLinkType == LinkFactory::LinkType::eLinkUnknown)
{
LogError("failed to set link type to '", linktypename,
"' as that is invalid");
return false;
}
// IWP config
m_OutboundPort = conf->iwp_links.outboundPort();
m_OutboundPort = std::get< LinksConfig::Port >(conf->links.outboundLink());
// Router config
_rc.SetNick(conf->router.nickname());
maxConnectedRouters = conf->router.maxConnectedRouters();
@ -391,7 +399,7 @@ namespace llarp
lokidRPCPassword = conf->lokid.lokidRPCPassword;
// TODO: add config flag for "is service node"
if(conf->iwp_links.servers().size())
if(conf->links.inboundLinks().size())
{
m_isServiceNode = true;
}
@ -479,15 +487,34 @@ namespace llarp
}
// create inbound links, if we are a service node
for(const auto &serverConfig : conf->iwp_links.servers())
for(const auto &serverConfig : conf->links.inboundLinks())
{
auto server = llarp::utp::NewInboundLink(
// get default factory
auto inboundLinkFactory = LinkFactory::Obtain(_defaultLinkType, true);
// for each option if provided ...
for(const auto &opt : std::get< LinksConfig::Options >(serverConfig))
{
// try interpreting it as a link type
const auto linktype = LinkFactory::TypeFromName(opt);
if(linktype != LinkFactory::LinkType::eLinkUnknown)
{
// override link factory if it's a valid link type
auto factory = LinkFactory::Obtain(linktype, true);
if(factory)
{
inboundLinkFactory = std::move(factory);
break;
}
}
}
auto server = inboundLinkFactory(
encryption(), util::memFn(&AbstractRouter::rc, this),
util::memFn(&AbstractRouter::HandleRecvLinkMessageBuffer, this),
util::memFn(&AbstractRouter::Sign, this),
util::memFn(&IOutboundSessionMaker::OnSessionEstablished,
&_outboundSessionMaker),
util::memFn(&AbstractRouter::CheckRenegotiateValid, this),
util::memFn(&AbstractRouter::Sign, this),
util::memFn(&IOutboundSessionMaker::OnConnectTimeout,
&_outboundSessionMaker),
util::memFn(&AbstractRouter::SessionClosed, this));
@ -498,9 +525,9 @@ namespace llarp
return false;
}
const auto &key = std::get< 0 >(serverConfig);
int af = std::get< 1 >(serverConfig);
uint16_t port = std::get< 2 >(serverConfig);
const auto &key = std::get< LinksConfig::Interface >(serverConfig);
int af = std::get< LinksConfig::AddressFamily >(serverConfig);
uint16_t port = std::get< LinksConfig::Port >(serverConfig);
if(!server->Configure(netloop(), key, af, port))
{
LogError("failed to bind inbound link on ", key, " port ", port);
@ -1059,48 +1086,44 @@ namespace llarp
bool
Router::InitOutboundLinks()
{
using LinkFactory = std::function< LinkLayer_ptr(
const SecretKey &, GetRCFunc, LinkMessageHandler,
SessionEstablishedHandler, SessionRenegotiateHandler, SignBufferFunc,
TimeoutHandler, SessionClosedHandler) >;
const auto linkTypeName = LinkFactory::NameFromType(_defaultLinkType);
LogInfo("initialize outbound link: ", linkTypeName);
auto factory = LinkFactory::Obtain(_defaultLinkType, false);
if(factory == nullptr)
{
LogError("cannot initialize outbound link of type '", linkTypeName,
"' as it has no implementation");
return false;
}
auto link =
factory(encryption(), util::memFn(&AbstractRouter::rc, this),
util::memFn(&AbstractRouter::HandleRecvLinkMessageBuffer, this),
util::memFn(&AbstractRouter::Sign, this),
util::memFn(&IOutboundSessionMaker::OnSessionEstablished,
&_outboundSessionMaker),
util::memFn(&AbstractRouter::CheckRenegotiateValid, this),
util::memFn(&IOutboundSessionMaker::OnConnectTimeout,
&_outboundSessionMaker),
util::memFn(&AbstractRouter::SessionClosed, this));
if(!link)
return false;
if(!link->EnsureKeys(transport_keyfile.string().c_str()))
{
LogError("failed to load ", transport_keyfile);
return false;
}
static std::list< LinkFactory > linkFactories = {utp::NewOutboundLink,
iwp::NewServer};
const auto afs = {AF_INET, AF_INET6};
bool addedAtLeastOne = false;
for(const auto &factory : linkFactories)
for(const auto af : afs)
{
auto link = factory(
encryption(), util::memFn(&AbstractRouter::rc, this),
util::memFn(&AbstractRouter::HandleRecvLinkMessageBuffer, this),
util::memFn(&IOutboundSessionMaker::OnSessionEstablished,
&_outboundSessionMaker),
util::memFn(&AbstractRouter::CheckRenegotiateValid, this),
util::memFn(&AbstractRouter::Sign, this),
util::memFn(&IOutboundSessionMaker::OnConnectTimeout,
&_outboundSessionMaker),
util::memFn(&AbstractRouter::SessionClosed, this));
if(!link)
if(!link->Configure(netloop(), "*", af, m_OutboundPort))
continue;
if(!link->EnsureKeys(transport_keyfile.string().c_str()))
{
LogError("failed to load ", transport_keyfile);
continue;
}
const auto afs = {AF_INET, AF_INET6};
for(const auto af : afs)
{
if(!link->Configure(netloop(), "*", af, m_OutboundPort))
continue;
_linkManager.AddLink(std::move(link), false);
addedAtLeastOne = true;
break;
}
_linkManager.AddLink(std::move(link), false);
return true;
}
return addedAtLeastOne;
return false;
}
bool

@ -28,6 +28,7 @@
#include <router/outbound_message_handler.hpp>
#include <router/outbound_session_maker.hpp>
#include <link/link_manager.hpp>
#include <link/factory.hpp>
#include <router/rc_lookup_handler.hpp>
#include <functional>
@ -175,6 +176,8 @@ namespace llarp
struct sockaddr_in ip4addr;
AddressInfo addrInfo;
LinkFactory::LinkType _defaultLinkType;
llarp_ev_loop_ptr _netloop;
std::shared_ptr< llarp::thread::ThreadPool > cryptoworker;
std::shared_ptr< Logic > _logic;

@ -510,7 +510,7 @@ namespace llarp
{
auto msg = std::make_shared< routing::DHTMessage >();
msg->M.emplace_back(
std::make_unique< dht::PublishIntroMessage >(m_IntroSet, txid, 1));
std::make_unique< dht::PublishIntroMessage >(m_IntroSet, txid, 5));
return msg;
}

@ -309,7 +309,8 @@ namespace llarp
if(self->frame.T != self->msg->tag)
{
LogError("convotag missmatch: ", self->frame.T, " != ", self->msg->tag);
LogError("convotag missmatch: ", self->frame.T,
" != ", self->msg->tag);
self->msg.reset();
delete self;
return;

@ -10,9 +10,10 @@ namespace llarp
{
LinkLayer_ptr
NewOutboundLink(const SecretKey& routerEncSecret, GetRCFunc getrc,
LinkMessageHandler h, SessionEstablishedHandler est,
SessionRenegotiateHandler reneg, SignBufferFunc sign,
TimeoutHandler timeout, SessionClosedHandler closed)
LinkMessageHandler h, SignBufferFunc sign,
SessionEstablishedHandler est,
SessionRenegotiateHandler reneg, TimeoutHandler timeout,
SessionClosedHandler closed)
{
return std::make_shared< LinkLayer >(routerEncSecret, getrc, h, sign, est,
reneg, timeout, closed, false);
@ -20,9 +21,10 @@ namespace llarp
LinkLayer_ptr
NewInboundLink(const SecretKey& routerEncSecret, GetRCFunc getrc,
LinkMessageHandler h, SessionEstablishedHandler est,
SessionRenegotiateHandler reneg, SignBufferFunc sign,
TimeoutHandler timeout, SessionClosedHandler closed)
LinkMessageHandler h, SignBufferFunc sign,
SessionEstablishedHandler est,
SessionRenegotiateHandler reneg, TimeoutHandler timeout,
SessionClosedHandler closed)
{
return std::make_shared< LinkLayer >(routerEncSecret, getrc, h, sign, est,
reneg, timeout, closed, true);

@ -6,20 +6,20 @@
namespace llarp
{
struct AbstractRouter;
namespace utp
{
LinkLayer_ptr
NewInboundLink(const SecretKey& routerEncSecret, GetRCFunc getrc,
LinkMessageHandler h, SessionEstablishedHandler est,
SessionRenegotiateHandler reneg, SignBufferFunc sign,
TimeoutHandler timeout, SessionClosedHandler closed);
LinkMessageHandler h, SignBufferFunc sign,
SessionEstablishedHandler est,
SessionRenegotiateHandler reneg, TimeoutHandler timeout,
SessionClosedHandler closed);
LinkLayer_ptr
NewOutboundLink(const SecretKey& routerEncSecret, GetRCFunc getrc,
LinkMessageHandler h, SessionEstablishedHandler est,
SessionRenegotiateHandler reneg, SignBufferFunc sign,
TimeoutHandler timeout, SessionClosedHandler closed);
LinkMessageHandler h, SignBufferFunc sign,
SessionEstablishedHandler est,
SessionRenegotiateHandler reneg, TimeoutHandler timeout,
SessionClosedHandler closed);
/// shim
const auto NewServer = NewInboundLink;
} // namespace utp

@ -102,10 +102,10 @@ metric-tank-host=52.80.56.123:2003
ASSERT_FALSE(config.metrics.disableMetrics);
{
using kv = IwpConfig::Servers::value_type;
using kv = LinksConfig::Links::value_type;
ASSERT_THAT(config.iwp_links.servers(),
UnorderedElementsAre(kv("eth0", AF_INET, 5501)));
ASSERT_THAT(config.links.inboundLinks(),
UnorderedElementsAre(kv("eth0", AF_INET, 5501, {})));
}
ASSERT_THAT(config.bootstrap.routers,

@ -193,14 +193,15 @@ TEST_F(LinkLayerTest, TestUTPAliceRenegWithBob)
return true;
}
},
[&](Signature& sig, const llarp_buffer_t& buf) -> bool {
return m_crypto.sign(sig, Alice.signingKey, buf);
},
[&](ILinkSession* s) -> bool {
const auto rc = s->GetRemoteRC();
return rc.pubkey == Bob.GetRC().pubkey;
},
[&](RouterContact, RouterContact) -> bool { return true; },
[&](Signature& sig, const llarp_buffer_t& buf) -> bool {
return m_crypto.sign(sig, Alice.signingKey, buf);
},
[&](ILinkSession* session) {
ASSERT_FALSE(session->IsEstablished());
Stop();
@ -231,6 +232,10 @@ TEST_F(LinkLayerTest, TestUTPAliceRenegWithBob)
Bob.gotLIM = true;
return sendDiscardMessage(s);
},
[&](Signature& sig, const llarp_buffer_t& buf) -> bool {
return m_crypto.sign(sig, Bob.signingKey, buf);
},
[&](ILinkSession* s) -> bool {
if(s->GetRemoteRC().pubkey != Alice.GetRC().pubkey)
return false;
@ -242,9 +247,6 @@ TEST_F(LinkLayerTest, TestUTPAliceRenegWithBob)
success = newrc.pubkey == oldrc.pubkey;
return true;
},
[&](Signature& sig, const llarp_buffer_t& buf) -> bool {
return m_crypto.sign(sig, Bob.signingKey, buf);
},
[&](ILinkSession* session) { ASSERT_FALSE(session->IsEstablished()); },
[&](RouterID router) { ASSERT_EQ(router, Alice.GetRouterID()); });
@ -280,6 +282,9 @@ TEST_F(LinkLayerTest, TestUTPAliceConnectToBob)
return false;
}
return AliceGotMessage(buf);
},
[&](Signature& sig, const llarp_buffer_t& buf) -> bool {
return m_crypto.sign(sig, Alice.signingKey, buf);
},
[&](ILinkSession* s) -> bool {
if(s->GetRemoteRC().pubkey != Bob.GetRC().pubkey)
@ -288,9 +293,7 @@ TEST_F(LinkLayerTest, TestUTPAliceConnectToBob)
return true;
},
[&](RouterContact, RouterContact) -> bool { return true; },
[&](Signature& sig, const llarp_buffer_t& buf) -> bool {
return m_crypto.sign(sig, Alice.signingKey, buf);
},
[&](ILinkSession* session) {
ASSERT_FALSE(session->IsEstablished());
Stop();
@ -312,6 +315,9 @@ TEST_F(LinkLayerTest, TestUTPAliceConnectToBob)
return false;
}
return true;
},
[&](Signature& sig, const llarp_buffer_t& buf) -> bool {
return m_crypto.sign(sig, Bob.signingKey, buf);
},
[&](ILinkSession* s) -> bool {
if(s->GetRemoteRC().pubkey != Alice.GetRC().pubkey)
@ -332,9 +338,6 @@ TEST_F(LinkLayerTest, TestUTPAliceConnectToBob)
return true;
},
[&](RouterContact, RouterContact) -> bool { return true; },
[&](Signature& sig, const llarp_buffer_t& buf) -> bool {
return m_crypto.sign(sig, Bob.signingKey, buf);
},
[&](ILinkSession* session) { ASSERT_FALSE(session->IsEstablished()); },
[&](RouterID router) { ASSERT_EQ(router, Alice.GetRouterID()); });

Loading…
Cancel
Save