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 <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,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…
Reference in New Issue