lokinet/llarp/link/server.hpp

269 lines
6.6 KiB
C++
Raw Normal View History

#ifndef LLARP_LINK_SERVER_HPP
#define LLARP_LINK_SERVER_HPP
#include <crypto/types.hpp>
2019-01-11 01:19:36 +00:00
#include <ev/ev.h>
2018-12-12 01:32:10 +00:00
#include <link/session.hpp>
#include <net/net.hpp>
2018-12-12 01:55:30 +00:00
#include <router_contact.hpp>
2019-01-11 01:19:36 +00:00
#include <util/logic.hpp>
#include <util/threading.hpp>
#include <util/status.hpp>
2018-12-12 01:32:10 +00:00
2018-09-07 20:36:06 +00:00
#include <list>
2019-04-02 09:03:53 +00:00
#include <memory>
2018-12-12 01:32:10 +00:00
#include <unordered_map>
2018-09-03 12:08:02 +00:00
namespace llarp
{
/// handle a link layer message
using LinkMessageHandler =
std::function< bool(ILinkSession*, const llarp_buffer_t&) >;
/// sign a buffer with identity key
using SignBufferFunc =
std::function< bool(Signature&, const llarp_buffer_t&) >;
/// handle connection timeout
using TimeoutHandler = std::function< void(ILinkSession*) >;
/// get our RC
using GetRCFunc = std::function< const llarp::RouterContact&(void) >;
/// handler of session established
2019-02-27 12:55:26 +00:00
/// return false to reject
/// return true to accept
using SessionEstablishedHandler = std::function< bool(ILinkSession*) >;
/// f(new, old)
/// handler of session renegotiation
/// returns true if the new rc is valid
/// returns false otherwise and the session is terminated
using SessionRenegotiateHandler =
std::function< bool(llarp::RouterContact, llarp::RouterContact) >;
/// handles close of all sessions with pubkey
using SessionClosedHandler = std::function< void(llarp::RouterID) >;
2019-04-19 15:10:26 +00:00
struct ILinkLayer
{
ILinkLayer(const SecretKey& routerEncSecret, GetRCFunc getrc,
LinkMessageHandler handler, SignBufferFunc signFunc,
SessionEstablishedHandler sessionEstablish,
SessionRenegotiateHandler renegotiate, TimeoutHandler timeout,
SessionClosedHandler closed);
virtual ~ILinkLayer();
2018-10-29 16:48:36 +00:00
/// get current time via event loop
llarp_time_t
Now() const
2018-10-29 16:48:36 +00:00
{
return llarp_ev_loop_time_now_ms(m_Loop);
}
bool
HasSessionTo(const RouterID& pk);
bool
HasSessionVia(const Addr& addr);
void
2019-04-08 12:01:52 +00:00
ForEachSession(std::function< void(const ILinkSession*) > visit,
bool randomize = false) const
LOCKS_EXCLUDED(m_AuthedLinksMutex);
void
ForEachSession(std::function< void(ILinkSession*) > visit)
LOCKS_EXCLUDED(m_AuthedLinksMutex);
static void
udp_tick(llarp_udp_io* udp)
{
static_cast< ILinkLayer* >(udp->user)->Pump();
}
static void
2019-02-03 00:48:10 +00:00
udp_recv_from(llarp_udp_io* udp, const sockaddr* from, ManagedBuffer buf)
{
2018-11-03 13:19:18 +00:00
if(!udp)
{
llarp::LogWarn("no udp set");
return;
}
2019-03-25 15:41:37 +00:00
const llarp::Addr srcaddr(*from);
// maybe check from too?
2018-11-23 14:37:26 +00:00
// no it's never null
2019-02-02 23:12:42 +00:00
static_cast< ILinkLayer* >(udp->user)->RecvFrom(
2019-03-25 15:41:37 +00:00
srcaddr, buf.underlying.base, buf.underlying.sz);
}
2019-01-03 21:10:40 +00:00
void
2019-03-07 15:17:29 +00:00
SendTo_LL(const llarp::Addr& to, const llarp_buffer_t& pkt)
2019-01-03 21:10:40 +00:00
{
llarp_ev_udp_sendto(&m_udp, to, pkt);
}
2019-08-07 16:33:29 +00:00
virtual bool
2019-04-08 12:01:52 +00:00
Configure(llarp_ev_loop_ptr loop, const std::string& ifname, int af,
uint16_t port);
2019-04-02 09:03:53 +00:00
virtual std::shared_ptr< ILinkSession >
NewOutboundSession(const RouterContact& rc, const AddressInfo& ai) = 0;
virtual void
Pump();
virtual void
RecvFrom(const Addr& from, const void* buf, size_t sz) = 0;
bool
PickAddress(const RouterContact& rc, AddressInfo& picked) const;
bool
2018-12-19 17:48:29 +00:00
TryEstablishTo(RouterContact rc);
2019-01-03 21:10:40 +00:00
virtual bool
2019-05-22 16:20:50 +00:00
Start(std::shared_ptr< llarp::Logic > l);
2019-08-07 16:33:29 +00:00
virtual void
Stop();
virtual const char*
Name() const = 0;
2019-02-18 19:44:41 +00:00
util::StatusObject
2019-04-19 15:10:26 +00:00
ExtractStatus() const LOCKS_EXCLUDED(m_AuthedLinksMutex);
void
CloseSessionTo(const RouterID& remote);
void
KeepAliveSessionTo(const RouterID& remote);
2019-08-07 16:33:29 +00:00
virtual bool
2019-07-26 16:19:31 +00:00
SendTo(const RouterID& remote, const llarp_buffer_t& buf,
ILinkSession::CompletionHandler completed);
2019-08-07 16:33:29 +00:00
virtual bool
GetOurAddressInfo(AddressInfo& addr) const;
bool
VisitSessionByPubkey(const RouterID& pk,
std::function< bool(ILinkSession*) > visit)
LOCKS_EXCLUDED(m_AuthedLinksMutex);
virtual uint16_t
Rank() const = 0;
virtual bool
KeyGen(SecretKey&) = 0;
const byte_t*
TransportPubKey() const;
const SecretKey&
RouterEncryptionSecret() const
{
return m_RouterEncSecret;
}
const SecretKey&
TransportSecretKey() const;
2019-01-05 13:45:05 +00:00
bool
IsCompatable(const llarp::RouterContact& other) const
{
const std::string us = Name();
for(const auto& ai : other.addrs)
if(ai.dialect == us)
return true;
return false;
}
bool
EnsureKeys(const char* fpath);
bool
GenEphemeralKeys();
2019-08-23 11:32:52 +00:00
virtual bool
MapAddr(const RouterID& pk, ILinkSession* s);
2018-09-04 19:15:06 +00:00
2019-02-18 19:44:41 +00:00
void
Tick(llarp_time_t now);
2018-09-06 20:31:58 +00:00
LinkMessageHandler HandleMessage;
TimeoutHandler HandleTimeout;
SignBufferFunc Sign;
GetRCFunc GetOurRC;
SessionEstablishedHandler SessionEstablished;
SessionClosedHandler SessionClosed;
SessionRenegotiateHandler SessionRenegotiate;
2019-08-07 16:33:29 +00:00
std::shared_ptr< Logic >
logic()
{
return m_Logic;
}
bool
operator<(const ILinkLayer& other) const
{
return Rank() < other.Rank() || Name() < other.Name()
|| m_ourAddr < other.m_ourAddr;
}
2019-01-07 16:35:25 +00:00
/// called by link session to remove a pending session who is timed out
2019-03-11 13:01:43 +00:00
// void
// RemovePending(ILinkSession* s) LOCKS_EXCLUDED(m_PendingMutex);
2019-01-07 16:35:25 +00:00
private:
static void
on_timer_tick(void* user, uint64_t orig, uint64_t left)
{
// timer cancelled
if(left)
return;
2018-10-29 16:48:36 +00:00
static_cast< ILinkLayer* >(user)->OnTick(orig);
}
void
2018-10-29 16:48:36 +00:00
OnTick(uint64_t interval);
void
ScheduleTick(uint64_t interval);
uint32_t tick_id;
const SecretKey& m_RouterEncSecret;
protected:
using Lock = util::Lock;
using Mutex = util::Mutex;
2018-09-10 13:43:36 +00:00
2019-01-07 12:47:57 +00:00
bool
2019-04-02 09:03:53 +00:00
PutSession(const std::shared_ptr< ILinkSession >& s);
2019-05-22 16:20:50 +00:00
std::shared_ptr< llarp::Logic > m_Logic = nullptr;
2019-04-08 12:01:52 +00:00
llarp_ev_loop_ptr m_Loop;
Addr m_ourAddr;
llarp_udp_io m_udp;
SecretKey m_SecretKey;
2018-09-07 20:36:06 +00:00
2019-03-29 14:03:07 +00:00
using AuthedLinks =
2019-04-02 09:03:53 +00:00
std::unordered_multimap< RouterID, std::shared_ptr< ILinkSession >,
2019-03-29 14:03:07 +00:00
RouterID::Hash >;
using Pending =
2019-04-02 09:03:53 +00:00
std::unordered_multimap< llarp::Addr, std::shared_ptr< ILinkSession >,
2019-03-29 14:03:07 +00:00
llarp::Addr::Hash >;
mutable Mutex m_AuthedLinksMutex ACQUIRED_BEFORE(m_PendingMutex);
2019-03-29 14:03:07 +00:00
AuthedLinks m_AuthedLinks GUARDED_BY(m_AuthedLinksMutex);
mutable Mutex m_PendingMutex ACQUIRED_AFTER(m_AuthedLinksMutex);
2019-03-29 14:03:07 +00:00
Pending m_Pending GUARDED_BY(m_PendingMutex);
};
2019-05-15 15:54:26 +00:00
using LinkLayer_ptr = std::shared_ptr< ILinkLayer >;
} // namespace llarp
#endif