Reorganise tests to mirror source layout

pull/213/head
Michael 5 years ago
parent d1778e20d8
commit fa2b466ffe
No known key found for this signature in database
GPG Key ID: 2D51757B47E2434C

@ -511,7 +511,6 @@ set(LIB_SRC
llarp/encrypted_ack.cpp
llarp/encrypted_frame.cpp
llarp/establish_job.cpp
llarp/exit.cpp
llarp/exit/close_exit.cpp
llarp/exit/context.cpp
llarp/exit/endpoint.cpp
@ -573,7 +572,6 @@ set(LIB_SRC
llarp/routing/path_transfer.cpp
llarp/routing_endpoint.cpp
llarp/rpc.cpp
llarp/service.cpp
llarp/service/Identity.cpp
llarp/service/Intro.cpp
llarp/service/IntroSet.cpp
@ -608,30 +606,29 @@ set(DNS_SRC
)
set(TEST_SRC
test/base32_unittest.cpp
test/dht_unittest.cpp
test/encrypted_frame_unittest.cpp
test/exit_unittest.cpp
test/hiddenservice_unittest.cpp
test/dht/test_llarp_dht.cpp
test/dns/test_llarp_dns_dns.cpp
test/exit/test_llarp_exit_context.cpp
test/link/test_llarp_link.cpp
test/main.cpp
test/net_unittest.cpp
test/obtain_exit_unittest.cpp
test/pq_unittest.cpp
test/net_unittest.cpp
test/link_layer_unittest.cpp
test/test_dns_unit.cpp
test/test_dnsc_unit.cpp
test/test_dnsd_unit.cpp
test/test_dnslib.cpp
test/test_llarp_aligned.cpp
test/test_llarp_bencode.cpp
test/routing/llarp_routing_transfer_traffic.cpp
test/routing/test_llarp_routing_obtainexitmessage.cpp
test/service/test_llarp_service_address.cpp
test/service/test_llarp_service_identity.cpp
test/test_llarp_crypto.cpp
test/test_llarp_dht_key.cpp
test/test_llarp_queue_manager.cpp
test/test_llarp_queue.cpp
test/test_llarp_thread_pool.cpp
test/test_router_contact.cpp
test/test_service_address.cpp
test/traffic_transfer_unittest.cpp
test/test_llarp_dns.cpp
test/test_llarp_dnsd.cpp
test/test_llarp_encrypted_frame.cpp
test/test_llarp_net_inaddr.cpp
test/test_llarp_net.cpp
test/test_llarp_router_contact.cpp
test/util/test_llarp_util_aligned.cpp
test/util/test_llarp_util_bencode.cpp
test/util/test_llarp_util_encode.cpp
test/util/test_llarp_util_queue_manager.cpp
test/util/test_llarp_util_queue.cpp
test/util/test_llarp_util_thread_pool.cpp
)
set(TEST_EXE testAll)
@ -674,7 +671,7 @@ else()
target_link_libraries(${ABYSS_EXE} ${UTIL_LIB} ${PLATFORM_LIB} ws2_32 iphlpapi)
endif(NOT WIN32)
set(TEST_SRC ${TEST_SRC} test/jsonrpc_unittest.cpp)
set(TEST_SRC ${TEST_SRC} test/test_libabyss.cpp)
# for freebsd
if(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
include_directories(/usr/local/include)

@ -1,8 +1,7 @@
#ifndef LLARP_HPP
#define LLARP_HPP
#include <crypto.h>
#include <llarp.h>
#include <crypto.hpp>
#include <util/threading.hpp>
#include <iostream>
@ -12,9 +11,16 @@
struct llarp_config;
struct llarp_config_iterator;
struct llarp_ev_loop;
struct llarp_nodedb;
struct llarp_nodedb_iter;
namespace llarp
{
class Logic;
struct Router;
struct RouterContact;
struct Context
{
~Context();
@ -40,7 +46,7 @@ namespace llarp
LoadDatabase();
int
IterateDatabase(struct llarp_nodedb_iter i);
IterateDatabase(llarp_nodedb_iter &i);
bool
PutDatabase(struct llarp::RouterContact &rc);

@ -1,7 +1,6 @@
#ifndef LLARP_AI_HPP
#define LLARP_AI_HPP
#include <crypto.h>
#include <crypto.hpp>
#include <net.h>
#include <util/bencode.hpp>

@ -1,11 +1,15 @@
#include <llarp.hpp>
#include <llarp.h>
#include <dht/context.hpp>
#include <dns_dotlokilookup.hpp>
#include <dnsd.hpp>
#include <ev.hpp>
#include <getopt.h>
#include <llarp.h>
#include <llarp.hpp>
#include <util/logger.h>
#include <router.hpp>
#include <nodedb.hpp>
#include <getopt.h>
#include <signal.h>
#include <sys/param.h> // for MIN
@ -103,7 +107,7 @@ namespace llarp
}
int
Context::IterateDatabase(struct llarp_nodedb_iter i)
Context::IterateDatabase(llarp_nodedb_iter &i)
{
return nodedb->iterate_all(i);
}

@ -1,6 +0,0 @@
#ifndef LLARP_CRYPTO_H_
#define LLARP_CRYPTO_H_
#ifdef __cplusplus
#include "crypto.hpp"
#endif
#endif

@ -13,7 +13,7 @@
#include <stdint.h>
/**
* crypto.h
* crypto.hpp
*
* libsodium abstraction layer
* potentially allow libssl support in the future

@ -1,4 +1,3 @@
#include <crypto.h>
#include <crypto.hpp>
#include <sodium/crypto_generichash.h>
#include <sodium/crypto_sign.h>

@ -1,5 +0,0 @@
#include <dht/context.hpp>
#include <dht/key.hpp>
#include <dht/message.hpp>
#include <dht/messages/all.hpp>
#include <dht/node.hpp>

@ -1,10 +1,7 @@
#ifndef LLARP_DNS_DNS_HPP
#define LLARP_DNS_DNS_HPP
#include <dns/name.hpp>
#include <dns/rr.hpp>
#include <dns/serialize.hpp>
#include <dns/message.hpp>
#include <dns/server.hpp>
#include <stdint.h>
namespace llarp
{

@ -1,7 +1,7 @@
#ifndef LLARP_ENCRYPTED_FRAME_HPP
#define LLARP_ENCRYPTED_FRAME_HPP
#include <crypto.h>
#include <crypto.hpp>
#include <encrypted.hpp>
#include <util/buffer.hpp>
#include <util/mem.h>

@ -1 +0,0 @@
#include <exit.hpp>

@ -1,6 +0,0 @@
#ifndef LLARP_EXIT_HPP
#define LLARP_EXIT_HPP
#include <exit/context.hpp>
#include <exit/policy.hpp>
#include <exit/session.hpp>
#endif

@ -1,98 +0,0 @@
#ifndef LLARP_XI_H
#define LLARP_XI_H
#include <buffer.h>
#include <crypto.h>
#include <net.h>
#ifdef __cplusplus
#include <bits.hpp>
#include <iostream>
#include <string>
#endif
/**
* exit_info.h
*
* utilities for handling exits on the llarp network
*/
struct llarp_xi;
bool
llarp_xi_bdecode(struct llarp_xi *xi, llarp_buffer_t *buf);
bool
llarp_xi_bencode(const struct llarp_xi *xi, llarp_buffer_t *buf);
/// Exit info model
struct llarp_xi
{
struct in6_addr address;
struct in6_addr netmask;
byte_t pubkey[PUBKEYSIZE];
#ifdef __cplusplus
bool
BEncode(llarp_buffer_t *buf) const
{
return llarp_xi_bencode(this, buf);
}
bool
BDecode(llarp_buffer_t *buf)
{
return llarp_xi_bdecode(this, buf);
}
friend std::ostream &
operator<<(std::ostream &out, const llarp_xi &xi)
{
char tmp[128] = {0};
if(inet_ntop(AF_INET6, (void *)&xi.address, tmp, sizeof(tmp)))
out << std::string(tmp);
else
return out;
out << std::string("/");
return out << std::to_string(
llarp::bits::count_array_bits(xi.netmask.s6_addr));
}
#endif
};
struct llarp_xi_list;
struct llarp_xi_list *
llarp_xi_list_new();
void
llarp_xi_list_free(struct llarp_xi_list *l);
bool
llarp_xi_list_bdecode(struct llarp_xi_list *l, llarp_buffer_t *buf);
bool
llarp_xi_list_bencode(struct llarp_xi_list *l, llarp_buffer_t *buf);
void
llarp_xi_list_pushback(struct llarp_xi_list *l, struct llarp_xi *xi);
void
llarp_xi_list_copy(struct llarp_xi_list *dst, struct llarp_xi_list *src);
size_t
llarp_xi_list_size(const struct llarp_xi_list *l);
void
llarp_xi_copy(struct llarp_xi *dst, struct llarp_xi *src);
struct llarp_xi_list_iter
{
void *user;
struct llarp_xi_list *list;
bool (*visit)(struct llarp_xi_list_iter *, struct llarp_xi *);
};
void
llarp_xi_list_iterate(struct llarp_xi_list *l, struct llarp_xi_list_iter *iter);
#endif

@ -1,6 +1,7 @@
#ifndef LLARP_MESSAGES_DHT_HPP
#define LLARP_MESSAGES_DHT_HPP
#include <dht.hpp>
#include <dht/message.hpp>
#include <routing/message.hpp>
#include <vector>
@ -25,13 +26,12 @@ namespace llarp
bool
HandleMessage(IMessageHandler* h, llarp::Router* r) const override;
void
Clear() override
void
Clear() override
{
M.clear();
V = 0;
}
};
} // namespace routing
} // namespace llarp

@ -1,6 +1,7 @@
#ifndef LLARP_MESSAGES_DHT_IMMEDIATE_HPP
#define LLARP_MESSAGES_DHT_IMMEDIATE_HPP
#include <dht.hpp>
#include <dht/message.hpp>
#include <link_message.hpp>
#include <vector>

@ -202,7 +202,7 @@ llarp_nodedb::visit(std::function< bool(const llarp::RouterContact &) > visit)
}
bool
llarp_nodedb::iterate(struct llarp_nodedb_iter &i)
llarp_nodedb::iterate(llarp_nodedb_iter &i)
{
i.index = 0;
llarp::util::Lock lock(access);

@ -1,7 +1,7 @@
#ifndef LLARP_NODEDB_HPP
#define LLARP_NODEDB_HPP
#include <crypto.h>
#include <crypto.hpp>
#include <router_contact.hpp>
#include <router_id.hpp>
#include <util/common.hpp>
@ -82,7 +82,7 @@ struct llarp_nodedb
visit(std::function< bool(const llarp::RouterContact &) > visit);
bool
iterate(struct llarp_nodedb_iter &i);
iterate(llarp_nodedb_iter &i);
void
set_dir(const char *dir);

@ -2,7 +2,6 @@
#define LLARP_PATH_HPP
#include <crypto.hpp>
#include <dht.hpp>
#include <messages/relay_commit.hpp>
#include <messages/relay.hpp>
#include <path_types.hpp>

@ -1,8 +1,8 @@
#ifndef LLARP_PATH_TYPES_HPP
#define LLARP_PATH_TYPES_HPP
#include <crypto.hpp>
#include <util/aligned.hpp>
#include <crypto.h>
namespace llarp
{

@ -1,6 +1,6 @@
#ifndef LLARP_POW_HPP
#define LLARP_POW_HPP
#include <crypto.h>
#include <crypto.hpp>
#include <router_id.hpp>
#include <util/bencode.hpp>

@ -2,6 +2,7 @@
#include <constants/proto.hpp>
#include <crypto.hpp>
#include <dht/context.hpp>
#include <link_message.hpp>
#include <link/iwp.hpp>
#include <link/server.hpp>

@ -4,10 +4,9 @@
#include <config.h>
#include <crypto.hpp>
#include <dht.h>
#include <dht.hpp>
#include <establish_job.hpp>
#include <ev.h>
#include <exit.hpp>
#include <exit/context.hpp>
#include <handlers/tun.hpp>
#include <link_layer.hpp>
#include <link_message_parser.hpp>
@ -19,7 +18,7 @@
#include <routing/handler.hpp>
#include <routing/message_parser.hpp>
#include <rpc.hpp>
#include <service.hpp>
#include <service/context.hpp>
#include <util/buffer.h>
#include <util/fs.hpp>
#include <util/mem.hpp>

@ -3,7 +3,7 @@
#include <address_info.hpp>
#include <constants/version.hpp>
#include <crypto.h>
#include <crypto.hpp>
#include <exit_info.hpp>
#include <util/bencode.hpp>

@ -1,7 +1,6 @@
#ifndef LLARP_ROUTING_HANDLER_HPP
#define LLARP_ROUTING_HANDLER_HPP
#include <dht.hpp>
#include <messages/exit.hpp>
#include <messages/path_confirm.hpp>
#include <messages/path_latency.hpp>
@ -19,7 +18,6 @@ namespace llarp
struct IMessageHandler
{
virtual bool
HandleObtainExitMessage(const ObtainExitMessage *msg,
llarp::Router *r) = 0;

@ -1,376 +0,0 @@
#include <service.hpp>
#include <ini.hpp>
#include <util/buffer.hpp>
#include <util/fs.hpp>
namespace llarp
{
namespace service
{
IntroSet::~IntroSet()
{
if(W)
delete W;
}
bool
IntroSet::DecodeKey(llarp_buffer_t key, llarp_buffer_t* buf)
{
bool read = false;
if(!BEncodeMaybeReadDictEntry("a", A, read, key, buf))
return false;
if(llarp_buffer_eq(key, "i"))
{
return BEncodeReadList(I, buf);
}
if(!BEncodeMaybeReadDictEntry("k", K, read, key, buf))
return false;
if(!BEncodeMaybeReadDictEntry("n", topic, read, key, buf))
return false;
if(!BEncodeMaybeReadDictInt("t", T, read, key, buf))
return false;
if(llarp_buffer_eq(key, "w"))
{
if(W)
delete W;
W = new PoW();
return W->BDecode(buf);
}
if(!BEncodeMaybeReadDictInt("v", version, read, key, buf))
return false;
if(!BEncodeMaybeReadDictEntry("z", Z, read, key, buf))
return false;
return read;
}
bool
IntroSet::BEncode(llarp_buffer_t* buf) const
{
if(!bencode_start_dict(buf))
return false;
if(!BEncodeWriteDictEntry("a", A, buf))
return false;
// start introduction list
if(!bencode_write_bytestring(buf, "i", 1))
return false;
if(!BEncodeWriteList(I.begin(), I.end(), buf))
return false;
// end introduction list
// pq pubkey
if(!BEncodeWriteDictEntry("k", K, buf))
return false;
// topic tag
if(topic.ToString().size())
{
if(!BEncodeWriteDictEntry("n", topic, buf))
return false;
}
// Timestamp published
if(!BEncodeWriteDictInt("t", T, buf))
return false;
// write version
if(!BEncodeWriteDictInt("v", version, buf))
return false;
if(W)
{
if(!BEncodeWriteDictEntry("w", *W, buf))
return false;
}
if(!BEncodeWriteDictEntry("z", Z, buf))
return false;
return bencode_end(buf);
}
bool
IntroSet::HasExpiredIntros(llarp_time_t now) const
{
for(const auto& i : I)
if(now >= i.expiresAt)
return true;
return false;
}
bool
IntroSet::IsExpired(llarp_time_t now) const
{
return GetNewestIntroExpiration() < now;
}
Introduction::~Introduction()
{
}
bool
Introduction::DecodeKey(llarp_buffer_t key, llarp_buffer_t* buf)
{
bool read = false;
if(!BEncodeMaybeReadDictEntry("k", router, read, key, buf))
return false;
if(!BEncodeMaybeReadDictInt("l", latency, read, key, buf))
return false;
if(!BEncodeMaybeReadDictEntry("p", pathID, read, key, buf))
return false;
if(!BEncodeMaybeReadDictInt("v", version, read, key, buf))
return false;
if(!BEncodeMaybeReadDictInt("x", expiresAt, read, key, buf))
return false;
return read;
}
bool
Introduction::BEncode(llarp_buffer_t* buf) const
{
if(!bencode_start_dict(buf))
return false;
if(!BEncodeWriteDictEntry("k", router, buf))
return false;
if(latency)
{
if(!BEncodeWriteDictInt("l", latency, buf))
return false;
}
if(!BEncodeWriteDictEntry("p", pathID, buf))
return false;
if(!BEncodeWriteDictInt("v", version, buf))
return false;
if(!BEncodeWriteDictInt("x", expiresAt, buf))
return false;
return bencode_end(buf);
}
void
Introduction::Clear()
{
router.Zero();
pathID.Zero();
latency = 0;
expiresAt = 0;
}
Identity::~Identity()
{
}
bool
Identity::BEncode(llarp_buffer_t* buf) const
{
if(!bencode_start_dict(buf))
return false;
if(!BEncodeWriteDictEntry("e", enckey, buf))
return false;
if(!BEncodeWriteDictEntry("q", pq, buf))
return false;
if(!BEncodeWriteDictEntry("s", signkey, buf))
return false;
if(!BEncodeWriteDictInt("v", version, buf))
return false;
if(!BEncodeWriteDictEntry("x", vanity, buf))
return false;
return bencode_end(buf);
}
bool
Identity::DecodeKey(llarp_buffer_t key, llarp_buffer_t* buf)
{
bool read = false;
if(!BEncodeMaybeReadDictEntry("e", enckey, read, key, buf))
return false;
if(llarp_buffer_eq(key, "q"))
{
llarp_buffer_t str;
if(!bencode_read_string(buf, &str))
return false;
if(str.sz == 3200 || str.sz == 2818)
{
pq = str.base;
return true;
}
else
return false;
}
if(!BEncodeMaybeReadDictEntry("s", signkey, read, key, buf))
return false;
if(!BEncodeMaybeReadDictInt("v", version, read, key, buf))
return false;
if(!BEncodeMaybeReadDictEntry("x", vanity, read, key, buf))
return false;
return read;
}
void
Identity::RegenerateKeys(llarp::Crypto* crypto)
{
crypto->encryption_keygen(enckey);
crypto->identity_keygen(signkey);
pub.Update(llarp::seckey_topublic(enckey),
llarp::seckey_topublic(signkey));
crypto->pqe_keygen(pq);
}
bool
Identity::KeyExchange(path_dh_func dh, SharedSecret& result,
const ServiceInfo& other,
const KeyExchangeNonce& N) const
{
return dh(result, other.EncryptionPublicKey(), enckey, N);
}
bool
Identity::Sign(Crypto* c, Signature& sig, llarp_buffer_t buf) const
{
return c->sign(sig, signkey, buf);
}
bool
Identity::EnsureKeys(const std::string& fname, llarp::Crypto* c)
{
byte_t tmp[4096];
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
std::error_code ec;
// check for file
if(!fs::exists(fname, ec))
{
if(ec)
{
llarp::LogError(ec);
return false;
}
// regen and encode
RegenerateKeys(c);
if(!BEncode(&buf))
return false;
// rewind
buf.sz = buf.cur - buf.base;
buf.cur = buf.base;
// write
std::ofstream f;
f.open(fname, std::ios::binary);
if(!f.is_open())
return false;
f.write((char*)buf.cur, buf.sz);
}
// read file
std::ifstream inf(fname, std::ios::binary);
inf.seekg(0, std::ios::end);
size_t sz = inf.tellg();
inf.seekg(0, std::ios::beg);
if(sz > sizeof(tmp))
return false;
// decode
inf.read((char*)buf.base, sz);
if(!BDecode(&buf))
return false;
ServiceInfo::OptNonce van;
if(!vanity.IsZero())
van = vanity;
// update pubkeys
pub.Update(llarp::seckey_topublic(enckey),
llarp::seckey_topublic(signkey), van);
return true;
}
bool
Identity::SignIntroSet(IntroSet& i, llarp::Crypto* crypto,
llarp_time_t now) const
{
if(i.I.size() == 0)
return false;
// set timestamp
// TODO: round to nearest 1000 ms
i.T = now;
// set service info
i.A = pub;
// set public encryption key
i.K = pq_keypair_to_public(pq);
// zero out signature for signing process
i.Z.Zero();
byte_t tmp[MAX_INTROSET_SIZE];
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
if(!i.BEncode(&buf))
return false;
// rewind and resize buffer
buf.sz = buf.cur - buf.base;
buf.cur = buf.base;
return Sign(crypto, i.Z, buf);
}
bool
IntroSet::Verify(llarp::Crypto* crypto, llarp_time_t now) const
{
byte_t tmp[MAX_INTROSET_SIZE];
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
IntroSet copy;
copy = *this;
copy.Z.Zero();
if(!copy.BEncode(&buf))
return false;
// rewind and resize buffer
buf.sz = buf.cur - buf.base;
buf.cur = buf.base;
if(!A.Verify(crypto, buf, Z))
return false;
// validate PoW
if(W && !W->IsValid(crypto->shorthash, now))
return false;
// valid timestamps
// add max clock skew
now += MAX_INTROSET_TIME_DELTA;
for(const auto& intro : I)
{
if(intro.expiresAt > now
&& intro.expiresAt - now > DEFAULT_PATH_LIFETIME)
{
if(W && intro.expiresAt - W->extendedLifetime > DEFAULT_PATH_LIFETIME)
return false;
else if(W == nullptr)
{
llarp::LogWarn("intro has too high expire time");
return false;
}
}
}
if(IsExpired(now))
{
llarp::LogWarn("introset expired: ", *this);
return false;
}
return true;
}
llarp_time_t
IntroSet::GetNewestIntroExpiration() const
{
llarp_time_t t = 0;
for(const auto& intro : I)
t = std::max(intro.expiresAt, t);
return t;
}
bool
Config::Load(const std::string& fname)
{
ini::Parser parser(fname);
for(const auto& sec : parser.top().ordered_sections)
{
services.push_back({sec->first, sec->second.values});
}
return services.size() > 0;
}
} // namespace service
} // namespace llarp

@ -1,14 +0,0 @@
#ifndef LLARP_SERVICE_HPP
#define LLARP_SERVICE_HPP
#include <service/Identity.hpp>
#include <service/Intro.hpp>
#include <service/IntroSet.hpp>
#include <service/config.hpp>
#include <service/context.hpp>
#include <service/endpoint.hpp>
#include <service/types.hpp>
#include <iostream>
#endif

@ -1 +1,158 @@
#include <service/Identity.hpp>
#include <util/fs.hpp>
namespace llarp
{
namespace service
{
Identity::~Identity()
{
}
bool
Identity::BEncode(llarp_buffer_t* buf) const
{
if(!bencode_start_dict(buf))
return false;
if(!BEncodeWriteDictEntry("e", enckey, buf))
return false;
if(!BEncodeWriteDictEntry("q", pq, buf))
return false;
if(!BEncodeWriteDictEntry("s", signkey, buf))
return false;
if(!BEncodeWriteDictInt("v", version, buf))
return false;
if(!BEncodeWriteDictEntry("x", vanity, buf))
return false;
return bencode_end(buf);
}
bool
Identity::DecodeKey(llarp_buffer_t key, llarp_buffer_t* buf)
{
bool read = false;
if(!BEncodeMaybeReadDictEntry("e", enckey, read, key, buf))
return false;
if(llarp_buffer_eq(key, "q"))
{
llarp_buffer_t str;
if(!bencode_read_string(buf, &str))
return false;
if(str.sz == 3200 || str.sz == 2818)
{
pq = str.base;
return true;
}
else
return false;
}
if(!BEncodeMaybeReadDictEntry("s", signkey, read, key, buf))
return false;
if(!BEncodeMaybeReadDictInt("v", version, read, key, buf))
return false;
if(!BEncodeMaybeReadDictEntry("x", vanity, read, key, buf))
return false;
return read;
}
void
Identity::RegenerateKeys(llarp::Crypto* crypto)
{
crypto->encryption_keygen(enckey);
crypto->identity_keygen(signkey);
pub.Update(llarp::seckey_topublic(enckey),
llarp::seckey_topublic(signkey));
crypto->pqe_keygen(pq);
}
bool
Identity::KeyExchange(path_dh_func dh, SharedSecret& result,
const ServiceInfo& other,
const KeyExchangeNonce& N) const
{
return dh(result, other.EncryptionPublicKey(), enckey, N);
}
bool
Identity::Sign(Crypto* c, Signature& sig, llarp_buffer_t buf) const
{
return c->sign(sig, signkey, buf);
}
bool
Identity::EnsureKeys(const std::string& fname, llarp::Crypto* c)
{
byte_t tmp[4096];
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
std::error_code ec;
// check for file
if(!fs::exists(fname, ec))
{
if(ec)
{
llarp::LogError(ec);
return false;
}
// regen and encode
RegenerateKeys(c);
if(!BEncode(&buf))
return false;
// rewind
buf.sz = buf.cur - buf.base;
buf.cur = buf.base;
// write
std::ofstream f;
f.open(fname, std::ios::binary);
if(!f.is_open())
return false;
f.write((char*)buf.cur, buf.sz);
}
// read file
std::ifstream inf(fname, std::ios::binary);
inf.seekg(0, std::ios::end);
size_t sz = inf.tellg();
inf.seekg(0, std::ios::beg);
if(sz > sizeof(tmp))
return false;
// decode
inf.read((char*)buf.base, sz);
if(!BDecode(&buf))
return false;
ServiceInfo::OptNonce van;
if(!vanity.IsZero())
van = vanity;
// update pubkeys
pub.Update(llarp::seckey_topublic(enckey),
llarp::seckey_topublic(signkey), van);
return true;
}
bool
Identity::SignIntroSet(IntroSet& i, llarp::Crypto* crypto,
llarp_time_t now) const
{
if(i.I.size() == 0)
return false;
// set timestamp
// TODO: round to nearest 1000 ms
i.T = now;
// set service info
i.A = pub;
// set public encryption key
i.K = pq_keypair_to_public(pq);
// zero out signature for signing process
i.Z.Zero();
byte_t tmp[MAX_INTROSET_SIZE];
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
if(!i.BEncode(&buf))
return false;
// rewind and resize buffer
buf.sz = buf.cur - buf.base;
buf.cur = buf.base;
return Sign(crypto, i.Z, buf);
}
} // namespace service
} // namespace llarp

@ -1 +1,59 @@
#include <service/Intro.hpp>
namespace llarp
{
namespace service
{
Introduction::~Introduction()
{
}
bool
Introduction::DecodeKey(llarp_buffer_t key, llarp_buffer_t* buf)
{
bool read = false;
if(!BEncodeMaybeReadDictEntry("k", router, read, key, buf))
return false;
if(!BEncodeMaybeReadDictInt("l", latency, read, key, buf))
return false;
if(!BEncodeMaybeReadDictEntry("p", pathID, read, key, buf))
return false;
if(!BEncodeMaybeReadDictInt("v", version, read, key, buf))
return false;
if(!BEncodeMaybeReadDictInt("x", expiresAt, read, key, buf))
return false;
return read;
}
bool
Introduction::BEncode(llarp_buffer_t* buf) const
{
if(!bencode_start_dict(buf))
return false;
if(!BEncodeWriteDictEntry("k", router, buf))
return false;
if(latency)
{
if(!BEncodeWriteDictInt("l", latency, buf))
return false;
}
if(!BEncodeWriteDictEntry("p", pathID, buf))
return false;
if(!BEncodeWriteDictInt("v", version, buf))
return false;
if(!BEncodeWriteDictInt("x", expiresAt, buf))
return false;
return bencode_end(buf);
}
void
Introduction::Clear()
{
router.Zero();
pathID.Zero();
latency = 0;
expiresAt = 0;
}
}
}

@ -1 +1,161 @@
#include <service/IntroSet.hpp>
#include <path.hpp>
namespace llarp
{
namespace service
{
IntroSet::~IntroSet()
{
if(W)
delete W;
}
bool
IntroSet::DecodeKey(llarp_buffer_t key, llarp_buffer_t* buf)
{
bool read = false;
if(!BEncodeMaybeReadDictEntry("a", A, read, key, buf))
return false;
if(llarp_buffer_eq(key, "i"))
{
return BEncodeReadList(I, buf);
}
if(!BEncodeMaybeReadDictEntry("k", K, read, key, buf))
return false;
if(!BEncodeMaybeReadDictEntry("n", topic, read, key, buf))
return false;
if(!BEncodeMaybeReadDictInt("t", T, read, key, buf))
return false;
if(llarp_buffer_eq(key, "w"))
{
if(W)
delete W;
W = new PoW();
return W->BDecode(buf);
}
if(!BEncodeMaybeReadDictInt("v", version, read, key, buf))
return false;
if(!BEncodeMaybeReadDictEntry("z", Z, read, key, buf))
return false;
return read;
}
bool
IntroSet::BEncode(llarp_buffer_t* buf) const
{
if(!bencode_start_dict(buf))
return false;
if(!BEncodeWriteDictEntry("a", A, buf))
return false;
// start introduction list
if(!bencode_write_bytestring(buf, "i", 1))
return false;
if(!BEncodeWriteList(I.begin(), I.end(), buf))
return false;
// end introduction list
// pq pubkey
if(!BEncodeWriteDictEntry("k", K, buf))
return false;
// topic tag
if(topic.ToString().size())
{
if(!BEncodeWriteDictEntry("n", topic, buf))
return false;
}
// Timestamp published
if(!BEncodeWriteDictInt("t", T, buf))
return false;
// write version
if(!BEncodeWriteDictInt("v", version, buf))
return false;
if(W)
{
if(!BEncodeWriteDictEntry("w", *W, buf))
return false;
}
if(!BEncodeWriteDictEntry("z", Z, buf))
return false;
return bencode_end(buf);
}
bool
IntroSet::HasExpiredIntros(llarp_time_t now) const
{
for(const auto& i : I)
if(now >= i.expiresAt)
return true;
return false;
}
bool
IntroSet::IsExpired(llarp_time_t now) const
{
return GetNewestIntroExpiration() < now;
}
bool
IntroSet::Verify(llarp::Crypto* crypto, llarp_time_t now) const
{
byte_t tmp[MAX_INTROSET_SIZE];
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
IntroSet copy;
copy = *this;
copy.Z.Zero();
if(!copy.BEncode(&buf))
return false;
// rewind and resize buffer
buf.sz = buf.cur - buf.base;
buf.cur = buf.base;
if(!A.Verify(crypto, buf, Z))
return false;
// validate PoW
if(W && !W->IsValid(crypto->shorthash, now))
return false;
// valid timestamps
// add max clock skew
now += MAX_INTROSET_TIME_DELTA;
for(const auto& intro : I)
{
if(intro.expiresAt > now
&& intro.expiresAt - now > DEFAULT_PATH_LIFETIME)
{
if(W && intro.expiresAt - W->extendedLifetime > DEFAULT_PATH_LIFETIME)
return false;
else if(W == nullptr)
{
llarp::LogWarn("intro has too high expire time");
return false;
}
}
}
if(IsExpired(now))
{
llarp::LogWarn("introset expired: ", *this);
return false;
}
return true;
}
llarp_time_t
IntroSet::GetNewestIntroExpiration() const
{
llarp_time_t t = 0;
for(const auto& intro : I)
t = std::max(intro.expiresAt, t);
return t;
}
} // namespace service
} // namespace llarp

@ -1 +1,21 @@
#include <service/config.hpp>
#include <ini.hpp>
namespace llarp
{
namespace service
{
bool
Config::Load(const std::string& fname)
{
ini::Parser parser(fname);
for(const auto& sec : parser.top().ordered_sections)
{
services.push_back({sec->first, sec->second.values});
}
return services.size() > 0;
}
} // namespace service
} // namespace llarp

@ -1,5 +1,7 @@
#include <messages/discard.hpp>
#include <path.hpp>
#include <dht/context.hpp>
#include <messages/discard.hpp>
#include <router.hpp>
#include <routing/handler.hpp>
#include <util/buffer.hpp>

@ -1,5 +1,8 @@
#include <dht/bucket.hpp>
#include <dht/key.hpp>
#include <dht/node.hpp>
#include <gtest/gtest.h>
#include <dht.hpp>
using Key_t = llarp::dht::Key_t;
@ -77,7 +80,7 @@ TEST_F(KademliaDHTTest, TestBucketOperators)
ASSERT_TRUE((one ^ three) == (three ^ one));
};
TEST_F(KademliaDHTTest, TestBucketRandomzied_1000)
TEST_F(KademliaDHTTest, TestBucketRandomized_1000)
{
size_t moreNodes = 100;
while(moreNodes--)

@ -1,6 +1,9 @@
#include <gtest/gtest.h>
#include <dns/dns.hpp>
#include <dns/message.hpp>
#include <dns/name.hpp>
#include <dns/rr.hpp>
#include <net.hpp>
#include <algorithm>

@ -1,6 +1,6 @@
#include <gtest/gtest.h>
#include <exit.hpp>
#include <exit/context.hpp>
#include <router.hpp>
struct ExitTest : public ::testing::Test

@ -1,10 +1,11 @@
#include <gtest/gtest.h>
#include <link/utp.hpp>
#include <link/iwp.hpp>
#include <messages/link_intro.hpp>
#include <messages/discard.hpp>
#include <ev.h>
#include <gtest/gtest.h>
struct LinkLayerTest : public ::testing::Test
{
static constexpr uint16_t AlicePort = 5000;

@ -1,164 +0,0 @@
#include <gtest/gtest.h>
#include <net.hpp>
#include <net_inaddr.hpp>
struct NetTest : public ::testing::Test
{
};
TEST_F(NetTest, TestinAddrFrom4Int)
{
llarp::inAddr test;
test.from4int(127, 0, 0, 1);
char str[INET6_ADDRSTRLEN];
if (inet_ntop(AF_INET, &test._addr, str, INET6_ADDRSTRLEN) == NULL) {
ASSERT_TRUE(false);
}
ASSERT_TRUE(strcmp("127.0.0.1", str) == 0);
}
TEST_F(NetTest, TestinAddrFromStr)
{
llarp::inAddr test;
test.from_char_array("127.0.0.1");
char str[INET6_ADDRSTRLEN];
if (inet_ntop(AF_INET, &test._addr, str, INET6_ADDRSTRLEN) == NULL) {
ASSERT_TRUE(false);
}
ASSERT_TRUE(strcmp("127.0.0.1", str) == 0);
}
TEST_F(NetTest, TestinAddrReset)
{
llarp::inAddr test;
test.from_char_array("127.0.0.1");
test.reset();
char str[INET6_ADDRSTRLEN];
if (inet_ntop(AF_INET, &test._addr, str, INET6_ADDRSTRLEN) == NULL) {
ASSERT_TRUE(false);
}
ASSERT_TRUE(strcmp("0.0.0.0", str) == 0);
}
TEST_F(NetTest, TestinAddrModeSet)
{
llarp::inAddr test;
test.from_char_array("127.0.0.1");
//test.hexDebug();
ASSERT_TRUE(test.isIPv4Mode());
// corrupt it
test._addr.s6_addr[10] = 0xfe;
test._addr.s6_addr[11] = 0xfe;
test.setIPv4Mode();
//test.hexDebug();
ASSERT_TRUE(test.isIPv4Mode());
}
TEST_F(NetTest, TestinAddrSIIT)
{
llarp::inAddr test;
test.from_char_array("127.0.0.1");
test.toSIIT();
//test.hexDebug();
ASSERT_TRUE(llarp::ipv6_is_siit(test._addr));
test.fromSIIT();
//test.hexDebug();
ASSERT_TRUE(!llarp::ipv6_is_siit(test._addr));
}
TEST_F(NetTest, TestinAddrN32)
{
llarp::inAddr test;
test.from_char_array("127.0.0.1");
llarp::nuint32_t netOrder = test.toN32();
llarp::inAddr test2;
test2.fromN32(netOrder);
char str[INET6_ADDRSTRLEN];
if (inet_ntop(AF_INET, &test2._addr, str, INET6_ADDRSTRLEN) == NULL) {
ASSERT_TRUE(false);
}
//printf("[%s]\n", str);
ASSERT_TRUE(strcmp("127.0.0.1", str) == 0);
}
TEST_F(NetTest, TestinAddrH32)
{
llarp::inAddr test;
test.from_char_array("127.0.0.1");
llarp::huint32_t netOrder = test.toH32();
llarp::inAddr test2;
test2.fromH32(netOrder);
char str[INET6_ADDRSTRLEN];
if (inet_ntop(AF_INET, &test2._addr, str, INET6_ADDRSTRLEN) == NULL) {
ASSERT_TRUE(false);
}
//printf("[%s]\n", str);
ASSERT_TRUE(strcmp("127.0.0.1", str) == 0);
}
TEST_F(NetTest, TestRangeContains8)
{
ASSERT_TRUE(llarp::iprange_ipv4(10, 0, 0, 1, 8)
.Contains(llarp::ipaddr_ipv4_bits(10, 40, 11, 6)));
}
TEST_F(NetTest, TestRangeContains24)
{
ASSERT_TRUE(llarp::iprange_ipv4(10, 200, 0, 1, 24)
.Contains(llarp::ipaddr_ipv4_bits(10, 200, 0, 253)));
}
TEST_F(NetTest, TestRangeContainsFail)
{
ASSERT_TRUE(!llarp::iprange_ipv4(192, 168, 0, 1, 24)
.Contains(llarp::ipaddr_ipv4_bits(10, 200, 0, 253)));
}
TEST_F(NetTest, TestIPv4Netmask)
{
ASSERT_TRUE(llarp::netmask_ipv4_bits(8)
== llarp::huint32_t{0xFF000000});
ASSERT_TRUE(llarp::netmask_ipv4_bits(24)
== llarp::huint32_t{0xFFFFFF00});
};
TEST_F(NetTest, TestBogon_10_8)
{
ASSERT_TRUE(llarp::IsIPv4Bogon(llarp::ipaddr_ipv4_bits(10, 40, 11, 6)));
};
TEST_F(NetTest, TestBogon_192_168_16)
{
ASSERT_TRUE(llarp::IsIPv4Bogon(llarp::ipaddr_ipv4_bits(192, 168, 1, 111)));
};
TEST_F(NetTest, TestBogon_DoD_8)
{
ASSERT_TRUE(llarp::IsIPv4Bogon(llarp::ipaddr_ipv4_bits(21, 3, 37, 70)));
};
TEST_F(NetTest, TestBogon_127_8)
{
ASSERT_TRUE(llarp::IsIPv4Bogon(llarp::ipaddr_ipv4_bits(127, 0, 0, 1)));
};
TEST_F(NetTest, TestBogon_0_8)
{
ASSERT_TRUE(llarp::IsIPv4Bogon(llarp::ipaddr_ipv4_bits(0, 0, 0, 0)));
};
TEST_F(NetTest, TestBogon_NonBogon)
{
ASSERT_FALSE(llarp::IsIPv4Bogon(llarp::ipaddr_ipv4_bits(1, 1, 1, 1)));
ASSERT_FALSE(llarp::IsIPv4Bogon(llarp::ipaddr_ipv4_bits(8, 8, 6, 6)));
ASSERT_FALSE(llarp::IsIPv4Bogon(llarp::ipaddr_ipv4_bits(141, 55, 12, 99)));
ASSERT_FALSE(llarp::IsIPv4Bogon(llarp::ipaddr_ipv4_bits(79, 12, 3, 4)));
}

@ -1,6 +1,10 @@
#include <gtest/gtest.h>
#include <service.hpp>
#include <crypto.hpp>
#include <path.hpp>
#include <service/address.hpp>
#include <service/Identity.hpp>
#include <service/IntroSet.hpp>
#include <util/time.hpp>
struct HiddenServiceTest : public ::testing::Test

@ -1,6 +0,0 @@
#include <gtest/gtest.h>
#include <dnsc.hpp>
#include <llarp.h> // for llarp_main_init
#include <logic.hpp> // for threadpool/llarp::Logic
#include <net.hpp> // for llarp::Addr

@ -1,9 +0,0 @@
#include <gtest/gtest.h>
struct DTLSTest : public ::testing::Test
{
};
TEST_F(DTLSTest, TestAliceConnectToBob)
{
}

@ -1,9 +1,10 @@
#include <gtest/gtest.h>
#include <dnsd.hpp>
#include <llarp.h> // for llarp_main_init
#include <logic.hpp> // for threadpool/llarp::Logic
#include <net.hpp> // for llarp::Addr
#include <dnsd.hpp>
unsigned int g_length = 0;
std::string g_result = "";

@ -0,0 +1,65 @@
#include <gtest/gtest.h>
#include <net.hpp>
#include <net_inaddr.hpp>
struct TestNet : public ::testing::Test
{
};
TEST_F(TestNet, TestRangeContains8)
{
ASSERT_TRUE(llarp::iprange_ipv4(10, 0, 0, 1, 8)
.Contains(llarp::ipaddr_ipv4_bits(10, 40, 11, 6)));
}
TEST_F(TestNet, TestRangeContains24)
{
ASSERT_TRUE(llarp::iprange_ipv4(10, 200, 0, 1, 24)
.Contains(llarp::ipaddr_ipv4_bits(10, 200, 0, 253)));
}
TEST_F(TestNet, TestRangeContainsFail)
{
ASSERT_TRUE(!llarp::iprange_ipv4(192, 168, 0, 1, 24)
.Contains(llarp::ipaddr_ipv4_bits(10, 200, 0, 253)));
}
TEST_F(TestNet, TestIPv4Netmask)
{
ASSERT_TRUE(llarp::netmask_ipv4_bits(8) == llarp::huint32_t{0xFF000000});
ASSERT_TRUE(llarp::netmask_ipv4_bits(24) == llarp::huint32_t{0xFFFFFF00});
};
TEST_F(TestNet, TestBogon_10_8)
{
ASSERT_TRUE(llarp::IsIPv4Bogon(llarp::ipaddr_ipv4_bits(10, 40, 11, 6)));
};
TEST_F(TestNet, TestBogon_192_168_16)
{
ASSERT_TRUE(llarp::IsIPv4Bogon(llarp::ipaddr_ipv4_bits(192, 168, 1, 111)));
};
TEST_F(TestNet, TestBogon_DoD_8)
{
ASSERT_TRUE(llarp::IsIPv4Bogon(llarp::ipaddr_ipv4_bits(21, 3, 37, 70)));
};
TEST_F(TestNet, TestBogon_127_8)
{
ASSERT_TRUE(llarp::IsIPv4Bogon(llarp::ipaddr_ipv4_bits(127, 0, 0, 1)));
};
TEST_F(TestNet, TestBogon_0_8)
{
ASSERT_TRUE(llarp::IsIPv4Bogon(llarp::ipaddr_ipv4_bits(0, 0, 0, 0)));
};
TEST_F(TestNet, TestBogon_NonBogon)
{
ASSERT_FALSE(llarp::IsIPv4Bogon(llarp::ipaddr_ipv4_bits(1, 1, 1, 1)));
ASSERT_FALSE(llarp::IsIPv4Bogon(llarp::ipaddr_ipv4_bits(8, 8, 6, 6)));
ASSERT_FALSE(llarp::IsIPv4Bogon(llarp::ipaddr_ipv4_bits(141, 55, 12, 99)));
ASSERT_FALSE(llarp::IsIPv4Bogon(llarp::ipaddr_ipv4_bits(79, 12, 3, 4)));
}

@ -0,0 +1,106 @@
#include <gtest/gtest.h>
#include <net_inaddr.hpp>
struct TestNetInAddr : public ::testing::Test
{
};
TEST_F(TestNetInAddr, TestinAddrFrom4Int)
{
llarp::inAddr test;
test.from4int(127, 0, 0, 1);
char str[INET6_ADDRSTRLEN];
if(inet_ntop(AF_INET, &test._addr, str, INET6_ADDRSTRLEN) == NULL)
{
ASSERT_TRUE(false);
}
ASSERT_TRUE(strcmp("127.0.0.1", str) == 0);
}
TEST_F(TestNetInAddr, TestinAddrFromStr)
{
llarp::inAddr test;
test.from_char_array("127.0.0.1");
char str[INET6_ADDRSTRLEN];
if(inet_ntop(AF_INET, &test._addr, str, INET6_ADDRSTRLEN) == NULL)
{
ASSERT_TRUE(false);
}
ASSERT_TRUE(strcmp("127.0.0.1", str) == 0);
}
TEST_F(TestNetInAddr, TestinAddrReset)
{
llarp::inAddr test;
test.from_char_array("127.0.0.1");
test.reset();
char str[INET6_ADDRSTRLEN];
if(inet_ntop(AF_INET, &test._addr, str, INET6_ADDRSTRLEN) == NULL)
{
ASSERT_TRUE(false);
}
ASSERT_TRUE(strcmp("0.0.0.0", str) == 0);
}
TEST_F(TestNetInAddr, TestinAddrModeSet)
{
llarp::inAddr test;
test.from_char_array("127.0.0.1");
// test.hexDebug();
ASSERT_TRUE(test.isIPv4Mode());
// corrupt it
test._addr.s6_addr[10] = 0xfe;
test._addr.s6_addr[11] = 0xfe;
test.setIPv4Mode();
// test.hexDebug();
ASSERT_TRUE(test.isIPv4Mode());
}
TEST_F(TestNetInAddr, TestinAddrSIIT)
{
llarp::inAddr test;
test.from_char_array("127.0.0.1");
test.toSIIT();
// test.hexDebug();
ASSERT_TRUE(llarp::ipv6_is_siit(test._addr));
test.fromSIIT();
// test.hexDebug();
ASSERT_TRUE(!llarp::ipv6_is_siit(test._addr));
}
TEST_F(TestNetInAddr, TestinAddrN32)
{
llarp::inAddr test;
test.from_char_array("127.0.0.1");
llarp::nuint32_t netOrder = test.toN32();
llarp::inAddr test2;
test2.fromN32(netOrder);
char str[INET6_ADDRSTRLEN];
if(inet_ntop(AF_INET, &test2._addr, str, INET6_ADDRSTRLEN) == NULL)
{
ASSERT_TRUE(false);
}
// printf("[%s]\n", str);
ASSERT_TRUE(strcmp("127.0.0.1", str) == 0);
}
TEST_F(TestNetInAddr, TestinAddrH32)
{
llarp::inAddr test;
test.from_char_array("127.0.0.1");
llarp::huint32_t netOrder = test.toH32();
llarp::inAddr test2;
test2.fromH32(netOrder);
char str[INET6_ADDRSTRLEN];
if(inet_ntop(AF_INET, &test2._addr, str, INET6_ADDRSTRLEN) == NULL)
{
ASSERT_TRUE(false);
}
// printf("[%s]\n", str);
ASSERT_TRUE(strcmp("127.0.0.1", str) == 0);
}

@ -1,16 +1,13 @@
#include <gtest/gtest.h>
#include <crypto.hpp>
#include <util/aligned.hpp>
#include <util/encode.hpp>
#include <util/logger.hpp>
struct Base32Test : public ::testing::Test
{
Base32Test() : crypto(llarp::Crypto::sodium{})
Base32Test()
{
}
llarp::Crypto crypto;
};
TEST_F(Base32Test, Serialize)

@ -1,334 +0,0 @@
#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;
}
/// regenerate rc and rotate onion key
bool
Regen()
{
crypto->encryption_keygen(encryptionKey);
rc.enckey = llarp::seckey_topublic(encryptionKey);
return rc.Sign(crypto, signingKey);
}
std::unique_ptr< ILinkLayer > link;
static std::string
localLoopBack()
{
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) \
|| (__APPLE__ && __MACH__)
return "lo0";
#else
return "lo";
#endif
}
bool
Start(llarp::Logic* logic, llarp_ev_loop* loop, uint16_t port)
{
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(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;
llarp_time_t oldRCLifetime;
std::unique_ptr< llarp::Logic > logic;
UTPTest()
: crypto(llarp::Crypto::sodium{})
, Alice(crypto)
, Bob(crypto)
, netLoop(nullptr)
, oldRCLifetime(llarp::RouterContact::Lifetime)
{
llarp::RouterContact::IgnoreBogons = true;
llarp::RouterContact::Lifetime = 500;
llarp_ev_loop_alloc(&netLoop);
logic.reset(new llarp::Logic());
}
~UTPTest()
{
Alice.TearDown();
Bob.TearDown();
logic.reset();
llarp_ev_loop_free(&netLoop);
llarp::RouterContact::IgnoreBogons = false;
llarp::RouterContact::Lifetime = oldRCLifetime;
}
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;
Stop();
return true;
}
};
TEST_F(UTPTest, TestAliceRenegWithBob)
{
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)
{
Alice.Regen();
return s->RenegotiateSession();
}
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::RouterContact rc) {
ASSERT_EQ(rc, Bob.GetRC());
llarp::LogInfo("alice established with bob");
},
[&](llarp::RouterContact, llarp::RouterContact) -> bool { return true; },
[&](llarp::ILinkSession* session) {
ASSERT_FALSE(session->IsEstablished());
Stop();
},
[&](llarp::RouterID router) { ASSERT_EQ(router, Bob.GetRouterID()); }));
auto sendDiscardMessage = [](llarp::ILinkSession* s) -> bool {
// send discard message in reply to complete unit test
byte_t tmp[32] = {0};
auto otherBuf = llarp::StackBuffer< decltype(tmp) >(tmp);
llarp::DiscardMessage discard;
if(!discard.BEncode(&otherBuf))
return false;
otherBuf.sz = otherBuf.cur - otherBuf.base;
otherBuf.cur = otherBuf.base;
return s->SendMessageBuffer(otherBuf);
};
Bob.link.reset(new Link_t(
&crypto, Bob.encryptionKey,
[&]() -> const llarp::RouterContact& { return Bob.GetRC(); },
[&](llarp::ILinkSession* s, llarp_buffer_t buf) -> bool {
llarp::LinkIntroMessage msg;
if(!msg.BDecode(&buf))
return false;
if(!s->GotLIM(&msg))
return false;
Bob.gotLIM = true;
return sendDiscardMessage(s);
},
[&](llarp::Signature& sig, llarp_buffer_t buf) -> bool {
return crypto.sign(sig, Bob.signingKey, buf);
},
[&](llarp::RouterContact rc) {
ASSERT_EQ(rc, Alice.GetRC());
llarp::LogInfo("bob established with alice");
Bob.link->VisitSessionByPubkey(Alice.GetRC().pubkey.as_array(),
sendDiscardMessage);
},
[&](llarp::RouterContact newrc, llarp::RouterContact oldrc) -> bool {
success = newrc.pubkey == oldrc.pubkey;
return true;
},
[&](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);
}
TEST_F(UTPTest, TestAliceConnectToBob)
{
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::RouterContact rc) {
ASSERT_EQ(rc, Bob.GetRC());
llarp::LogInfo("alice established with bob");
},
[&](llarp::RouterContact, llarp::RouterContact) -> bool { return true; },
[&](llarp::ILinkSession* session) {
ASSERT_FALSE(session->IsEstablished());
Stop();
},
[&](llarp::RouterID router) { ASSERT_EQ(router, Bob.GetRouterID()); }));
auto sendDiscardMessage = [](llarp::ILinkSession* s) -> bool {
// send discard message in reply to complete unit test
byte_t tmp[32] = {0};
auto otherBuf = llarp::StackBuffer< decltype(tmp) >(tmp);
llarp::DiscardMessage discard;
if(!discard.BEncode(&otherBuf))
return false;
otherBuf.sz = otherBuf.cur - otherBuf.base;
otherBuf.cur = otherBuf.base;
return s->SendMessageBuffer(otherBuf);
};
Bob.link.reset(new Link_t(
&crypto, Bob.encryptionKey,
[&]() -> const llarp::RouterContact& { return Bob.GetRC(); },
[&](llarp::ILinkSession* s, llarp_buffer_t buf) -> bool {
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::RouterContact rc) {
ASSERT_EQ(rc, Alice.GetRC());
llarp::LogInfo("bob established with alice");
Bob.link->VisitSessionByPubkey(Alice.GetRC().pubkey.as_array(),
sendDiscardMessage);
},
[&](llarp::RouterContact, llarp::RouterContact) -> bool { return true; },
[&](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