mirror of https://github.com/oxen-io/lokinet
add bencode file helpers and move link server functions into source file
This commit is contained in:
parent
a8b672a19f
commit
1839da9c3c
|
@ -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)
|
||||
CloseSessionTo(const PubKey& remote);
|
||||
|
||||
void
|
||||
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
|
||||
EnsureKeys(const char* fpath);
|
||||
|
||||
private:
|
||||
static void
|
||||
on_timer_tick(void* user, uint64_t orig, uint64_t left)
|
||||
{
|
||||
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);
|
||||
}
|
||||
// timer cancelled
|
||||
if(left)
|
||||
return;
|
||||
static_cast< ILinkLayer* >(user)->Tick(orig, llarp_time_now_ms());
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
Tick(uint64_t interval, llarp_time_t now);
|
||||
|
||||
bool
|
||||
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;
|
||||
}
|
||||
void
|
||||
ScheduleTick(uint64_t interval);
|
||||
|
||||
virtual bool
|
||||
GetOurAddressInfo(llarp::AddressInfo& addr) const = 0;
|
||||
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…
Reference in New Issue