add bencode file helpers and move link server functions into source file

pull/15/head
Jeff Becker 6 years ago
parent a8b672a19f
commit 1839da9c3c
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05

@ -338,8 +338,7 @@ set(LIB_SRC
llarp/service.cpp
llarp/transit_hop.cpp
llarp/testnet.c
llarp/curvecp/server.cpp
llarp/curvecp/client.cpp
llarp/curvecp/impl.cpp
llarp/dht/context.cpp
llarp/dht/decode.cpp
llarp/dht/dht_immediate.cpp
@ -350,6 +349,7 @@ set(LIB_SRC
llarp/dht/publish_intro.cpp
llarp/handlers/tun.cpp
llarp/link/encoder.cpp
llarp/link/server.cpp
llarp/routing/dht_message.cpp
llarp/routing/message_parser.cpp
llarp/routing/path_confirm.cpp

@ -6,6 +6,7 @@
#include <llarp/logger.hpp>
#include <llarp/mem.hpp>
#include <set>
#include <fstream>
namespace llarp
{
@ -261,6 +262,50 @@ namespace llarp
}
};
/// read entire file and decode its contents into t
template < typename T >
bool
BDecodeReadFile(const char* fpath, T& t)
{
byte_t* ptr = nullptr;
size_t sz = 0;
{
std::ifstream f;
f.open(fpath);
if(!f.is_open())
return false;
f.seekg(0, std::ios::end);
sz = f.tellg();
f.seekg(0, std::ios::end);
ptr = new byte_t[sz];
f.read((char*)ptr, sz);
}
llarp_buffer_t buf = InitBuffer(ptr, sz);
auto result = t.BDecode(&buf);
delete[] ptr;
return result;
}
/// bencode and write to file
template < typename T, size_t bufsz >
bool
BEncodeWriteFile(const char* fpath, const T& t)
{
uint8_t tmp[bufsz] = {0};
auto buf = StackBuffer< decltype(tmp) >(tmp);
if(!t.BEncode(&buf))
return false;
buf.sz = buf.cur - buf.base;
{
std::ofstream f;
f.open(fpath);
if(!f.is_open())
return false;
f.write((char*)buf.base, buf.sz);
}
return true;
}
} // namespace llarp
#endif

@ -7,6 +7,7 @@
#include <llarp/net.hpp>
#include <llarp/ev.h>
#include <llarp/link/session.hpp>
#include <llarp/logic.h>
struct llarp_router;
@ -14,28 +15,19 @@ namespace llarp
{
struct ILinkLayer
{
ILinkLayer(llarp_router* r) : m_router(r)
{
}
ILinkLayer(llarp_router* r);
virtual ~ILinkLayer();
bool
HasSessionTo(const PubKey& pk)
{
util::Lock l(m_LinksMutex);
return m_Links.find(pk) != m_Links.end();
}
HasSessionTo(const PubKey& pk);
bool
HasSessionVia(const Addr& addr)
{
util::Lock l(m_SessionsMutex);
return m_Sessions.find(addr) != m_Sessions.end();
}
HasSessionVia(const Addr& addr);
static void
udp_tick(llarp_udp_io* udp)
{
static_cast< ILinkLayer* >(udp->user)->Tick();
static_cast< ILinkLayer* >(udp->user)->Pump();
}
static void
@ -47,20 +39,7 @@ namespace llarp
bool
Configure(llarp_ev_loop* loop, const std::string& ifname, int af,
uint16_t port)
{
m_udp.user = this;
m_udp.recvfrom = &ILinkLayer::udp_recv_from;
m_udp.tick = &ILinkLayer::udp_tick;
if(ifname == "*")
{
if(!AllInterfaces(af, m_ourAddr))
return false;
}
else if(!GetIFAddr(ifname, m_ourAddr, af))
return false;
return llarp_ev_add_udp(loop, &m_udp, m_ourAddr) != -1;
}
uint16_t port);
virtual ILinkSession*
NewInboundSession(const Addr& from) const = 0;
@ -69,134 +48,74 @@ namespace llarp
NewOutboundSession(const RouterContact& rc) const = 0;
void
Tick()
{
auto now = llarp_time_now_ms();
util::Lock l(m_SessionsMutex);
auto itr = m_Sessions.begin();
while(itr != m_Sessions.end())
{
itr->second->Tick(now);
if(itr->second->TimedOut(now))
itr = m_Sessions.erase(itr);
else
++itr;
}
}
Pump();
void
RecvFrom(const Addr& from, const void* buf, size_t sz)
{
util::Lock l(m_SessionsMutex);
auto itr = m_Sessions.find(from);
if(itr == m_Sessions.end())
m_Sessions
.insert(std::make_pair(
from, std::unique_ptr< ILinkSession >(NewInboundSession(from))))
.first->second->Recv(buf, sz);
else
itr->second->Recv(buf, sz);
}
RecvFrom(const Addr& from, const void* buf, size_t sz);
virtual bool
PickAddress(const RouterContact& rc, llarp::Addr& picked) const = 0;
bool
PickAddress(const RouterContact& rc, llarp::Addr& picked) const;
void
TryEstablishTo(const RouterContact& rc)
{
llarp::Addr to;
if(!PickAddress(rc, to))
return;
util::Lock l(m_SessionsMutex);
auto itr = m_Sessions.find(to);
if(itr == m_Sessions.end())
m_Sessions
.insert(std::make_pair(
to, std::unique_ptr< ILinkSession >(NewOutboundSession(rc))))
.first->second->Handshake();
else
itr->second->Handshake();
}
TryEstablishTo(const RouterContact& rc);
virtual bool
Start(llarp_logic* l) = 0;
bool
Start(llarp_logic* l);
virtual void
Stop() = 0;
void
Stop();
virtual const char*
Name() const = 0;
void
CloseSessionTo(const PubKey& remote)
{
llarp::Addr addr;
{
util::Lock l(m_LinksMutex);
auto itr = m_Links.find(remote);
if(itr == m_Links.end())
return;
addr = itr->second;
}
{
util::Lock l(m_SessionsMutex);
auto itr = m_Sessions.find(addr);
if(itr == m_Sessions.end())
return;
itr->second->SendClose();
m_Sessions.erase(itr);
}
}
CloseSessionTo(const PubKey& remote);
void
KeepAliveSessionTo(const PubKey& remote)
{
llarp::Addr addr;
{
util::Lock l(m_LinksMutex);
auto itr = m_Links.find(remote);
if(itr == m_Links.end())
return;
addr = itr->second;
}
{
util::Lock l(m_SessionsMutex);
auto itr = m_Sessions.find(addr);
if(itr == m_Sessions.end())
return;
itr->second->SendKeepAlive();
}
}
KeepAliveSessionTo(const PubKey& remote);
bool
SendTo(const PubKey& remote, llarp_buffer_t buf);
bool
GetOurAddressInfo(llarp::AddressInfo& addr) const;
virtual uint16_t
Rank() const = 0;
virtual bool
KeyGen(llarp::SecretKey&) = 0;
const byte_t*
TransportPubKey() const;
bool
SendTo(const PubKey& remote, llarp_buffer_t buf)
EnsureKeys(const char* fpath);
private:
static void
on_timer_tick(void* user, uint64_t orig, uint64_t left)
{
bool result = false;
llarp::Addr addr;
{
util::Lock l(m_LinksMutex);
auto itr = m_Links.find(remote);
if(itr == m_Links.end())
return false;
addr = itr->second;
}
{
util::Lock l(m_SessionsMutex);
auto itr = m_Sessions.find(addr);
if(itr == m_Sessions.end())
return false;
result = itr->second->SendMessageBuffer(buf);
}
return result;
// timer cancelled
if(left)
return;
static_cast< ILinkLayer* >(user)->Tick(orig, llarp_time_now_ms());
}
virtual bool
GetOurAddressInfo(llarp::AddressInfo& addr) const = 0;
void
Tick(uint64_t interval, llarp_time_t now);
void
ScheduleTick(uint64_t interval);
uint32_t tick_id;
protected:
llarp_router* m_router;
llarp_logic* m_Logic = nullptr;
Addr m_ourAddr;
llarp_udp_io m_udp;
SecretKey m_SecretKey;
util::Mutex m_LinksMutex;
util::Mutex m_SessionsMutex;
std::unordered_map< PubKey, Addr, PubKey::Hash > m_Links;

@ -13,6 +13,11 @@ namespace llarp
{
virtual ~ILinkSession(){};
/// called every event loop tick
virtual void
Pump() = 0;
/// called every timer tick
virtual void
Tick(llarp_time_t now) = 0;

@ -6,6 +6,7 @@
#ifndef ssize_t
#define ssize_t long
#endif
size_t
llarp_buffer_size_left(llarp_buffer_t buff)
{
@ -118,4 +119,4 @@ llarp_buffer_put_uint32(llarp_buffer_t* buf, uint32_t* i)
*i = bufbe32toh(buf->cur);
buf->cur += sizeof(uint32_t);
return true;
}
}

@ -0,0 +1,32 @@
#include <llarp/link/curvecp.hpp>
#include "router.hpp"
namespace llarp
{
namespace curvecp
{
struct LinkLayer : public llarp::ILinkLayer
{
LinkLayer(llarp_router* r) : llarp::ILinkLayer(r)
{
}
~LinkLayer()
{
}
const char*
Name() const
{
return "curvecp";
}
};
std::unique_ptr< llarp::ILinkLayer >
NewServer(llarp_router* r)
{
return std::unique_ptr< llarp::ILinkLayer >(new LinkLayer(r));
}
} // namespace curvecp
} // namespace llarp

@ -1,4 +1,5 @@
#include <llarp/link/curvecp.hpp>
#include "router.hpp"
namespace llarp
{

@ -0,0 +1,249 @@
#include <llarp/link/server.hpp>
#include "fs.hpp"
namespace llarp
{
ILinkLayer::ILinkLayer(llarp_router* r) : m_router(r)
{
}
ILinkLayer::~ILinkLayer()
{
}
bool
ILinkLayer::HasSessionTo(const PubKey& pk)
{
util::Lock l(m_LinksMutex);
return m_Links.find(pk) != m_Links.end();
}
bool
ILinkLayer::HasSessionVia(const Addr& addr)
{
util::Lock l(m_SessionsMutex);
return m_Sessions.find(addr) != m_Sessions.end();
}
bool
ILinkLayer::Configure(llarp_ev_loop* loop, const std::string& ifname, int af,
uint16_t port)
{
m_udp.user = this;
m_udp.recvfrom = &ILinkLayer::udp_recv_from;
m_udp.tick = &ILinkLayer::udp_tick;
if(ifname == "*")
{
if(!AllInterfaces(af, m_ourAddr))
return false;
}
else if(!GetIFAddr(ifname, m_ourAddr, af))
return false;
return llarp_ev_add_udp(loop, &m_udp, m_ourAddr) != -1;
}
void
ILinkLayer::Pump()
{
auto now = llarp_time_now_ms();
util::Lock l(m_SessionsMutex);
auto itr = m_Sessions.begin();
while(itr != m_Sessions.end())
{
if(!itr->second->TimedOut(now))
{
itr->second->Pump();
++itr;
}
else
itr = m_Sessions.erase(itr);
}
}
void
ILinkLayer::RecvFrom(const Addr& from, const void* buf, size_t sz)
{
util::Lock l(m_SessionsMutex);
auto itr = m_Sessions.find(from);
if(itr == m_Sessions.end())
m_Sessions
.insert(std::make_pair(
from, std::unique_ptr< ILinkSession >(NewInboundSession(from))))
.first->second->Recv(buf, sz);
else
itr->second->Recv(buf, sz);
}
bool
ILinkLayer::PickAddress(const RouterContact& rc, llarp::Addr& picked) const
{
std::string OurDialect = Name();
for(const auto& addr : rc.addrs)
{
if(addr.dialect == OurDialect)
{
picked = addr;
return true;
}
}
return false;
}
void
ILinkLayer::TryEstablishTo(const RouterContact& rc)
{
llarp::Addr to;
if(!PickAddress(rc, to))
return;
util::Lock l(m_SessionsMutex);
auto itr = m_Sessions.find(to);
if(itr == m_Sessions.end())
m_Sessions
.insert(std::make_pair(
to, std::unique_ptr< ILinkSession >(NewOutboundSession(rc))))
.first->second->Handshake();
else
itr->second->Handshake();
}
bool
ILinkLayer::Start(llarp_logic* l)
{
m_Logic = l;
ScheduleTick(500);
return true;
}
void
ILinkLayer::Stop()
{
if(m_Logic && tick_id)
llarp_logic_remove_call(m_Logic, tick_id);
}
void
ILinkLayer::CloseSessionTo(const PubKey& remote)
{
llarp::Addr addr;
{
util::Lock l(m_LinksMutex);
auto itr = m_Links.find(remote);
if(itr == m_Links.end())
return;
addr = itr->second;
}
{
util::Lock l(m_SessionsMutex);
auto itr = m_Sessions.find(addr);
if(itr == m_Sessions.end())
return;
itr->second->SendClose();
m_Sessions.erase(itr);
}
}
void
ILinkLayer::KeepAliveSessionTo(const PubKey& remote)
{
llarp::Addr addr;
{
util::Lock l(m_LinksMutex);
auto itr = m_Links.find(remote);
if(itr == m_Links.end())
return;
addr = itr->second;
}
{
util::Lock l(m_SessionsMutex);
auto itr = m_Sessions.find(addr);
if(itr == m_Sessions.end())
return;
itr->second->SendKeepAlive();
}
}
bool
ILinkLayer::SendTo(const PubKey& remote, llarp_buffer_t buf)
{
bool result = false;
llarp::Addr addr;
{
util::Lock l(m_LinksMutex);
auto itr = m_Links.find(remote);
if(itr == m_Links.end())
return false;
addr = itr->second;
}
{
util::Lock l(m_SessionsMutex);
auto itr = m_Sessions.find(addr);
if(itr == m_Sessions.end())
return false;
result = itr->second->SendMessageBuffer(buf);
}
return result;
}
bool
ILinkLayer::GetOurAddressInfo(llarp::AddressInfo& addr) const
{
addr.dialect = Name();
addr.pubkey = TransportPubKey();
addr.rank = Rank();
addr.port = m_ourAddr.port();
addr.ip = *m_ourAddr.addr6();
return true;
}
const byte_t*
ILinkLayer::TransportPubKey() const
{
return llarp::seckey_topublic(m_SecretKey);
}
bool
ILinkLayer::EnsureKeys(const char* f)
{
fs::path fpath(f);
llarp::SecretKey keys;
std::error_code ec;
if(!fs::exists(fpath, ec))
{
if(!KeyGen(m_SecretKey))
return false;
// generated new keys
if(!BEncodeWriteFile< decltype(keys), 128 >(f, m_SecretKey))
return false;
}
// load keys
if(!BDecodeReadFile(f, m_SecretKey))
return false;
return true;
}
void
ILinkLayer::Tick(uint64_t interval, llarp_time_t now)
{
util::Lock l(m_SessionsMutex);
auto itr = m_Sessions.begin();
while(itr != m_Sessions.end())
{
if(!itr->second->TimedOut(now))
{
itr->second->Tick(now);
++itr;
}
else
itr = m_Sessions.erase(itr);
}
ScheduleTick(interval);
}
void
ILinkLayer::ScheduleTick(uint64_t interval)
{
tick_id = llarp_logic_call_later(
m_Logic, {interval, this, &ILinkLayer::on_timer_tick});
}
} // namespace llarp

@ -727,6 +727,12 @@ llarp_router::InitOutboundLink()
auto link = llarp::curvecp::NewServer(this);
if(!link->EnsureKeys(transport_keyfile.string().c_str()))
{
llarp::LogError("failed to load ", transport_keyfile);
return false;
}
auto afs = {AF_INET, AF_INET6};
for(auto af : afs)
@ -911,6 +917,11 @@ namespace llarp
if(!StrEq(key, "*"))
{
auto server = llarp::curvecp::NewServer(self);
if(!server->EnsureKeys(self->transport_keyfile.string().c_str()))
{
llarp::LogError("failed to ensure keyfile ", self->transport_keyfile);
return;
}
if(server->Configure(self->netloop, key, af, proto))
{
self->AddInboundLink(server);

Loading…
Cancel
Save