mirror of https://github.com/oxen-io/lokinet
Merge pull request #213 from michael-loki/organise_tests
Reorganise tests to mirror source layoutpull/215/head
commit
9c1804b398
@ -1,6 +0,0 @@
|
|||||||
#ifndef LLARP_CRYPTO_H_
|
|
||||||
#define LLARP_CRYPTO_H_
|
|
||||||
#ifdef __cplusplus
|
|
||||||
#include "crypto.hpp"
|
|
||||||
#endif
|
|
||||||
#endif
|
|
@ -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 +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,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 <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>
|
#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 <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 <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,6 +1,9 @@
|
|||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
#include <dns/dns.hpp>
|
#include <dns/dns.hpp>
|
||||||
|
#include <dns/message.hpp>
|
||||||
|
#include <dns/name.hpp>
|
||||||
|
#include <dns/rr.hpp>
|
||||||
#include <net.hpp>
|
#include <net.hpp>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
@ -1,6 +1,6 @@
|
|||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
#include <exit.hpp>
|
#include <exit/context.hpp>
|
||||||
#include <router.hpp>
|
#include <router.hpp>
|
||||||
|
|
||||||
struct ExitTest : public ::testing::Test
|
struct ExitTest : public ::testing::Test
|
@ -1,10 +1,11 @@
|
|||||||
#include <gtest/gtest.h>
|
|
||||||
#include <link/utp.hpp>
|
#include <link/utp.hpp>
|
||||||
#include <link/iwp.hpp>
|
#include <link/iwp.hpp>
|
||||||
#include <messages/link_intro.hpp>
|
#include <messages/link_intro.hpp>
|
||||||
#include <messages/discard.hpp>
|
#include <messages/discard.hpp>
|
||||||
#include <ev.h>
|
#include <ev.h>
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
struct LinkLayerTest : public ::testing::Test
|
struct LinkLayerTest : public ::testing::Test
|
||||||
{
|
{
|
||||||
static constexpr uint16_t AlicePort = 5000;
|
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 <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>
|
#include <util/time.hpp>
|
||||||
|
|
||||||
struct HiddenServiceTest : public ::testing::Test
|
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 <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include <dnsd.hpp>
|
||||||
|
|
||||||
#include <llarp.h> // for llarp_main_init
|
#include <llarp.h> // for llarp_main_init
|
||||||
#include <logic.hpp> // for threadpool/llarp::Logic
|
#include <logic.hpp> // for threadpool/llarp::Logic
|
||||||
#include <net.hpp> // for llarp::Addr
|
#include <net.hpp> // for llarp::Addr
|
||||||
#include <dnsd.hpp>
|
|
||||||
|
|
||||||
unsigned int g_length = 0;
|
unsigned int g_length = 0;
|
||||||
std::string g_result = "";
|
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 <gtest/gtest.h>
|
||||||
|
|
||||||
#include <crypto.hpp>
|
#include <util/aligned.hpp>
|
||||||
#include <util/encode.hpp>
|
#include <util/encode.hpp>
|
||||||
#include <util/logger.hpp>
|
|
||||||
|
|
||||||
struct Base32Test : public ::testing::Test
|
struct Base32Test : public ::testing::Test
|
||||||
{
|
{
|
||||||
Base32Test() : crypto(llarp::Crypto::sodium{})
|
Base32Test()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
llarp::Crypto crypto;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(Base32Test, Serialize)
|
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…
Reference in New Issue