2018-09-02 18:25:42 +00:00
|
|
|
#ifndef LLARP_LINK_SERVER_HPP
|
|
|
|
#define LLARP_LINK_SERVER_HPP
|
2018-12-12 02:52:51 +00:00
|
|
|
|
2019-01-13 16:30:07 +00:00
|
|
|
#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>
|
2019-01-11 01:42:02 +00:00
|
|
|
#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>
|
2019-01-10 19:41:51 +00:00
|
|
|
#include <util/threading.hpp>
|
2019-02-15 22:19:19 +00:00
|
|
|
#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
|
|
|
|
2018-09-02 18:25:42 +00:00
|
|
|
namespace llarp
|
|
|
|
{
|
2018-12-17 20:46:08 +00:00
|
|
|
/// handle a link layer message
|
|
|
|
using LinkMessageHandler =
|
2019-02-01 01:58:06 +00:00
|
|
|
std::function< bool(ILinkSession*, const llarp_buffer_t&) >;
|
2018-12-17 20:46:08 +00:00
|
|
|
|
|
|
|
/// sign a buffer with identity key
|
2019-02-01 01:58:06 +00:00
|
|
|
using SignBufferFunc =
|
|
|
|
std::function< bool(Signature&, const llarp_buffer_t&) >;
|
2018-12-17 20:46:08 +00:00
|
|
|
|
|
|
|
/// 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*) >;
|
2018-12-17 20:46:08 +00:00
|
|
|
|
2018-12-19 16:17:41 +00:00
|
|
|
/// 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) >;
|
|
|
|
|
2018-12-17 20:46:08 +00:00
|
|
|
/// handles close of all sessions with pubkey
|
|
|
|
using SessionClosedHandler = std::function< void(llarp::RouterID) >;
|
2018-12-10 16:26:46 +00:00
|
|
|
|
2019-04-19 15:10:26 +00:00
|
|
|
struct ILinkLayer
|
2018-09-02 18:25:42 +00:00
|
|
|
{
|
2019-01-02 01:04:04 +00:00
|
|
|
ILinkLayer(const SecretKey& routerEncSecret, GetRCFunc getrc,
|
2018-12-17 20:46:08 +00:00
|
|
|
LinkMessageHandler handler, SignBufferFunc signFunc,
|
|
|
|
SessionEstablishedHandler sessionEstablish,
|
2018-12-19 16:17:41 +00:00
|
|
|
SessionRenegotiateHandler renegotiate, TimeoutHandler timeout,
|
|
|
|
SessionClosedHandler closed);
|
2018-09-03 13:10:56 +00:00
|
|
|
virtual ~ILinkLayer();
|
2018-12-17 20:46:08 +00:00
|
|
|
|
2018-10-29 16:48:36 +00:00
|
|
|
/// get current time via event loop
|
|
|
|
llarp_time_t
|
2018-12-17 20:46:08 +00:00
|
|
|
Now() const
|
2018-10-29 16:48:36 +00:00
|
|
|
{
|
|
|
|
return llarp_ev_loop_time_now_ms(m_Loop);
|
|
|
|
}
|
2018-12-17 20:46:08 +00:00
|
|
|
|
2019-04-02 09:03:53 +00:00
|
|
|
virtual Crypto*
|
|
|
|
OurCrypto() = 0;
|
|
|
|
|
2018-09-02 18:25:42 +00:00
|
|
|
bool
|
2019-01-02 01:03:53 +00:00
|
|
|
HasSessionTo(const RouterID& pk);
|
2018-09-02 18:25:42 +00:00
|
|
|
|
|
|
|
bool
|
2018-09-03 13:10:56 +00:00
|
|
|
HasSessionVia(const Addr& addr);
|
2018-09-02 18:25:42 +00:00
|
|
|
|
2018-10-25 18:18:12 +00:00
|
|
|
void
|
2019-04-08 12:01:52 +00:00
|
|
|
ForEachSession(std::function< void(const ILinkSession*) > visit,
|
|
|
|
bool randomize = false) const
|
2019-03-03 20:51:47 +00:00
|
|
|
LOCKS_EXCLUDED(m_AuthedLinksMutex);
|
2018-10-25 18:18:12 +00:00
|
|
|
|
2018-12-19 16:17:41 +00:00
|
|
|
void
|
2019-03-03 20:51:47 +00:00
|
|
|
ForEachSession(std::function< void(ILinkSession*) > visit)
|
|
|
|
LOCKS_EXCLUDED(m_AuthedLinksMutex);
|
2018-12-19 16:17:41 +00:00
|
|
|
|
2018-09-02 18:25:42 +00:00
|
|
|
static void
|
|
|
|
udp_tick(llarp_udp_io* udp)
|
|
|
|
{
|
2018-09-03 13:10:56 +00:00
|
|
|
static_cast< ILinkLayer* >(udp->user)->Pump();
|
2018-09-02 18:25:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2019-02-03 00:48:10 +00:00
|
|
|
udp_recv_from(llarp_udp_io* udp, const sockaddr* from, ManagedBuffer buf)
|
2018-09-02 18:25:42 +00:00
|
|
|
{
|
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);
|
2019-01-02 01:04:04 +00:00
|
|
|
// 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);
|
2018-09-02 18:25:42 +00:00
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2018-09-02 18:25:42 +00:00
|
|
|
bool
|
2019-04-08 12:01:52 +00:00
|
|
|
Configure(llarp_ev_loop_ptr loop, const std::string& ifname, int af,
|
2018-09-03 13:10:56 +00:00
|
|
|
uint16_t port);
|
2018-09-02 18:25:42 +00:00
|
|
|
|
2019-04-02 09:03:53 +00:00
|
|
|
virtual std::shared_ptr< ILinkSession >
|
2018-09-04 12:41:25 +00:00
|
|
|
NewOutboundSession(const RouterContact& rc, const AddressInfo& ai) = 0;
|
2018-09-02 18:25:42 +00:00
|
|
|
|
2018-09-04 12:41:25 +00:00
|
|
|
virtual void
|
2018-09-03 13:10:56 +00:00
|
|
|
Pump();
|
2018-09-02 18:25:42 +00:00
|
|
|
|
2018-09-04 12:41:25 +00:00
|
|
|
virtual void
|
|
|
|
RecvFrom(const Addr& from, const void* buf, size_t sz) = 0;
|
2018-09-02 18:25:42 +00:00
|
|
|
|
2018-09-03 13:10:56 +00:00
|
|
|
bool
|
2018-09-04 12:41:25 +00:00
|
|
|
PickAddress(const RouterContact& rc, AddressInfo& picked) const;
|
2018-09-02 18:25:42 +00:00
|
|
|
|
2018-11-21 14:56:12 +00:00
|
|
|
bool
|
2018-12-19 17:48:29 +00:00
|
|
|
TryEstablishTo(RouterContact rc);
|
2018-09-02 18:25:42 +00:00
|
|
|
|
2019-01-03 21:10:40 +00:00
|
|
|
virtual bool
|
2018-12-10 14:14:55 +00:00
|
|
|
Start(llarp::Logic* l);
|
2018-09-02 18:25:42 +00:00
|
|
|
|
2018-09-03 13:10:56 +00:00
|
|
|
void
|
|
|
|
Stop();
|
2018-09-02 18:25:42 +00:00
|
|
|
|
|
|
|
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);
|
2019-02-15 22:19:19 +00:00
|
|
|
|
2018-09-02 18:25:42 +00:00
|
|
|
void
|
2019-01-02 01:04:04 +00:00
|
|
|
CloseSessionTo(const RouterID& remote);
|
2018-09-02 18:25:42 +00:00
|
|
|
|
|
|
|
void
|
2019-01-02 01:04:04 +00:00
|
|
|
KeepAliveSessionTo(const RouterID& remote);
|
2018-09-03 13:10:56 +00:00
|
|
|
|
|
|
|
bool
|
2019-02-01 01:58:06 +00:00
|
|
|
SendTo(const RouterID& remote, const llarp_buffer_t& buf);
|
2018-09-03 13:10:56 +00:00
|
|
|
|
|
|
|
bool
|
2018-09-04 12:41:25 +00:00
|
|
|
GetOurAddressInfo(AddressInfo& addr) const;
|
2018-09-03 13:10:56 +00:00
|
|
|
|
2018-12-19 16:17:41 +00:00
|
|
|
bool
|
2019-01-02 01:03:53 +00:00
|
|
|
VisitSessionByPubkey(const RouterID& pk,
|
2019-03-03 20:51:47 +00:00
|
|
|
std::function< bool(ILinkSession*) > visit)
|
|
|
|
LOCKS_EXCLUDED(m_AuthedLinksMutex);
|
2018-12-19 16:17:41 +00:00
|
|
|
|
2018-09-03 13:10:56 +00:00
|
|
|
virtual uint16_t
|
|
|
|
Rank() const = 0;
|
|
|
|
|
|
|
|
virtual bool
|
2018-09-04 12:41:25 +00:00
|
|
|
KeyGen(SecretKey&) = 0;
|
2018-09-03 13:10:56 +00:00
|
|
|
|
|
|
|
const byte_t*
|
|
|
|
TransportPubKey() const;
|
2018-09-02 18:25:42 +00:00
|
|
|
|
2019-01-02 01:04:04 +00:00
|
|
|
const SecretKey&
|
2018-12-17 20:46:08 +00:00
|
|
|
RouterEncryptionSecret() const
|
|
|
|
{
|
|
|
|
return m_RouterEncSecret;
|
|
|
|
}
|
|
|
|
|
2019-01-02 01:04:04 +00:00
|
|
|
const SecretKey&
|
2018-09-04 12:41:25 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2018-09-02 18:25:42 +00:00
|
|
|
bool
|
2018-09-03 13:10:56 +00:00
|
|
|
EnsureKeys(const char* fpath);
|
|
|
|
|
2018-12-17 20:46:08 +00:00
|
|
|
bool
|
|
|
|
GenEphemeralKeys();
|
|
|
|
|
2019-01-07 12:47:57 +00:00
|
|
|
bool
|
2019-01-02 01:03:53 +00:00
|
|
|
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
|
|
|
|
2018-12-17 20:46:08 +00:00
|
|
|
LinkMessageHandler HandleMessage;
|
|
|
|
TimeoutHandler HandleTimeout;
|
|
|
|
SignBufferFunc Sign;
|
|
|
|
GetRCFunc GetOurRC;
|
|
|
|
SessionEstablishedHandler SessionEstablished;
|
|
|
|
SessionClosedHandler SessionClosed;
|
2018-12-19 16:17:41 +00:00
|
|
|
SessionRenegotiateHandler SessionRenegotiate;
|
2018-12-17 20:46:08 +00:00
|
|
|
|
2019-05-07 12:31:34 +00:00
|
|
|
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
|
|
|
|
2018-09-03 13:10:56 +00:00
|
|
|
private:
|
|
|
|
static void
|
|
|
|
on_timer_tick(void* user, uint64_t orig, uint64_t left)
|
2018-09-02 18:25:42 +00:00
|
|
|
{
|
2018-09-03 13:10:56 +00:00
|
|
|
// timer cancelled
|
|
|
|
if(left)
|
|
|
|
return;
|
2018-10-29 16:48:36 +00:00
|
|
|
static_cast< ILinkLayer* >(user)->OnTick(orig);
|
2018-09-02 18:25:42 +00:00
|
|
|
}
|
|
|
|
|
2018-09-03 13:10:56 +00:00
|
|
|
void
|
2018-10-29 16:48:36 +00:00
|
|
|
OnTick(uint64_t interval);
|
2018-09-03 13:10:56 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
ScheduleTick(uint64_t interval);
|
|
|
|
|
|
|
|
uint32_t tick_id;
|
2019-01-02 01:04:04 +00:00
|
|
|
const SecretKey& m_RouterEncSecret;
|
2018-09-02 18:25:42 +00:00
|
|
|
|
|
|
|
protected:
|
2018-11-22 23:59:03 +00:00
|
|
|
using Lock = util::NullLock;
|
|
|
|
using Mutex = util::NullMutex;
|
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);
|
2018-09-04 12:41:25 +00:00
|
|
|
|
2018-12-10 14:14:55 +00:00
|
|
|
llarp::Logic* m_Logic = nullptr;
|
2019-04-08 12:01:52 +00:00
|
|
|
llarp_ev_loop_ptr m_Loop;
|
2018-09-02 18:25:42 +00:00
|
|
|
Addr m_ourAddr;
|
|
|
|
llarp_udp_io m_udp;
|
2018-09-03 13:10:56 +00:00
|
|
|
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 >;
|
|
|
|
|
|
|
|
Mutex m_AuthedLinksMutex ACQUIRED_BEFORE(m_PendingMutex);
|
|
|
|
AuthedLinks m_AuthedLinks GUARDED_BY(m_AuthedLinksMutex);
|
|
|
|
Mutex m_PendingMutex ACQUIRED_AFTER(m_AuthedLinksMutex);
|
|
|
|
Pending m_Pending GUARDED_BY(m_PendingMutex);
|
2018-09-02 18:25:42 +00:00
|
|
|
};
|
|
|
|
} // namespace llarp
|
|
|
|
|
|
|
|
#endif
|