1
1
Fork 0
mirror of https://github.com/oxen-io/lokinet synced 2023-12-14 06:53:00 +01:00
lokinet/test/link/test_llarp_link.cpp

449 lines
12 KiB
C++
Raw Normal View History

2019-08-22 22:53:27 +02:00
#include <crypto/crypto_libsodium.hpp>
2019-01-11 02:19:36 +01:00
#include <ev/ev.h>
2019-03-29 16:17:49 +01:00
#include <iwp/iwp.hpp>
2019-05-28 21:45:09 +02:00
#include <llarp_test.hpp>
2019-08-22 22:53:27 +02:00
#include <iwp/iwp.hpp>
2019-01-05 14:45:05 +01:00
#include <messages/link_intro.hpp>
#include <messages/discard.hpp>
2019-03-29 15:23:19 +01:00
#include <utp/utp.hpp>
2019-01-05 14:45:05 +01:00
2019-08-22 13:18:05 +02:00
2019-05-28 21:45:09 +02:00
#include <test_util.hpp>
#include <gtest/gtest.h>
2019-05-28 21:45:09 +02:00
using namespace ::llarp;
using namespace ::testing;
2019-08-22 22:53:27 +02:00
struct LinkLayerTest : public test::LlarpTest< llarp::sodium::CryptoLibSodium >
2019-01-05 14:45:05 +01:00
{
static constexpr uint16_t AlicePort = 5000;
static constexpr uint16_t BobPort = 6000;
struct Context
{
Context()
2019-01-05 14:45:05 +01:00
{
2019-05-28 21:45:09 +02:00
CryptoManager::instance()->identity_keygen(signingKey);
CryptoManager::instance()->encryption_keygen(encryptionKey);
2019-03-28 20:15:20 +01:00
rc.pubkey = signingKey.toPublic();
rc.enckey = encryptionKey.toPublic();
2019-01-05 14:45:05 +01:00
}
2019-05-28 21:45:09 +02:00
SecretKey signingKey;
SecretKey encryptionKey;
2019-01-05 14:45:05 +01:00
2019-05-28 21:45:09 +02:00
RouterContact rc;
2019-01-05 14:45:05 +01:00
bool gotLIM = false;
2019-05-28 21:45:09 +02:00
const RouterContact&
2019-01-05 14:45:05 +01:00
GetRC() const
{
return rc;
}
2019-05-28 21:45:09 +02:00
RouterID
2019-01-05 14:45:05 +01:00
GetRouterID() const
{
return rc.pubkey;
}
/// regenerate rc and rotate onion key
bool
Regen()
{
2019-05-28 21:45:09 +02:00
CryptoManager::instance()->encryption_keygen(encryptionKey);
rc.enckey = seckey_topublic(encryptionKey);
return rc.Sign(signingKey);
2019-01-05 14:45:05 +01:00
}
2019-05-28 21:45:09 +02:00
std::shared_ptr< ILinkLayer > link;
2019-01-05 14:45:05 +01:00
static std::string
localLoopBack()
{
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) \
2019-08-26 15:44:01 +02:00
|| (__APPLE__ && __MACH__) || (__sun)
2019-01-05 14:45:05 +01:00
return "lo0";
#else
return "lo";
#endif
}
bool
2019-05-28 21:45:09 +02:00
Start(std::shared_ptr< Logic > logic, llarp_ev_loop_ptr loop, uint16_t port)
2019-01-05 14:45:05 +01:00
{
if(!link)
return false;
if(!link->Configure(loop, localLoopBack(), 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(signingKey))
2019-01-05 14:45:05 +01:00
return false;
return link->Start(logic);
}
void
Stop()
{
if(link)
link->Stop();
}
void
TearDown()
{
Stop();
link.reset();
}
};
Context Alice;
Context Bob;
bool success = false;
2019-04-08 14:01:52 +02:00
llarp_ev_loop_ptr netLoop;
2019-05-28 21:45:09 +02:00
std::shared_ptr< Logic > m_logic;
2019-01-05 14:45:05 +01:00
llarp_time_t oldRCLifetime;
2019-05-28 21:45:09 +02:00
LinkLayerTest() : netLoop(nullptr)
2019-01-05 14:45:05 +01:00
{
}
void
SetUp()
{
2019-08-27 01:29:17 +02:00
oldRCLifetime = RouterContact::Lifetime;
RouterContact::BlockBogons = false;
RouterContact::Lifetime = 500;
netLoop = llarp_make_ev_loop();
2019-05-28 21:45:09 +02:00
m_logic.reset(new Logic());
2019-01-05 14:45:05 +01:00
}
void
TearDown()
{
Alice.TearDown();
Bob.TearDown();
2019-04-26 01:21:19 +02:00
m_logic.reset();
2019-04-08 14:01:52 +02:00
netLoop.reset();
2019-08-27 01:29:17 +02:00
RouterContact::BlockBogons = true;
RouterContact::Lifetime = oldRCLifetime;
2019-01-05 14:45:05 +01:00
}
static void
OnTimeout(void* u, uint64_t, uint64_t left)
{
if(left)
return;
2019-06-02 23:17:05 +02:00
llarp::LogInfo("timed out test");
2019-01-05 14:45:05 +01:00
static_cast< LinkLayerTest* >(u)->Stop();
}
void
RunMainloop()
{
2019-04-26 01:21:19 +02:00
m_logic->call_later({5000, this, &OnTimeout});
2019-07-09 15:47:24 +02:00
llarp_ev_loop_run_single_process(netLoop, m_logic);
2019-01-05 14:45:05 +01:00
}
void
Stop()
{
2019-06-02 23:17:05 +02:00
llarp_ev_loop_stop(netLoop);
2019-01-05 14:45:05 +01:00
}
bool
AliceGotMessage(const llarp_buffer_t&)
2019-01-05 14:45:05 +01:00
{
success = true;
Stop();
return true;
}
};
2019-08-22 22:53:27 +02:00
TEST_F(LinkLayerTest, TestIWP)
2019-01-05 14:45:05 +01:00
{
2019-07-19 00:12:14 +02:00
#ifdef WIN32
2019-08-23 22:49:12 +02:00
GTEST_SKIP();
2019-07-19 00:12:14 +02:00
#else
2019-08-22 22:53:27 +02:00
Alice.link = iwp::NewInboundLink(
Alice.encryptionKey,
2019-05-28 21:45:09 +02:00
[&]() -> const RouterContact& { return Alice.GetRC(); },
[&](ILinkSession* s, const llarp_buffer_t& buf) -> bool {
2019-01-05 14:45:05 +01:00
if(Alice.gotLIM)
{
Alice.Regen();
return s->RenegotiateSession();
}
else
{
2019-05-28 21:45:09 +02:00
LinkIntroMessage msg;
2019-02-03 01:48:10 +01:00
ManagedBuffer copy{buf};
2019-02-03 00:12:42 +01:00
if(!msg.BDecode(&copy.underlying))
2019-01-05 14:45:05 +01:00
return false;
if(!s->GotLIM(&msg))
return false;
Alice.gotLIM = true;
return true;
}
},
2019-08-22 13:18:05 +02:00
[&](Signature& sig, const llarp_buffer_t& buf) -> bool {
return m_crypto.sign(sig, Alice.signingKey, buf);
},
2019-05-28 21:45:09 +02:00
[&](ILinkSession* s) -> bool {
2019-02-27 13:55:26 +01:00
const auto rc = s->GetRemoteRC();
return rc.pubkey == Bob.GetRC().pubkey;
2019-01-05 14:45:05 +01:00
},
2019-05-28 21:45:09 +02:00
[&](RouterContact, RouterContact) -> bool { return true; },
2019-08-22 13:18:05 +02:00
[&](ILinkSession* session) {
ASSERT_FALSE(session->IsEstablished());
Stop();
},
[&](RouterID router) { ASSERT_EQ(router, Bob.GetRouterID()); });
auto sendDiscardMessage = [](ILinkSession* s) -> bool {
// send discard message in reply to complete unit test
std::array< byte_t, 32 > tmp;
llarp_buffer_t otherBuf(tmp);
DiscardMessage discard;
if(!discard.BEncode(&otherBuf))
return false;
otherBuf.sz = otherBuf.cur - otherBuf.base;
otherBuf.cur = otherBuf.base;
return s->SendMessageBuffer(otherBuf, nullptr);
};
2019-08-22 22:53:27 +02:00
Bob.link = iwp::NewInboundLink(
2019-08-22 13:18:05 +02:00
Bob.encryptionKey, [&]() -> const RouterContact& { return Bob.GetRC(); },
[&](ILinkSession* s, const llarp_buffer_t& buf) -> bool {
LinkIntroMessage msg;
ManagedBuffer copy{buf};
if(!msg.BDecode(&copy.underlying))
return false;
if(!s->GotLIM(&msg))
return false;
Bob.gotLIM = true;
return sendDiscardMessage(s);
},
[&](Signature& sig, const llarp_buffer_t& buf) -> bool {
return m_crypto.sign(sig, Bob.signingKey, buf);
},
[&](ILinkSession* s) -> bool {
if(s->GetRemoteRC().pubkey != Alice.GetRC().pubkey)
return false;
LogInfo("bob established with alice");
return Bob.link->VisitSessionByPubkey(Alice.GetRC().pubkey.as_array(),
sendDiscardMessage);
},
[&](RouterContact newrc, RouterContact oldrc) -> bool {
success = newrc.pubkey == oldrc.pubkey;
return true;
},
[&](ILinkSession* session) { ASSERT_FALSE(session->IsEstablished()); },
[&](RouterID router) { ASSERT_EQ(router, Alice.GetRouterID()); });
ASSERT_TRUE(Alice.Start(m_logic, netLoop, AlicePort));
ASSERT_TRUE(Bob.Start(m_logic, netLoop, BobPort));
ASSERT_TRUE(Alice.link->TryEstablishTo(Bob.GetRC()));
RunMainloop();
ASSERT_TRUE(Bob.gotLIM);
2019-08-23 22:49:12 +02:00
#endif
2019-08-22 13:18:05 +02:00
};
2019-01-05 14:45:05 +01:00
TEST_F(LinkLayerTest, TestUTPAliceRenegWithBob)
{
2019-07-19 00:12:14 +02:00
#ifdef WIN32
GTEST_SKIP();
#else
2019-05-28 21:45:09 +02:00
Alice.link = utp::NewServer(
Alice.encryptionKey,
2019-05-28 21:45:09 +02:00
[&]() -> const RouterContact& { return Alice.GetRC(); },
[&](ILinkSession* s, const llarp_buffer_t& buf) -> bool {
2019-01-05 14:45:05 +01:00
if(Alice.gotLIM)
{
Alice.Regen();
return s->RenegotiateSession();
}
else
{
2019-05-28 21:45:09 +02:00
LinkIntroMessage msg;
2019-02-03 01:48:10 +01:00
ManagedBuffer copy{buf};
2019-02-03 00:12:42 +01:00
if(!msg.BDecode(&copy.underlying))
2019-01-05 14:45:05 +01:00
return false;
if(!s->GotLIM(&msg))
return false;
Alice.gotLIM = true;
return true;
}
},
2019-05-28 21:45:09 +02:00
[&](Signature& sig, const llarp_buffer_t& buf) -> bool {
return m_crypto.sign(sig, Alice.signingKey, buf);
2019-01-05 14:45:05 +01:00
},
2019-05-28 21:45:09 +02:00
[&](ILinkSession* s) -> bool {
2019-02-27 13:55:26 +01:00
const auto rc = s->GetRemoteRC();
return rc.pubkey == Bob.GetRC().pubkey;
2019-01-05 14:45:05 +01:00
},
2019-05-28 21:45:09 +02:00
[&](RouterContact, RouterContact) -> bool { return true; },
2019-08-07 18:33:29 +02:00
2019-05-28 21:45:09 +02:00
[&](ILinkSession* session) {
2019-01-05 14:45:05 +01:00
ASSERT_FALSE(session->IsEstablished());
Stop();
},
2019-05-28 21:45:09 +02:00
[&](RouterID router) { ASSERT_EQ(router, Bob.GetRouterID()); });
2019-01-05 14:45:05 +01:00
2019-05-28 21:45:09 +02:00
auto sendDiscardMessage = [](ILinkSession* s) -> bool {
2019-01-05 14:45:05 +01:00
// send discard message in reply to complete unit test
2019-02-03 00:12:42 +01:00
std::array< byte_t, 32 > tmp;
llarp_buffer_t otherBuf(tmp);
2019-05-28 21:45:09 +02:00
DiscardMessage discard;
2019-01-05 14:45:05 +01:00
if(!discard.BEncode(&otherBuf))
return false;
2019-07-19 00:12:14 +02:00
otherBuf.sz = otherBuf.cur - otherBuf.base;
2019-01-05 14:45:05 +01:00
otherBuf.cur = otherBuf.base;
2019-07-26 18:19:31 +02:00
return s->SendMessageBuffer(otherBuf, nullptr);
2019-01-05 14:45:05 +01:00
};
2019-05-28 21:45:09 +02:00
Bob.link = utp::NewServer(
Bob.encryptionKey, [&]() -> const RouterContact& { return Bob.GetRC(); },
[&](ILinkSession* s, const llarp_buffer_t& buf) -> bool {
LinkIntroMessage msg;
2019-02-03 01:48:10 +01:00
ManagedBuffer copy{buf};
2019-02-03 00:12:42 +01:00
if(!msg.BDecode(&copy.underlying))
2019-01-05 14:45:05 +01:00
return false;
if(!s->GotLIM(&msg))
return false;
Bob.gotLIM = true;
return sendDiscardMessage(s);
},
2019-08-07 18:33:29 +02:00
[&](Signature& sig, const llarp_buffer_t& buf) -> bool {
return m_crypto.sign(sig, Bob.signingKey, buf);
},
2019-05-28 21:45:09 +02:00
[&](ILinkSession* s) -> bool {
2019-02-27 13:55:26 +01:00
if(s->GetRemoteRC().pubkey != Alice.GetRC().pubkey)
return false;
2019-05-28 21:45:09 +02:00
LogInfo("bob established with alice");
2019-02-27 13:55:26 +01:00
return Bob.link->VisitSessionByPubkey(Alice.GetRC().pubkey.as_array(),
2019-03-04 17:31:05 +01:00
sendDiscardMessage);
2019-01-05 14:45:05 +01:00
},
2019-05-28 21:45:09 +02:00
[&](RouterContact newrc, RouterContact oldrc) -> bool {
2019-01-05 14:45:05 +01:00
success = newrc.pubkey == oldrc.pubkey;
return true;
},
2019-05-28 21:45:09 +02:00
[&](ILinkSession* session) { ASSERT_FALSE(session->IsEstablished()); },
[&](RouterID router) { ASSERT_EQ(router, Alice.GetRouterID()); });
2019-01-05 14:45:05 +01:00
ASSERT_TRUE(Alice.Start(m_logic, netLoop, AlicePort));
ASSERT_TRUE(Bob.Start(m_logic, netLoop, BobPort));
2019-01-05 14:45:05 +01:00
ASSERT_TRUE(Alice.link->TryEstablishTo(Bob.GetRC()));
RunMainloop();
ASSERT_TRUE(Bob.gotLIM);
ASSERT_TRUE(success);
2019-07-19 00:12:14 +02:00
#endif
2019-01-05 14:45:05 +01:00
}
TEST_F(LinkLayerTest, TestUTPAliceConnectToBob)
{
2019-07-19 00:12:14 +02:00
#ifdef WIN32
GTEST_SKIP();
#else
2019-05-28 21:45:09 +02:00
Alice.link = utp::NewServer(
Alice.encryptionKey,
2019-05-28 21:45:09 +02:00
[&]() -> const RouterContact& { return Alice.GetRC(); },
[&](ILinkSession* s, const llarp_buffer_t& buf) -> bool {
LinkIntroMessage lim;
2019-03-04 17:31:05 +01:00
llarp_buffer_t copy(buf.base, buf.sz);
if(lim.BDecode(&copy))
{
if(s->GotLIM(&lim))
{
Alice.gotLIM = true;
return true;
}
return false;
}
2019-02-27 13:55:26 +01:00
return AliceGotMessage(buf);
2019-08-07 18:33:29 +02:00
},
[&](Signature& sig, const llarp_buffer_t& buf) -> bool {
return m_crypto.sign(sig, Alice.signingKey, buf);
2019-01-05 14:45:05 +01:00
},
2019-05-28 21:45:09 +02:00
[&](ILinkSession* s) -> bool {
2019-02-27 13:55:26 +01:00
if(s->GetRemoteRC().pubkey != Bob.GetRC().pubkey)
return false;
2019-05-28 21:45:09 +02:00
LogInfo("alice established with bob");
2019-02-27 13:55:26 +01:00
return true;
2019-01-05 14:45:05 +01:00
},
2019-05-28 21:45:09 +02:00
[&](RouterContact, RouterContact) -> bool { return true; },
2019-08-07 18:33:29 +02:00
2019-05-28 21:45:09 +02:00
[&](ILinkSession* session) {
2019-01-05 14:45:05 +01:00
ASSERT_FALSE(session->IsEstablished());
Stop();
},
2019-05-28 21:45:09 +02:00
[&](RouterID router) { ASSERT_EQ(router, Bob.GetRouterID()); });
2019-01-05 14:45:05 +01:00
2019-05-28 21:45:09 +02:00
Bob.link = utp::NewServer(
Bob.encryptionKey, [&]() -> const RouterContact& { return Bob.GetRC(); },
[&](ILinkSession* s, const llarp_buffer_t& buf) -> bool {
LinkIntroMessage lim;
2019-03-04 17:31:05 +01:00
llarp_buffer_t copy(buf.base, buf.sz);
if(lim.BDecode(&copy))
{
if(s->GotLIM(&lim))
{
Bob.gotLIM = true;
return true;
}
return false;
}
2019-01-05 14:45:05 +01:00
return true;
2019-08-07 18:33:29 +02:00
},
[&](Signature& sig, const llarp_buffer_t& buf) -> bool {
return m_crypto.sign(sig, Bob.signingKey, buf);
2019-01-05 14:45:05 +01:00
},
2019-05-28 21:45:09 +02:00
[&](ILinkSession* s) -> bool {
2019-02-27 13:55:26 +01:00
if(s->GetRemoteRC().pubkey != Alice.GetRC().pubkey)
return false;
2019-05-28 21:45:09 +02:00
LogInfo("bob established with alice");
2019-04-26 01:21:19 +02:00
m_logic->queue_job({s, [](void* u) {
2019-05-28 21:45:09 +02:00
ILinkSession* self =
static_cast< ILinkSession* >(u);
2019-04-26 01:21:19 +02:00
std::array< byte_t, 32 > tmp;
llarp_buffer_t otherBuf(tmp);
2019-05-28 21:45:09 +02:00
DiscardMessage discard;
2019-04-26 01:21:19 +02:00
if(!discard.BEncode(&otherBuf))
return;
2019-07-19 00:12:14 +02:00
otherBuf.sz = otherBuf.cur - otherBuf.base;
2019-04-26 01:21:19 +02:00
otherBuf.cur = otherBuf.base;
2019-07-26 18:19:31 +02:00
self->SendMessageBuffer(otherBuf, nullptr);
2019-04-26 01:21:19 +02:00
}});
2019-02-27 13:55:26 +01:00
return true;
2019-01-05 14:45:05 +01:00
},
2019-05-28 21:45:09 +02:00
[&](RouterContact, RouterContact) -> bool { return true; },
[&](ILinkSession* session) { ASSERT_FALSE(session->IsEstablished()); },
[&](RouterID router) { ASSERT_EQ(router, Alice.GetRouterID()); });
2019-01-05 14:45:05 +01:00
ASSERT_TRUE(Alice.Start(m_logic, netLoop, AlicePort));
ASSERT_TRUE(Bob.Start(m_logic, netLoop, BobPort));
2019-01-05 14:45:05 +01:00
ASSERT_TRUE(Alice.link->TryEstablishTo(Bob.GetRC()));
RunMainloop();
ASSERT_TRUE(Bob.gotLIM);
ASSERT_TRUE(success);
2019-07-19 00:12:14 +02:00
#endif
2019-01-05 14:45:05 +01:00
}