You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
lokinet/llarp/link/server.cpp

280 lines
5.8 KiB
C++

#include <llarp/link/server.hpp>
#include "fs.hpp"
namespace llarp
{
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;
6 years ago
m_ourAddr.port(port);
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();
6 years ago
}
6 years ago
++itr;
}
}
bool
ILinkLayer::PickAddress(const RouterContact& rc,
llarp::AddressInfo& picked) const
{
std::string OurDialect = Name();
for(const auto& addr : rc.addrs)
{
if(addr.dialect == OurDialect)
{
picked = addr;
return true;
}
}
return false;
}
6 years ago
void
ILinkLayer::RemoveSessionVia(const Addr& addr)
{
auto itr = m_Sessions.find(addr);
if(itr == m_Sessions.end())
return;
delete itr->second;
m_Sessions.erase(itr);
}
void
ILinkLayer::TryEstablishTo(const RouterContact& rc)
{
llarp::AddressInfo to;
if(!PickAddress(rc, to))
return;
util::Lock l(m_SessionsMutex);
llarp::Addr addr(to);
auto itr = m_Sessions.find(addr);
6 years ago
if(itr != m_Sessions.end())
6 years ago
{
6 years ago
itr->second->SendClose();
delete itr->second;
m_Sessions.erase(itr);
6 years ago
}
6 years ago
auto s = NewOutboundSession(rc, to);
s->Start();
m_Sessions.emplace(addr, s);
}
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();
6 years ago
delete itr->second;
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;
6 years ago
llarp::LogDebug("found addr for ", remote, ", ", addr);
}
{
util::Lock l(m_SessionsMutex);
auto itr = m_Sessions.find(addr);
if(itr == m_Sessions.end())
6 years ago
{
llarp::LogWarn("no session to ", addr, " for ", remote);
return false;
6 years ago
}
llarp::LogDebug("SendMessageBuffer ", buf.sz, "bytes");
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
{
6 years ago
return llarp::seckey_topublic(TransportSecretKey());
}
const byte_t*
ILinkLayer::TransportSecretKey() const
{
return m_SecretKey;
}
6 years ago
void
ILinkLayer::PutSession(const Addr& addr, ILinkSession* s)
{
util::Lock l(m_SessionsMutex);
m_Sessions.emplace(addr, s);
}
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))
6 years ago
{
llarp::LogError("Failed to load keyfile ", f);
return false;
6 years ago
}
return true;
}
void
6 years ago
ILinkLayer::OnTick(uint64_t interval, llarp_time_t now)
{
6 years ago
Tick(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
6 years ago
{
{
util::Lock lock(m_LinksMutex);
auto i = m_Links.find(itr->second->GetPubKey());
if(i != m_Links.end())
{
m_Links.erase(i);
}
}
delete itr->second;
itr = m_Sessions.erase(itr);
6 years ago
}
}
ScheduleTick(interval);
}
void
ILinkLayer::ScheduleTick(uint64_t interval)
{
tick_id = llarp_logic_call_later(
m_Logic, {interval, this, &ILinkLayer::on_timer_tick});
}
} // namespace llarp