!!! this breaks backwards compat :^) !!!

redo link protocol to use 2 session keys, add unit tests.
pull/174/head
Jeff Becker 6 years ago
parent c454b5264c
commit b39c46fc03
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05

@ -611,6 +611,7 @@ set(TEST_SRC
test/obtain_exit_unittest.cpp
test/pq_unittest.cpp
test/net_unittest.cpp
test/utp_unittest.cpp
test/test_dns_unit.cpp
test/test_dnsc_unit.cpp
test/test_dnsd_unit.cpp

@ -0,0 +1,3 @@
node_modules
build
*.log

@ -54,6 +54,10 @@ namespace llarp
using sym_cipher_func =
std::function< bool(llarp_buffer_t, const byte_t *, const byte_t *) >;
/// SD/SE(dst, src, key, nonce)
using sym_ciper_alt_func = std::function< bool(
llarp_buffer_t, llarp_buffer_t, const byte_t *, const byte_t *) >;
/// H(result, body)
using hash_func = std::function< bool(byte_t *, llarp_buffer_t) >;
@ -77,6 +81,8 @@ namespace llarp
{
/// xchacha symettric cipher
sym_cipher_func xchacha20;
/// xchacha symettric cipher (multibuffer)
sym_ciper_alt_func xchacha20_alt;
/// path dh creator's side
path_dh_func dh_client;
/// path dh relay side

@ -24,6 +24,15 @@ namespace llarp
== 0;
}
static bool
xchacha20_alt(llarp_buffer_t out, llarp_buffer_t in, const byte_t *k,
const byte_t *n)
{
if(in.sz > out.sz)
return false;
return crypto_stream_xchacha20_xor(out.base, in.base, in.sz, n, k) == 0;
}
static bool
dh(uint8_t *out, const uint8_t *client_pk, const uint8_t *server_pk,
const uint8_t *themPub, const uint8_t *usSec)
@ -183,6 +192,7 @@ namespace llarp
else
ntru_init(0);
this->xchacha20 = llarp::sodium::xchacha20;
this->xchacha20_alt = llarp::sodium::xchacha20_alt;
this->dh_client = llarp::sodium::dh_client;
this->dh_server = llarp::sodium::dh_server;
this->transport_dh_client = llarp::sodium::dh_client;

@ -3,6 +3,20 @@
namespace llarp
{
ILinkLayer::ILinkLayer(const byte_t* routerEncSecret, GetRCFunc getrc,
LinkMessageHandler handler, SignBufferFunc signbuf,
SessionEstablishedHandler establishedSession,
TimeoutHandler timeout, SessionClosedHandler closed)
: HandleMessage(handler)
, HandleTimeout(timeout)
, Sign(signbuf)
, GetOurRC(getrc)
, SessionEstablished(establishedSession)
, SessionClosed(closed)
, m_RouterEncSecret(routerEncSecret)
{
}
ILinkLayer::~ILinkLayer()
{
}
@ -48,7 +62,7 @@ namespace llarp
void
ILinkLayer::Pump()
{
auto _now = now();
auto _now = Now();
{
Lock lock(m_AuthedLinksMutex);
auto itr = m_AuthedLinks.begin();
@ -246,6 +260,12 @@ namespace llarp
return m_SecretKey;
}
bool
ILinkLayer::GenEphemeralKeys()
{
return KeyGen(m_SecretKey);
}
bool
ILinkLayer::EnsureKeys(const char* f)
{
@ -279,7 +299,7 @@ namespace llarp
void
ILinkLayer::OnTick(uint64_t interval)
{
Tick(now());
Tick(Now());
ScheduleTick(interval);
}

@ -14,17 +14,40 @@
namespace llarp
{
struct Router;
/// handle a link layer message
using LinkMessageHandler =
std::function< bool(ILinkSession*, llarp_buffer_t) >;
/// sign a buffer with identity key
using SignBufferFunc = std::function< bool(Signature&, 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
using SessionEstablishedHandler = std::function< void(ILinkSession*) >;
/// handles close of all sessions with pubkey
using SessionClosedHandler = std::function< void(llarp::RouterID) >;
struct ILinkLayer
{
ILinkLayer(const byte_t* routerEncSecret, GetRCFunc getrc,
LinkMessageHandler handler, SignBufferFunc signFunc,
SessionEstablishedHandler sessionEstablish,
TimeoutHandler timeout, SessionClosedHandler closed);
virtual ~ILinkLayer();
/// get current time via event loop
llarp_time_t
now() const
Now() const
{
return llarp_ev_loop_time_now_ms(m_Loop);
}
bool
HasSessionTo(const byte_t* pk);
@ -102,20 +125,35 @@ namespace llarp
const byte_t*
TransportPubKey() const;
const byte_t*
RouterEncryptionSecret() const
{
return m_RouterEncSecret;
}
const byte_t*
TransportSecretKey() const;
bool
EnsureKeys(const char* fpath);
bool
GenEphemeralKeys();
void
MapAddr(const byte_t* pk, ILinkSession* s);
virtual void
Tick(__attribute__((unused)) llarp_time_t now)
virtual void Tick(llarp_time_t)
{
}
LinkMessageHandler HandleMessage;
TimeoutHandler HandleTimeout;
SignBufferFunc Sign;
GetRCFunc GetOurRC;
SessionEstablishedHandler SessionEstablished;
SessionClosedHandler SessionClosed;
private:
static void
on_timer_tick(void* user, uint64_t orig, uint64_t left)
@ -133,6 +171,7 @@ namespace llarp
ScheduleTick(uint64_t interval);
uint32_t tick_id;
const byte_t* m_RouterEncSecret;
protected:
using Lock = util::NullLock;

@ -43,14 +43,21 @@ namespace llarp
/// get remote public identity key
std::function< const byte_t *(void) > GetPubKey;
/// get remote address
std::function< const Addr &(void) > GetRemoteEndpoint;
// get remote rc
std::function< const llarp::RouterContact &(void) > GetRemoteRC;
/// handle a valid LIM
std::function< bool(const LinkIntroMessage *msg) > GotLIM;
/// send queue current blacklog
std::function< size_t(void) > SendQueueBacklog;
/// get parent link layer
std::function< ILinkLayer *(void) > GetLinkLayer;
};
} // namespace llarp

File diff suppressed because it is too large Load Diff

@ -2,17 +2,24 @@
#define LLARP_LINK_UTP_HPP
#include <memory>
#include <link/server.hpp>
namespace llarp
{
struct ILinkLayer;
struct Router;
namespace utp
{
std::unique_ptr< ILinkLayer >
NewServer(llarp::Router* r);
}
NewServer(llarp::Crypto* crypto, const byte_t* routerEncSecret,
llarp::GetRCFunc getrc, llarp::LinkMessageHandler h,
llarp::SessionEstablishedHandler est, llarp::SignBufferFunc sign,
llarp::TimeoutHandler timeout,
llarp::SessionClosedHandler closed);
std::unique_ptr< ILinkLayer >
NewServerFromRouter(llarp::Router* r);
} // namespace utp
} // namespace llarp
#endif

@ -0,0 +1,335 @@
#ifndef LLARP_LINK_UTP_INTERNAL_HPP
#define LLARP_LINK_UTP_INTERNAL_HPP
#include <link/utp.hpp>
#include <utp.h>
#include <aligned.hpp>
#include <link_layer.hpp>
#include <tuple>
#include <deque>
namespace llarp
{
namespace utp
{
/// size of keyed hash
constexpr size_t FragmentHashSize = 32;
/// size of outer nonce
constexpr size_t FragmentNonceSize = 32;
/// size of outer overhead
constexpr size_t FragmentOverheadSize =
FragmentHashSize + FragmentNonceSize;
/// max fragment payload size
constexpr size_t FragmentBodyPayloadSize = 1024;
/// size of inner nonce
constexpr size_t FragmentBodyNonceSize = 24;
/// size of fragment body overhead
constexpr size_t FragmentBodyOverhead = FragmentBodyNonceSize
+ sizeof(uint32) + sizeof(uint16_t) + sizeof(uint16_t);
/// size of fragment body
constexpr size_t FragmentBodySize =
FragmentBodyOverhead + FragmentBodyPayloadSize;
/// size of fragment
constexpr size_t FragmentBufferSize =
FragmentOverheadSize + FragmentBodySize;
static_assert(FragmentBufferSize == 1120);
/// buffer for a single utp fragment
using FragmentBuffer = llarp::AlignedBuffer< FragmentBufferSize >;
/// maximum size for send queue for a session before we drop
constexpr size_t MaxSendQueueSize = 1024;
/// buffer for a link layer message
using MessageBuffer = llarp::AlignedBuffer< MAX_LINK_MSG_SIZE >;
struct LinkLayer;
/// pending inbound message being received
struct InboundMessage
{
/// timestamp of last activity
llarp_time_t lastActive;
/// the underlying message buffer
MessageBuffer _msg;
/// for accessing message buffer
llarp_buffer_t buffer = llarp::Buffer(_msg);
/// return true if this inbound message can be removed due to expiration
bool
IsExpired(llarp_time_t now) const;
/// append data at ptr of size sz bytes to message buffer
/// increment current position
/// return false if we don't have enough room
/// return true on success
bool
AppendData(const byte_t* ptr, uint16_t sz);
};
struct Session final : public ILinkSession
{
/// remote router's rc
RouterContact remoteRC;
/// underlying socket
utp_socket* sock;
/// link layer parent
LinkLayer* parent;
/// did we get a LIM from the remote yet?
bool gotLIM;
/// remote router's transport pubkey
PubKey remoteTransportPubKey;
/// remote router's transport ip
Addr remoteAddr;
/// rx session key
SharedSecret rxKey;
/// tx session key
SharedSecret txKey;
/// timestamp last active
llarp_time_t lastActive;
/// session timeout (30s)
const static llarp_time_t sessionTimeout = 30 * 1000;
/// send queue for utp
std::deque< utp_iovec > vecq;
/// tx fragment queue
std::deque< FragmentBuffer > sendq;
/// current rx fragment buffer
FragmentBuffer recvBuf;
/// current offset in current rx fragment buffer
size_t recvBufOffset;
/// rx fragment message body
AlignedBuffer< FragmentBodySize > rxFragBody;
/// the next message id for tx
uint32_t m_NextTXMsgID;
/// the next message id for rx
uint32_t m_NextRXMsgID;
/// messages we are recving right now
std::unordered_map< uint32_t, InboundMessage > m_RecvMsgs;
/// are we stalled or nah?
bool stalled = false;
/// mark session as alive
void
Alive();
/// base
Session(LinkLayer* p);
/// outbound
Session(LinkLayer* p, utp_socket* s, const RouterContact& rc,
const AddressInfo& addr);
/// inbound
Session(LinkLayer* p, utp_socket* s, const Addr& remote);
enum State
{
eInitial, // initial state
eConnecting, // we are connecting
eLinkEstablished, // when utp connection is established
eCryptoHandshake, // crypto handshake initiated
eSessionReady, // session is ready
eClose // utp connection is closed
};
/// get router
// llarp::Router*
// Router();
llarp::Crypto*
Crypto();
/// session state, call EnterState(State) to set
State state;
/// hook for utp for when we have established a connection
void
OnLinkEstablished(LinkLayer* p);
/// switch states
void
EnterState(State st);
Session();
~Session();
/// pump tx queue
void
PumpWrite();
/// verify a fragment buffer and the decrypt it
/// buf is assumed to be FragmentBufferSize bytes long
bool
VerifyThenDecrypt(const byte_t* buf);
/// encrypt a fragment then hash the ciphertext
bool
EncryptThenHash(const byte_t* ptr, uint32_t msgid, uint16_t sz,
uint16_t remain);
/// queue a fully formed message
bool
QueueWriteBuffers(llarp_buffer_t buf);
/// prune expired inbound messages
void
PruneInboundMessages(llarp_time_t now);
/// do low level connect
void
Connect();
/// handle outbound connection made
void
OutboundLinkEstablished(LinkLayer* p);
// send first message
void
OutboundHandshake();
// do key exchange for handshake
bool
DoKeyExchange(transport_dh_func dh, SharedSecret& K,
const KeyExchangeNonce& n, const PubKey& other,
const byte_t* secret);
/// does K = HS(K + A)
bool
MutateKey(SharedSecret& K, const AlignedBuffer< 24 >& A);
void
TickImpl(llarp_time_t now);
/// close session
void
Close();
/// low level read
bool
Recv(const byte_t* buf, size_t sz);
/// handle inbound LIM
bool
InboundLIM(const LinkIntroMessage* msg);
/// handle outbound LIM
bool
OutboundLIM(const LinkIntroMessage* msg);
/// return true if timed out
bool
IsTimedOut(llarp_time_t now) const;
/// get remote identity pubkey
const PubKey&
RemotePubKey() const;
/// get remote address
const Addr&
RemoteEndpoint() const;
/// get remote rc
const RouterContact&
RemoteRC() const;
/// get parent link
ILinkLayer*
GetParent();
void
MarkEstablished();
};
struct LinkLayer final : public ILinkLayer
{
utp_context* _utp_ctx = nullptr;
llarp::Crypto* _crypto = nullptr;
// low level read callback
static uint64
OnRead(utp_callback_arguments* arg);
// low level sendto callback
static uint64
SendTo(utp_callback_arguments* arg);
/// error callback
static uint64
OnError(utp_callback_arguments* arg);
/// state change callback
static uint64
OnStateChange(utp_callback_arguments*);
/// accept callback
static uint64
OnAccept(utp_callback_arguments*);
/// logger callback
static uint64
OnLog(utp_callback_arguments* arg);
/// construct
LinkLayer(llarp::Crypto* crypto, const byte_t* routerEncSecret,
llarp::GetRCFunc getrc, llarp::LinkMessageHandler h,
llarp::SignBufferFunc sign,
llarp::SessionEstablishedHandler established,
llarp::TimeoutHandler timeout,
llarp::SessionClosedHandler closed);
/// destruct
~LinkLayer();
/// get AI rank
uint16_t
Rank() const;
/// handle low level recv
void
RecvFrom(const Addr& from, const void* buf, size_t sz);
#ifdef __linux__
/// process ICMP stuff on linux
void
ProcessICMP();
#endif
llarp::Crypto*
Crypto();
/// pump sessions
void
Pump();
/// stop link layer
void
Stop();
/// rengenerate transport keypair
bool
KeyGen(SecretKey& k);
/// do tick
void
Tick(llarp_time_t now);
/// create new outbound session
ILinkSession*
NewOutboundSession(const RouterContact& rc, const AddressInfo& addr);
/// create new socket
utp_socket*
NewSocket();
/// get ai name
const char*
Name() const;
};
} // namespace utp
} // namespace llarp
#endif

@ -122,7 +122,8 @@ namespace llarp
}
bool
LinkIntroMessage::Sign(llarp::Crypto* c, const SecretKey& k)
LinkIntroMessage::Sign(
std::function< bool(Signature&, llarp_buffer_t) > signer)
{
Z.Zero();
byte_t tmp[MaxSize] = {0};
@ -131,7 +132,7 @@ namespace llarp
return false;
buf.sz = buf.cur - buf.base;
buf.cur = buf.base;
return c->sign(Z, k, buf);
return signer(Z, buf);
}
bool

@ -9,11 +9,10 @@ namespace llarp
{
class Logic
{
private:
public:
struct llarp_threadpool* thread;
struct llarp_timer_context* timer;
public:
Logic()
: thread(llarp_init_same_process_threadpool())
, timer(llarp_init_timer())

@ -40,7 +40,7 @@ namespace llarp
HandleMessage(llarp::Router* router) const;
bool
Sign(llarp::Crypto* c, const SecretKey& signKeySecret);
Sign(std::function< bool(Signature&, llarp_buffer_t) > signer);
bool
Verify(llarp::Crypto* c) const;

@ -179,10 +179,9 @@ llarp_findOrCreateEncryption(llarp::Crypto *crypto, const char *fpath,
namespace llarp
{
void
Router::HandleLinkSessionEstablished(llarp::RouterContact rc,
llarp::ILinkLayer *link)
Router::OnSessionEstablished(llarp::ILinkSession *session)
{
async_verify_RC(rc, link);
async_verify_RC(session->GetRemoteRC(), session->GetLinkLayer());
}
Router::Router(struct llarp_threadpool *_tp, struct llarp_ev_loop *_netloop,
@ -591,9 +590,9 @@ namespace llarp
}
void
Router::OnConnectTimeout(const llarp::RouterID &remote)
Router::OnConnectTimeout(ILinkSession *session)
{
auto itr = pendingEstablishJobs.find(remote);
auto itr = pendingEstablishJobs.find(session->GetPubKey());
if(itr != pendingEstablishJobs.end())
{
itr->second->AttemptTimedout();
@ -691,6 +690,12 @@ namespace llarp
rpcCaller->Tick(now);
}
bool
Router::Sign(llarp::Signature &sig, llarp_buffer_t buf) const
{
return crypto.sign(sig, identity, buf);
}
void
Router::SendTo(llarp::RouterID remote, const llarp::ILinkMessage *msg,
llarp::ILinkLayer *selected)
@ -735,7 +740,7 @@ namespace llarp
}
void
Router::SessionClosed(const llarp::RouterID &remote)
Router::SessionClosed(llarp::RouterID remote)
{
__llarp_dht_remove_peer(dht, remote);
// remove from valid routers if it's a valid router
@ -1088,7 +1093,7 @@ namespace llarp
if(outboundLink)
return true;
auto link = llarp::utp::NewServer(this);
auto link = llarp::utp::NewServerFromRouter(this);
if(!link->EnsureKeys(transport_keyfile.string().c_str()))
{
@ -1189,7 +1194,7 @@ namespace llarp
{
if(!StrEq(key, "*"))
{
auto server = llarp::utp::NewServer(self);
auto server = llarp::utp::NewServerFromRouter(self);
if(!server->EnsureKeys(self->transport_keyfile.string().c_str()))
{
llarp::LogError("failed to ensure keyfile ", self->transport_keyfile);

@ -89,6 +89,9 @@ namespace llarp
llarp_threadpool *disk;
llarp_dht_context *dht = nullptr;
bool
Sign(Signature &sig, llarp_buffer_t buf) const;
llarp_nodedb *nodedb;
// buffer for serializing link messages
@ -188,7 +191,7 @@ namespace llarp
~Router();
void
HandleLinkSessionEstablished(llarp::RouterContact, llarp::ILinkLayer *);
OnSessionEstablished(llarp::ILinkSession *from);
bool
HandleRecvLinkMessageBuffer(llarp::ILinkSession *from, llarp_buffer_t msg);
@ -254,7 +257,7 @@ namespace llarp
}
void
OnConnectTimeout(const llarp::RouterID &remote);
OnConnectTimeout(ILinkSession *session);
bool
HasPendingConnectJob(const llarp::RouterID &remote);
@ -305,9 +308,9 @@ namespace llarp
void
FlushOutbound();
/// called by link when a remote session is expunged
/// called by link when a remote session has no more sessions open
void
SessionClosed(const llarp::RouterID &remote);
SessionClosed(RouterID remote);
/// call internal router ticker
void

@ -12,6 +12,8 @@
namespace llarp
{
bool RouterContact::IgnoreBogons = false;
bool
RouterContact::BEncode(llarp_buffer_t *buf) const
{
@ -169,7 +171,7 @@ namespace llarp
{
for(const auto &a : addrs)
{
if(IsBogon(a.ip))
if(IsBogon(a.ip) && !IgnoreBogons)
{
llarp::LogError("invalid address info: ", a);
return false;

@ -15,6 +15,9 @@ namespace llarp
{
struct RouterContact final : public IBEncodeMessage
{
/// for unit tests
static bool IgnoreBogons;
RouterContact() : IBEncodeMessage()
{
Clear();
@ -51,6 +54,14 @@ namespace llarp
bool
BEncode(llarp_buffer_t *buf) const override;
bool
operator==(const RouterContact &other) const
{
return addrs == other.addrs && enckey == other.enckey
&& pubkey == other.pubkey && signature == other.signature
&& nickname == other.nickname && last_updated == other.last_updated;
}
void
Clear();

@ -0,0 +1,235 @@
#include <gtest/gtest.h>
#include <link/utp_internal.hpp>
#include <messages/link_intro.hpp>
#include <messages/discard.hpp>
#include <ev.h>
struct UTPTest : public ::testing::Test
{
using Link_t = llarp::utp::LinkLayer;
static constexpr uint16_t AlicePort = 5000;
static constexpr uint16_t BobPort = 6000;
struct Context
{
Context(llarp::Crypto& c)
{
crypto = &c;
crypto->identity_keygen(signingKey);
crypto->encryption_keygen(encryptionKey);
rc.pubkey = llarp::seckey_topublic(signingKey);
rc.enckey = llarp::seckey_topublic(encryptionKey);
}
llarp::SecretKey signingKey;
llarp::SecretKey encryptionKey;
llarp::RouterContact rc;
llarp::Crypto* crypto;
bool gotLIM = false;
const llarp::RouterContact&
GetRC() const
{
return rc;
}
llarp::RouterID
GetRouterID() const
{
return rc.pubkey;
}
std::unique_ptr< Link_t > link;
bool
Start(llarp::Logic* logic, llarp_ev_loop* loop, uint16_t port)
{
if(!link->Configure(loop, "lo", AF_INET, port))
return false;
if(!link->GenEphemeralKeys())
return false;
rc.addrs.emplace_back();
if(!link->GetOurAddressInfo(rc.addrs[0]))
return false;
if(!rc.Sign(crypto, signingKey))
return false;
return link->Start(logic);
}
void
Stop()
{
link->Stop();
}
void
TearDown()
{
Stop();
link.reset();
}
};
llarp::Crypto crypto;
Context Alice;
Context Bob;
bool success = false;
llarp_ev_loop* netLoop;
std::unique_ptr< llarp::Logic > logic;
UTPTest()
: crypto(llarp::Crypto::sodium{})
, Alice(crypto)
, Bob(crypto)
, netLoop(nullptr)
{
}
void
SetUp()
{
llarp::RouterContact::IgnoreBogons = true;
llarp_ev_loop_alloc(&netLoop);
logic.reset(new llarp::Logic());
}
void
TearDown()
{
Alice.TearDown();
Bob.TearDown();
logic.reset();
llarp_ev_loop_free(&netLoop);
llarp::RouterContact::IgnoreBogons = false;
}
static void
OnTimeout(void* u, uint64_t, uint64_t left)
{
if(left)
return;
static_cast< UTPTest* >(u)->Stop();
}
void
RunMainloop()
{
logic->call_later({5000, this, &OnTimeout});
llarp_ev_loop_run_single_process(netLoop, logic->thread, logic.get());
}
void
Stop()
{
llarp_ev_loop_stop(netLoop);
}
bool AliceGotMessage(llarp_buffer_t)
{
success = true;
return true;
}
bool BobGotMessage(llarp_buffer_t)
{
success = true;
return true;
}
};
TEST_F(UTPTest, TestAliceAndBob)
{
Alice.link.reset(new Link_t(
&crypto, Alice.encryptionKey,
[&]() -> const llarp::RouterContact& { return Alice.GetRC(); },
[&](llarp::ILinkSession* s, llarp_buffer_t buf) -> bool {
if(Alice.gotLIM)
{
return AliceGotMessage(buf);
}
else
{
llarp::LinkIntroMessage msg;
if(!msg.BDecode(&buf))
return false;
if(!s->GotLIM(&msg))
return false;
Alice.gotLIM = true;
return true;
}
},
[&](llarp::Signature& sig, llarp_buffer_t buf) -> bool {
return crypto.sign(sig, Alice.signingKey, buf);
},
[&](llarp::ILinkSession* session) {
ASSERT_EQ(session->GetRemoteRC(), Bob.GetRC());
llarp::DiscardMessage msg;
byte_t tmp[32] = {0};
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
ASSERT_TRUE(msg.BEncode(&buf));
buf.sz = buf.cur - buf.base;
buf.cur = buf.base;
ASSERT_TRUE(session->SendMessageBuffer(buf));
ASSERT_TRUE(session->SendMessageBuffer(buf));
},
[&](llarp::ILinkSession* session) {
ASSERT_FALSE(session->IsEstablished());
Stop();
},
[&](llarp::RouterID router) { ASSERT_EQ(router, Bob.GetRouterID()); }));
Bob.link.reset(new Link_t(
&crypto, Bob.encryptionKey,
[&]() -> const llarp::RouterContact& { return Bob.GetRC(); },
[&](llarp::ILinkSession* s, llarp_buffer_t buf) -> bool {
if(Bob.gotLIM)
{
return BobGotMessage(buf);
}
else
{
llarp::LinkIntroMessage msg;
if(!msg.BDecode(&buf))
return false;
if(!s->GotLIM(&msg))
return false;
Bob.gotLIM = true;
return true;
}
},
[&](llarp::Signature& sig, llarp_buffer_t buf) -> bool {
return crypto.sign(sig, Bob.signingKey, buf);
},
[&](llarp::ILinkSession* session) {
ASSERT_EQ(session->GetRemoteRC(), Alice.GetRC());
llarp::DiscardMessage msg;
byte_t tmp[32] = {0};
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
ASSERT_TRUE(msg.BEncode(&buf));
buf.sz = buf.cur - buf.base;
buf.cur = buf.base;
ASSERT_TRUE(session->SendMessageBuffer(buf));
ASSERT_TRUE(session->SendMessageBuffer(buf));
},
[&](llarp::ILinkSession* session) {
ASSERT_FALSE(session->IsEstablished());
},
[&](llarp::RouterID router) { ASSERT_EQ(router, Alice.GetRouterID()); }));
ASSERT_TRUE(Alice.Start(logic.get(), netLoop, AlicePort));
ASSERT_TRUE(Bob.Start(logic.get(), netLoop, BobPort));
ASSERT_TRUE(Alice.link->TryEstablishTo(Bob.GetRC()));
RunMainloop();
ASSERT_TRUE(Alice.gotLIM);
ASSERT_TRUE(Bob.gotLIM);
ASSERT_TRUE(success);
}
Loading…
Cancel
Save