* make format

* snode to snode direct traffic

* wire up dns on service node tun
This commit is contained in:
Jeff Becker 2018-12-13 11:14:44 -05:00
parent e787165da9
commit be234e4b6e
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05
34 changed files with 546 additions and 209 deletions

View File

@ -261,7 +261,7 @@ main(int argc, char *argv[])
if(verifyMode)
{
llarp::Crypto crypto;
llarp::Crypto crypto;
llarp_crypto_init(&crypto);
if(!rc.Read(rcfname))
{
@ -327,7 +327,7 @@ main(int argc, char *argv[])
// this is the only one...
if(listMode)
{
llarp::Crypto crypto;
llarp::Crypto crypto;
llarp_crypto_init(&crypto);
auto nodedb = llarp_nodedb_new(&crypto);
llarp_nodedb_iter itr;
@ -467,7 +467,7 @@ main(int argc, char *argv[])
if(listMode)
{
llarp::Crypto crypto;
llarp::Crypto crypto;
// no longer used?
// llarp_crypto_libsodium_init(&crypto);
llarp_crypto_init(&crypto);

View File

@ -21,8 +21,8 @@ namespace llarp
int num_nethreads = 1;
bool singleThreaded = false;
std::unique_ptr<llarp::Crypto> crypto;
llarp::Router *router = nullptr;
std::unique_ptr< llarp::Crypto > crypto;
llarp::Router *router = nullptr;
llarp_threadpool *worker = nullptr;
llarp::Logic *logic = nullptr;
llarp_config *config = nullptr;

View File

@ -25,7 +25,7 @@ namespace llarp
}
bool
operator==(const AddressInfo& lhs, const AddressInfo& rhs)
operator==(const AddressInfo &lhs, const AddressInfo &rhs)
{
// we don't care about rank
return lhs.pubkey == rhs.pubkey && lhs.port == rhs.port
@ -33,7 +33,7 @@ namespace llarp
}
bool
operator<(const AddressInfo& lhs, const AddressInfo& rhs)
operator<(const AddressInfo &lhs, const AddressInfo &rhs)
{
return lhs.rank < rhs.rank || lhs.ip < rhs.ip || lhs.port < rhs.port;
}

View File

@ -84,7 +84,6 @@ namespace llarp
bool
operator<(const AddressInfo& lhs, const AddressInfo& rhs);
} // namespace llarp
#endif

View File

@ -14,7 +14,6 @@
#include <pthread_np.h>
#endif
namespace llarp
{
Context::~Context()
@ -81,7 +80,8 @@ namespace llarp
int
Context::LoadDatabase()
{
crypto = std::unique_ptr<llarp::Crypto>(new llarp::Crypto{llarp::Crypto::sodium{}});
crypto = std::unique_ptr< llarp::Crypto >(
new llarp::Crypto{llarp::Crypto::sodium{}});
nodedb = new llarp_nodedb(crypto.get());
if(!llarp_nodedb::ensure_dir(nodedb_dir.c_str()))

View File

@ -1,4 +1,6 @@
#include <crypto.hpp>
#include <fstream>
#include <buffer.hpp>
namespace llarp
{
@ -14,4 +16,46 @@ namespace llarp
char buf[(PUBKEYSIZE + 1) * 2] = {0};
return HexEncode(*this, buf);
}
bool
SecretKey::LoadFromFile(const char* fname)
{
std::ifstream f;
f.open(fname, std::ios::binary);
if(!f.is_open())
return false;
size_t sz = 0;
f.seekg(0, std::ios::end);
sz = f.tellg();
f.seekg(0, std::ios::beg);
if(sz == size())
{
// is raw buffer
f.read((char*)data(), 64);
return true;
}
byte_t tmp[128];
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
if(sz > sizeof(tmp))
return false;
f.read((char*)tmp, sz);
return BDecode(&buf);
}
bool
SecretKey::SaveToFile(const char* fname) const
{
byte_t tmp[128];
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
if(!BEncode(&buf))
return false;
std::ofstream f;
f.open(fname, std::ios::binary);
if(!f.is_open())
return false;
f.write((char*)buf.base, buf.cur - buf.base);
return true;
}
} // namespace llarp

View File

@ -14,17 +14,17 @@
* potentially allow libssl support in the future
*/
static constexpr uint32_t PUBKEYSIZE = 32;
static constexpr uint32_t SECKEYSIZE = 64;
static constexpr uint32_t NONCESIZE = 24;
static constexpr uint32_t PUBKEYSIZE = 32;
static constexpr uint32_t SECKEYSIZE = 64;
static constexpr uint32_t NONCESIZE = 24;
static constexpr uint32_t SHAREDKEYSIZE = 32;
static constexpr uint32_t HASHSIZE = 64;
static constexpr uint32_t HASHSIZE = 64;
static constexpr uint32_t SHORTHASHSIZE = 32;
static constexpr uint32_t HMACSECSIZE = 32;
static constexpr uint32_t SIGSIZE = 64;
static constexpr uint32_t TUNNONCESIZE = 32;
static constexpr uint32_t HMACSIZE = 32;
static constexpr uint32_t PATHIDSIZE = 16;
static constexpr uint32_t HMACSECSIZE = 32;
static constexpr uint32_t SIGSIZE = 64;
static constexpr uint32_t TUNNONCESIZE = 32;
static constexpr uint32_t HMACSIZE = 32;
static constexpr uint32_t PATHIDSIZE = 16;
#include <libntrup/ntru.h>
@ -35,84 +35,88 @@ static constexpr uint32_t PATHIDSIZE = 16;
namespace llarp
{
/// label functors
/// label functors
/// PKE(result, publickey, secretkey, nonce)
using path_dh_func = std::function<bool(byte_t *, const byte_t *, const byte_t *,
const byte_t *)>;
/// PKE(result, publickey, secretkey, nonce)
using path_dh_func = std::function< bool(byte_t *, const byte_t *,
const byte_t *, const byte_t *) >;
/// TKE(result, publickey, secretkey, nonce)
using transport_dh_func = std::function<bool(byte_t *, const byte_t *,
const byte_t *, const byte_t *)>;
/// TKE(result, publickey, secretkey, nonce)
using transport_dh_func = std::function< bool(
byte_t *, const byte_t *, const byte_t *, const byte_t *) >;
/// SD/SE(buffer, key, nonce)
using sym_cipher_func = std::function<bool(llarp_buffer_t, const byte_t *,
const byte_t *)>;
/// SD/SE(buffer, key, nonce)
using sym_cipher_func =
std::function< bool(llarp_buffer_t, const byte_t *, const byte_t *) >;
/// H(result, body)
using hash_func = std::function<bool(byte_t *, llarp_buffer_t)>;
/// H(result, body)
using hash_func = std::function< bool(byte_t *, llarp_buffer_t) >;
/// SH(result, body)
using shorthash_func = std::function<bool(byte_t *, llarp_buffer_t)>;
/// SH(result, body)
using shorthash_func = std::function< bool(byte_t *, llarp_buffer_t) >;
/// MDS(result, body, shared_secret)
using hmac_func = std::function<bool(byte_t *, llarp_buffer_t, const byte_t *)>;
/// MDS(result, body, shared_secret)
using hmac_func =
std::function< bool(byte_t *, llarp_buffer_t, const byte_t *) >;
/// S(sig, secretkey, body)
using sign_func = std::function<bool(byte_t *, const byte_t *, llarp_buffer_t)>;
/// S(sig, secretkey, body)
using sign_func =
std::function< bool(byte_t *, const byte_t *, llarp_buffer_t) >;
/// V(pubkey, body, sig)
using verify_func = std::function<bool(const byte_t *, llarp_buffer_t,
const byte_t *)>;
/// V(pubkey, body, sig)
using verify_func =
std::function< bool(const byte_t *, llarp_buffer_t, const byte_t *) >;
/// library crypto configuration
struct Crypto
{
/// xchacha symettric cipher
sym_cipher_func xchacha20;
/// path dh creator's side
path_dh_func dh_client;
/// path dh relay side
path_dh_func dh_server;
/// transport dh client side
transport_dh_func transport_dh_client;
/// transport dh server side
transport_dh_func transport_dh_server;
/// blake2b 512 bit
hash_func hash;
/// blake2b 256 bit
shorthash_func shorthash;
/// blake2s 256 bit hmac
hmac_func hmac;
/// ed25519 sign
sign_func sign;
/// ed25519 verify
verify_func verify;
/// randomize buffer
std::function<void(llarp_buffer_t)> randomize;
/// randomizer memory
std::function<void(void *, size_t)> randbytes;
/// generate signing keypair
std::function<void(byte_t *)> identity_keygen;
/// generate encryption keypair
std::function<void(byte_t *)> encryption_keygen;
/// generate post quantum encrytion key
std::function<void(byte_t *)> pqe_keygen;
/// post quantum decrypt (buffer, sharedkey_dst, sec)
std::function<bool(const byte_t *, byte_t *, const byte_t *)> pqe_decrypt;
/// post quantum encrypt (buffer, sharedkey_dst, pub)
std::function<bool(byte_t *, byte_t *, const byte_t *)> pqe_encrypt;
/// library crypto configuration
struct Crypto
{
/// xchacha symettric cipher
sym_cipher_func xchacha20;
/// path dh creator's side
path_dh_func dh_client;
/// path dh relay side
path_dh_func dh_server;
/// transport dh client side
transport_dh_func transport_dh_client;
/// transport dh server side
transport_dh_func transport_dh_server;
/// blake2b 512 bit
hash_func hash;
/// blake2b 256 bit
shorthash_func shorthash;
/// blake2s 256 bit hmac
hmac_func hmac;
/// ed25519 sign
sign_func sign;
/// ed25519 verify
verify_func verify;
/// randomize buffer
std::function< void(llarp_buffer_t) > randomize;
/// randomizer memory
std::function< void(void *, size_t) > randbytes;
/// generate signing keypair
std::function< void(byte_t *) > identity_keygen;
/// generate encryption keypair
std::function< void(byte_t *) > encryption_keygen;
/// generate post quantum encrytion key
std::function< void(byte_t *) > pqe_keygen;
/// post quantum decrypt (buffer, sharedkey_dst, sec)
std::function< bool(const byte_t *, byte_t *, const byte_t *) > pqe_decrypt;
/// post quantum encrypt (buffer, sharedkey_dst, pub)
std::function< bool(byte_t *, byte_t *, const byte_t *) > pqe_encrypt;
// Give a basic type tag for the constructor to pick libsodium
struct sodium {};
// Give a basic type tag for the constructor to pick libsodium
struct sodium
{
};
Crypto(Crypto::sodium tag);
};
Crypto(Crypto::sodium tag);
};
/// return random 64bit unsigned interger
uint64_t
randint();
/// return random 64bit unsigned interger
uint64_t
randint();
}
} // namespace llarp
#endif

View File

@ -60,6 +60,12 @@ namespace llarp
return out << "[secretkey]";
}
bool
LoadFromFile(const char* fname);
bool
SaveToFile(const char* fname) const;
SecretKey&
operator=(const byte_t* ptr)
{

View File

@ -174,43 +174,42 @@ namespace llarp
}
Crypto::Crypto(Crypto::sodium tag)
{
(void)tag;
assert(sodium_init() != -1);
char *avx2 = std::getenv("AVX2_FORCE_DISABLE");
if(avx2 && std::string(avx2) == "1")
ntru_init(1);
else
ntru_init(0);
this->xchacha20 = llarp::sodium::xchacha20;
this->dh_client = llarp::sodium::dh_client;
this->dh_server = llarp::sodium::dh_server;
this->transport_dh_client = llarp::sodium::dh_client;
this->transport_dh_server = llarp::sodium::dh_server;
this->hash = llarp::sodium::hash;
this->shorthash = llarp::sodium::shorthash;
this->hmac = llarp::sodium::hmac;
this->sign = llarp::sodium::sign;
this->verify = llarp::sodium::verify;
this->randomize = llarp::sodium::randomize;
this->randbytes = llarp::sodium::randbytes;
this->identity_keygen = llarp::sodium::sigkeygen;
this->encryption_keygen = llarp::sodium::enckeygen;
this->pqe_encrypt = llarp::pq::encrypt;
this->pqe_decrypt = llarp::pq::decrypt;
this->pqe_keygen = llarp::pq::keygen;
int seed = 0;
this->randbytes(&seed, sizeof(seed));
srand(seed);
}
uint64_t
randint()
{
uint64_t i;
randombytes((byte_t *)&i, sizeof(i));
return i;
}
{
(void)tag;
assert(sodium_init() != -1);
char *avx2 = std::getenv("AVX2_FORCE_DISABLE");
if(avx2 && std::string(avx2) == "1")
ntru_init(1);
else
ntru_init(0);
this->xchacha20 = llarp::sodium::xchacha20;
this->dh_client = llarp::sodium::dh_client;
this->dh_server = llarp::sodium::dh_server;
this->transport_dh_client = llarp::sodium::dh_client;
this->transport_dh_server = llarp::sodium::dh_server;
this->hash = llarp::sodium::hash;
this->shorthash = llarp::sodium::shorthash;
this->hmac = llarp::sodium::hmac;
this->sign = llarp::sodium::sign;
this->verify = llarp::sodium::verify;
this->randomize = llarp::sodium::randomize;
this->randbytes = llarp::sodium::randbytes;
this->identity_keygen = llarp::sodium::sigkeygen;
this->encryption_keygen = llarp::sodium::enckeygen;
this->pqe_encrypt = llarp::pq::encrypt;
this->pqe_decrypt = llarp::pq::decrypt;
this->pqe_keygen = llarp::pq::keygen;
int seed = 0;
this->randbytes(&seed, sizeof(seed));
srand(seed);
}
uint64_t
randint()
{
uint64_t i;
randombytes((byte_t *)&i, sizeof(i));
return i;
}
} // namespace llarp

View File

@ -13,7 +13,10 @@
struct llarp_dht_context;
namespace llarp { struct Router; }
namespace llarp
{
struct Router;
}
/// allocator
struct llarp_dht_context*

View File

@ -235,7 +235,8 @@ namespace llarp
/// initialize dht context and explore every exploreInterval milliseconds
void
Init(const Key_t& us, llarp::Router* router, llarp_time_t exploreInterval);
Init(const Key_t& us, llarp::Router* router,
llarp_time_t exploreInterval);
/// get localally stored introset by service address
const llarp::service::IntroSet*

View File

@ -3,3 +3,18 @@
#include <dns/serialize.hpp>
#include <dns/message.hpp>
#include <dns/server.hpp>
namespace llarp
{
namespace dns
{
constexpr uint16_t qTypeTXT = 16;
constexpr uint16_t qTypeMX = 15;
constexpr uint16_t qTypePTR = 12;
constexpr uint16_t qTypeCNAME = 5;
constexpr uint16_t qTypeNS = 2;
constexpr uint16_t qTypeA = 1;
constexpr uint16_t qClassIN = 1;
} // namespace dns
} // namespace llarp

View File

@ -1,5 +1,5 @@
#include <buffer.hpp>
#include <dns/message.hpp>
#include <dns/dns.hpp>
#include <endian.hpp>
#include <logger.hpp>
@ -148,7 +148,7 @@ namespace llarp
}
void
Message::AddINReply(llarp::huint32_t ip)
Message::AddINReply(llarp::huint32_t ip, RR_TTL_t ttl)
{
if(questions.size())
{
@ -156,9 +156,9 @@ namespace llarp
const auto& question = questions[0];
ResourceRecord rec;
rec.rr_name = question.qname;
rec.rr_type = 1;
rec.rr_class = 1;
rec.ttl = 1;
rec.rr_type = qTypeA;
rec.rr_class = qClassIN;
rec.ttl = ttl;
rec.rData.resize(4);
htobe32buf(rec.rData.data(), ip.h);
answers.emplace_back(std::move(rec));
@ -166,7 +166,7 @@ namespace llarp
}
void
Message::AddAReply(std::string name)
Message::AddAReply(std::string name, RR_TTL_t ttl)
{
if(questions.size())
{
@ -176,31 +176,7 @@ namespace llarp
auto& rec = answers.back();
rec.rr_name = question.qname;
rec.rr_type = question.qtype;
rec.rr_class = 1;
rec.ttl = 1;
byte_t tmp[512] = {0};
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
if(EncodeName(&buf, name))
{
buf.sz = buf.cur - buf.base;
rec.rData.resize(buf.sz);
memcpy(rec.rData.data(), buf.base, buf.sz);
}
}
}
void
Message::AddCNAMEReply(std::string name, uint32_t ttl)
{
if(questions.size())
{
hdr_fields |= (1 << 15);
const auto& question = questions[0];
answers.emplace_back();
auto& rec = answers.back();
rec.rr_name = question.qname;
rec.rr_type = 5;
rec.rr_class = 1;
rec.rr_class = qClassIN;
rec.ttl = ttl;
byte_t tmp[512] = {0};
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
@ -214,7 +190,7 @@ namespace llarp
}
void
Message::AddMXReply(std::string name, uint16_t priority)
Message::AddCNAMEReply(std::string name, RR_TTL_t ttl)
{
if(questions.size())
{
@ -223,9 +199,33 @@ namespace llarp
answers.emplace_back();
auto& rec = answers.back();
rec.rr_name = question.qname;
rec.rr_type = question.qtype;
rec.rr_class = 1;
rec.ttl = 1;
rec.rr_type = qTypeCNAME;
rec.rr_class = qClassIN;
rec.ttl = ttl;
byte_t tmp[512] = {0};
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
if(EncodeName(&buf, name))
{
buf.sz = buf.cur - buf.base;
rec.rData.resize(buf.sz);
memcpy(rec.rData.data(), buf.base, buf.sz);
}
}
}
void
Message::AddMXReply(std::string name, uint16_t priority, RR_TTL_t ttl)
{
if(questions.size())
{
hdr_fields |= (1 << 15);
const auto& question = questions[0];
answers.emplace_back();
auto& rec = answers.back();
rec.rr_name = question.qname;
rec.rr_type = qTypeMX;
rec.rr_class = qClassIN;
rec.ttl = ttl;
byte_t tmp[512] = {0};
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
llarp_buffer_put_uint16(&buf, priority);
@ -239,7 +239,7 @@ namespace llarp
}
void
Message::AddNXReply()
Message::AddNXReply(RR_TTL_t ttl)
{
if(questions.size())
{
@ -250,7 +250,7 @@ namespace llarp
nx.rr_name = question.qname;
nx.rr_type = question.qtype;
nx.rr_class = question.qclass;
nx.ttl = 1;
nx.ttl = ttl;
nx.rData.resize(1);
nx.rData.data()[0] = 0;
}

View File

@ -51,19 +51,19 @@ namespace llarp
UpdateHeader();
void
AddNXReply();
AddNXReply(RR_TTL_t ttl = 1);
void
AddMXReply(std::string name, uint16_t priority);
AddMXReply(std::string name, uint16_t priority, RR_TTL_t ttl = 1);
void
AddCNAMEReply(std::string name, uint32_t ttl);
AddCNAMEReply(std::string name, RR_TTL_t ttl = 1);
void
AddINReply(llarp::huint32_t addr);
AddINReply(llarp::huint32_t addr, RR_TTL_t ttl = 1);
void
AddAReply(std::string name);
AddAReply(std::string name, RR_TTL_t ttl = 1);
bool
Encode(llarp_buffer_t* buf) const override;

View File

@ -4,7 +4,6 @@
#include <dnsd.hpp>
#include <service/address.hpp>
using map_address_hook_func =
std::function< bool(const byte_t *addr, bool isSNode, uint32_t ip) >;

View File

@ -14,8 +14,8 @@
#include <sys/types.h>
#include <unistd.h> /* close */
#include <algorithm> // for std::find_if
#include <stdio.h> // sprintf
#include <algorithm> // for std::find_if
#include <stdio.h> // sprintf
#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))

View File

@ -1,7 +1,7 @@
#ifndef LIBLLARP_DNSD_HPP
#define LIBLLARP_DNSD_HPP
#include <ev.h> // for sockaadr
#include <ev.h> // for sockaadr
#include <dns.hpp> // question and dnsc
#include <dnsc.hpp>

View File

@ -5,7 +5,6 @@
#include <stddef.h>
#define EV_TICK_INTERVAL 100
// apparently current Solaris will emulate epoll.

View File

@ -267,7 +267,7 @@ namespace llarp
{
// all BSD UNIX has pktinfo by default
const ssize_t offset = 4;
ssize_t ret = tuntap_read(tunif, buf, sz);
ssize_t ret = tuntap_read(tunif, buf, sz);
if(ret > offset && t->recvpkt)
{
buf += offset;

View File

@ -22,6 +22,12 @@ namespace llarp
{
}
bool
BaseSession::LoadIdentityFromFile(const char* fname)
{
return m_ExitIdentity.LoadFromFile(fname);
}
bool
BaseSession::ShouldBuildMore(llarp_time_t now) const
{
@ -173,5 +179,16 @@ namespace llarp
return true;
}
SNodeSession::SNodeSession(const llarp::RouterID& snodeRouter,
std::function< bool(llarp_buffer_t) > writepkt,
llarp::Router* r, size_t numpaths, size_t hoplen,
bool useRouterSNodeKey)
: BaseSession(snodeRouter, writepkt, r, numpaths, hoplen)
{
if(useRouterSNodeKey)
{
m_ExitIdentity = r->identity;
}
}
} // namespace exit
} // namespace llarp

View File

@ -52,8 +52,12 @@ namespace llarp
bool
IsExpired(llarp_time_t now) const;
bool
LoadIdentityFromFile(const char* fname);
protected:
llarp::RouterID m_ExitRouter;
llarp::SecretKey m_ExitIdentity;
std::function< bool(llarp_buffer_t) > m_WritePacket;
virtual void
@ -75,7 +79,6 @@ namespace llarp
using TieredQueue_t = std::map< uint8_t, UpstreamTrafficQueue_t >;
TieredQueue_t m_Upstream;
uint64_t m_Counter;
llarp::SecretKey m_ExitIdentity;
llarp_time_t m_LastUse;
};
@ -102,8 +105,8 @@ namespace llarp
{
SNodeSession(const llarp::RouterID& snodeRouter,
std::function< bool(llarp_buffer_t) > writepkt,
llarp::Router* r, size_t numpaths, size_t hoplen)
: BaseSession(snodeRouter, writepkt, r, numpaths, hoplen){};
llarp::Router* r, size_t numpaths, size_t hoplen,
bool useRouterSNodeKey = false);
~SNodeSession(){};

View File

@ -2,7 +2,7 @@
#include <net.hpp>
#include <router.hpp>
#include <str.hpp>
#include <dns/dns.hpp>
#include <cassert>
namespace llarp
@ -14,6 +14,7 @@ namespace llarp
{
static_cast< ExitEndpoint * >(tun->user)->OnInetPacket(buf);
}
static void
ExitHandlerFlush(llarp_tun_io *tun)
{
@ -22,8 +23,10 @@ namespace llarp
ExitEndpoint::ExitEndpoint(const std::string &name, llarp::Router *r)
: m_Router(r)
, m_Resolver(r->netloop, this)
, m_Name(name)
, m_Tun{{0}, 0, {0}, 0, 0, 0, 0, 0, 0, 0}
, m_LocalResolverAddr("127.0.0.1", 53)
, m_InetToNetwork(name + "_exit_rx", r->netloop, r->netloop)
{
@ -37,6 +40,89 @@ namespace llarp
{
}
bool
ExitEndpoint::ShouldHookDNSMessage(const llarp::dns::Message &msg) const
{
if(msg.questions.size() == 0)
return false;
if(msg.questions[0].qtype == llarp::dns::qTypePTR)
{
llarp::huint32_t ip;
if(!llarp::dns::DecodePTR(msg.questions[0].qname, ip))
return false;
return m_OurRange.Contains(ip);
}
else if(msg.questions[0].qtype == llarp::dns::qTypeA)
{
return msg.questions[0].qname.find(".snode.")
== (msg.questions[0].qname.size() - 7);
}
else
return false;
}
bool
ExitEndpoint::HandleHookedDNSMessage(
llarp::dns::Message msg,
std::function< void(llarp::dns::Message) > reply)
{
if(msg.questions[0].qtype == llarp::dns::qTypePTR)
{
llarp::huint32_t ip;
if(!llarp::dns::DecodePTR(msg.questions[0].qname, ip))
return false;
if(ip == m_IfAddr)
{
RouterID us = Router()->pubkey();
msg.AddAReply(us.ToString(), 300);
}
else
{
auto itr = m_IPToKey.find(ip);
if(itr != m_IPToKey.end()
&& m_SNodeKeys.find(itr->second) != m_SNodeKeys.end())
{
RouterID them = itr->second;
msg.AddAReply(them.ToString());
}
else
msg.AddNXReply();
}
}
else if(msg.questions[0].qtype == llarp::dns::qTypeA)
{
// forward dns for snode
RouterID r;
if(r.FromString(msg.questions[0].qname))
{
huint32_t ip;
if(m_SNodeKeys.find(r.data()) == m_SNodeKeys.end())
{
// we do not have it mapped
// map it
ip = ObtainServiceNodeIP(r);
msg.AddINReply(ip);
}
else
{
// we have it mapped already as a service node
auto itr = m_KeyToIP.find(r.data());
if(itr != m_KeyToIP.end())
{
ip = itr->second;
msg.AddINReply(ip);
}
else // fallback case that should never happen (probably)
msg.AddNXReply();
}
}
else
msg.AddNXReply();
}
reply(msg);
return true;
}
llarp_time_t
ExitEndpoint::Now() const
{
@ -60,6 +146,20 @@ namespace llarp
}
pk = itr->second;
}
// check if this key is a service node
if(m_SNodeKeys.find(pk) != m_SNodeKeys.end())
{
// check if it's a service node session we made and queue it via our
// snode session that we made otherwise use an inbound session that
// was made by the other service node
auto itr = m_SNodeSessions.find(pk);
if(itr != m_SNodeSessions.end())
{
if(itr->second->QueueUpstreamTraffic(pkt,
llarp::routing::ExitPadSize))
return;
}
}
llarp::exit::Endpoint *ep = nullptr;
auto range = m_ActiveExits.equal_range(pk);
auto itr = range.first;
@ -90,14 +190,29 @@ namespace llarp
}
}
});
auto itr = m_ActiveExits.begin();
while(itr != m_ActiveExits.end())
{
if(!itr->second->Flush())
auto itr = m_ActiveExits.begin();
while(itr != m_ActiveExits.end())
{
llarp::LogWarn("exit session with ", itr->first, " dropped packets");
if(!itr->second->Flush())
{
llarp::LogWarn("exit session with ", itr->first,
" dropped packets");
}
++itr;
}
}
{
auto itr = m_SNodeSessions.begin();
while(itr != m_SNodeSessions.end())
{
if(!itr->second->FlushUpstreamTraffic())
{
llarp::LogWarn("failed to flushsnode traffic to ", itr->first,
" via outbound session");
}
++itr;
}
++itr;
}
}
@ -105,7 +220,13 @@ namespace llarp
ExitEndpoint::Start()
{
if(m_ShouldInitTun)
return llarp_ev_add_tun(Router()->netloop, &m_Tun);
{
if(!llarp_ev_add_tun(Router()->netloop, &m_Tun))
return false;
if(m_UpstreamResolvers.size() == 0)
m_UpstreamResolvers.emplace_back("8.8.8.8", 53);
return m_Resolver.Start(m_LocalResolverAddr, m_UpstreamResolvers);
}
return true;
}
@ -224,6 +345,17 @@ namespace llarp
[buf](Pkt_t &pkt) -> bool { return pkt.Load(buf); });
}
bool
ExitEndpoint::QueueSNodePacket(llarp_buffer_t buf, llarp::huint32_t from)
{
llarp::net::IPv4Packet pkt;
if(!pkt.Load(buf))
return false;
// rewrite ip
pkt.UpdateIPv4PacketOnDst(from, m_IfAddr);
return llarp_ev_tun_async_write(&m_Tun, pkt.Buffer());
}
llarp::exit::Endpoint *
ExitEndpoint::FindEndpointByPath(const llarp::PathID_t &path)
{
@ -271,6 +403,33 @@ namespace llarp
m_PermitExit = IsTrueValue(v.c_str());
return true;
}
if(k == "local-dns")
{
std::string resolverAddr = v;
uint16_t dnsport = 53;
auto pos = v.find(":");
if(pos != std::string::npos)
{
resolverAddr = v.substr(0, pos);
dnsport = std::atoi(v.substr(pos + 1).c_str());
}
m_LocalResolverAddr = llarp::Addr(resolverAddr, dnsport);
llarp::LogInfo(Name(), " local dns set to ", m_LocalResolverAddr);
}
if(k == "upstream-dns")
{
std::string resolverAddr = v;
uint16_t dnsport = 53;
auto pos = v.find(":");
if(pos != std::string::npos)
{
resolverAddr = v.substr(0, pos);
dnsport = std::atoi(v.substr(pos + 1).c_str());
}
m_UpstreamResolvers.emplace_back(resolverAddr, dnsport);
llarp::LogInfo(Name(), "adding upstream dns set to ", resolverAddr, ":",
dnsport);
}
if(k == "ifaddr")
{
auto pos = v.find("/");
@ -286,9 +445,11 @@ namespace llarp
m_Tun.netmask = std::atoi(nmask_str.c_str());
llarp::Addr ifaddr(host_str);
m_IfAddr = ifaddr.xtohl();
m_NextAddr = m_IfAddr;
m_HigestAddr = m_IfAddr ^ (~llarp::netmask_ipv4_bits(m_Tun.netmask));
m_IfAddr = ifaddr.xtohl();
m_OurRange.netmask_bits = netmask_ipv4_bits(m_Tun.netmask);
m_OurRange.addr = m_IfAddr;
m_NextAddr = m_IfAddr;
m_HigestAddr = m_IfAddr | (~m_OurRange.netmask_bits);
llarp::LogInfo(Name(), " set ifaddr range to ", m_Tun.ifaddr, "/",
m_Tun.netmask, " lo=", m_IfAddr, " hi=", m_HigestAddr);
}
@ -313,6 +474,25 @@ namespace llarp
return true;
}
huint32_t
ExitEndpoint::ObtainServiceNodeIP(const llarp::RouterID &other)
{
huint32_t ip = GetIPForIdent(other.data());
if(m_SNodeKeys.insert(other.data()).second)
{
// this is a new service node make an outbound session to them
m_SNodeSessions.insert(
std::make_pair(other,
std::unique_ptr< llarp::exit::SNodeSession >(
new llarp::exit::SNodeSession(
other,
std::bind(&ExitEndpoint::QueueSNodePacket,
this, std::placeholders::_1, ip),
Router(), 2, 1, true))));
}
return ip;
}
bool
ExitEndpoint::AllocateNewExit(const llarp::PubKey pk,
const llarp::PathID_t &path,
@ -321,10 +501,17 @@ namespace llarp
if(wantInternet && !m_PermitExit)
return false;
huint32_t ip = GetIPForIdent(pk);
if(Router()->paths.TransitHopPreviousIsRouter(path, pk.data()))
{
// we think this path belongs to a service node
// mark it as such so we don't make an outbound session to them
m_SNodeKeys.insert(pk.data());
}
m_ActiveExits.insert(
std::make_pair(pk,
std::make_unique< llarp::exit::Endpoint >(
pk, path, !wantInternet, ip, this)));
m_Paths[path] = pk;
return HasLocalMappedAddrFor(pk);
}
@ -361,17 +548,29 @@ namespace llarp
void
ExitEndpoint::Tick(llarp_time_t now)
{
auto itr = m_ActiveExits.begin();
while(itr != m_ActiveExits.end())
{
if(itr->second->IsExpired(now))
auto itr = m_SNodeSessions.begin();
while(itr != m_SNodeSessions.end())
{
itr = m_ActiveExits.erase(itr);
if(itr->second->IsExpired(now))
itr = m_SNodeSessions.erase(itr);
else
++itr;
}
else
}
{
auto itr = m_ActiveExits.begin();
while(itr != m_ActiveExits.end())
{
itr->second->Tick(now);
++itr;
if(itr->second->IsExpired(now))
{
itr = m_ActiveExits.erase(itr);
}
else
{
itr->second->Tick(now);
++itr;
}
}
}
}

View File

@ -3,14 +3,14 @@
#include <exit/endpoint.hpp>
#include <handlers/tun.hpp>
#include <dns/server.hpp>
#include <unordered_map>
namespace llarp
{
namespace handlers
{
struct ExitEndpoint
struct ExitEndpoint : public llarp::dns::IQueryHandler
{
ExitEndpoint(const std::string& name, llarp::Router* r);
~ExitEndpoint();
@ -24,6 +24,14 @@ namespace llarp
std::string
Name() const;
bool
ShouldHookDNSMessage(const llarp::dns::Message& msg) const override;
bool
HandleHookedDNSMessage(
llarp::dns::Message,
std::function< void(llarp::dns::Message) >) override;
bool
AllocateNewExit(const llarp::PubKey pk, const llarp::PathID_t& path,
bool permitInternet);
@ -95,6 +103,14 @@ namespace llarp
huint32_t
AllocateNewAddress();
/// obtain ip for service node session, creates a new session if one does
/// not existing already
huint32_t
ObtainServiceNodeIP(const llarp::RouterID& router);
bool
QueueSNodePacket(llarp_buffer_t buf, llarp::huint32_t from);
void
MarkIPActive(llarp::huint32_t ip);
@ -102,6 +118,7 @@ namespace llarp
KickIdentOffExit(const llarp::PubKey& pk);
llarp::Router* m_Router;
llarp::dns::Proxy m_Resolver;
bool m_ShouldInitTun;
std::string m_Name;
bool m_PermitExit;
@ -118,6 +135,17 @@ namespace llarp
KeyMap_t m_KeyToIP;
using SNodes_t = std::set< llarp::PubKey >;
/// set of pubkeys we treat as snodes
SNodes_t m_SNodeKeys;
using SNodeSessions_t =
std::unordered_map< llarp::RouterID,
std::unique_ptr< llarp::exit::SNodeSession >,
llarp::RouterID::Hash >;
/// snode sessions we are talking to directly
SNodeSessions_t m_SNodeSessions;
std::unordered_map< llarp::huint32_t, llarp::PubKey,
llarp::huint32_t::Hash >
m_IPToKey;
@ -125,6 +153,7 @@ namespace llarp
huint32_t m_IfAddr;
huint32_t m_HigestAddr;
huint32_t m_NextAddr;
llarp::IPRange m_OurRange;
std::unordered_map< llarp::huint32_t, llarp_time_t,
llarp::huint32_t::Hash >
@ -132,6 +161,9 @@ namespace llarp
llarp_tun_io m_Tun;
llarp::Addr m_LocalResolverAddr;
std::vector< llarp::Addr > m_UpstreamResolvers;
using Pkt_t = llarp::net::IPv4Packet;
using PacketQueue_t =
llarp::util::CoDelQueue< Pkt_t, Pkt_t::GetTime, Pkt_t::PutTime,

View File

@ -10,6 +10,7 @@
#include <ev.hpp>
#include <router.hpp>
#include <dns/dns.hpp>
namespace llarp
{
@ -279,7 +280,7 @@ namespace llarp
if(msg.questions.size() == 1)
{
// always hook mx records
if(msg.questions[0].qtype == 15)
if(msg.questions[0].qtype == llarp::dns::qTypeMX)
return true;
if(msg.questions[0].qname == "random.snode"
|| msg.questions[0].qname == "random.snode.")
@ -290,7 +291,7 @@ namespace llarp
// always hook .snode
if(addr.FromString(msg.questions[0].qname, ".snode"))
return true;
if(msg.questions[0].qtype == 12)
if(msg.questions[0].qtype == llarp::dns::qTypePTR)
{
huint32_t ip = {0};
if(!dns::DecodePTR(msg.questions[0].qname, ip))

View File

@ -5,10 +5,11 @@
#include <string>
namespace llarp {
class Logic;
struct Router;
}
namespace llarp
{
class Logic;
struct Router;
} // namespace llarp
struct llarp_iwp_args
{

View File

@ -11,7 +11,6 @@
#include <tuple>
#include <deque>
#ifdef __linux__
#include <linux/errqueue.h>
#include <netinet/ip_icmp.h>
@ -326,7 +325,7 @@ namespace llarp
struct LinkLayer : public ILinkLayer
{
utp_context* _utp_ctx = nullptr;
llarp::Router* router = nullptr;
llarp::Router* router = nullptr;
static uint64
OnRead(utp_callback_arguments* arg);

View File

@ -5,8 +5,7 @@
namespace llarp
{
InboundMessageParser::InboundMessageParser(Router* _router)
: router(_router)
InboundMessageParser::InboundMessageParser(Router* _router) : router(_router)
{
}

View File

@ -174,6 +174,17 @@ namespace llarp
});
}
bool
PathContext::TransitHopPreviousIsRouter(const PathID_t& path,
const RouterID& otherRouter)
{
util::Lock lock(m_TransitPaths.first);
auto itr = m_TransitPaths.second.find(path);
if(itr == m_TransitPaths.second.end())
return false;
return itr->second->info.downstream == otherRouter;
}
IHopHandler*
PathContext::GetByDownstream(const RouterID& remote, const PathID_t& id)
{

View File

@ -581,6 +581,9 @@ namespace llarp
IHopHandler*
GetByUpstream(const RouterID& id, const PathID_t& path);
bool
TransitHopPreviousIsRouter(const PathID_t& path, const RouterID& r);
IHopHandler*
GetPathForTransfer(const PathID_t& topath);

View File

@ -23,7 +23,7 @@ namespace llarp
llarp::Router* router = nullptr;
llarp_threadpool* worker = nullptr;
llarp::Logic* logic = nullptr;
llarp::Crypto* crypto = nullptr;
llarp::Crypto* crypto = nullptr;
LR_CommitMessage LRCM;
static void

View File

@ -50,7 +50,8 @@ namespace llarp
}
bool
PathConfirmMessage::HandleMessage(IMessageHandler* h, llarp::Router* r) const
PathConfirmMessage::HandleMessage(IMessageHandler* h,
llarp::Router* r) const
{
return h && h->HandlePathConfirmMessage(this, r);
}

View File

@ -45,7 +45,8 @@ namespace llarp
}
bool
PathLatencyMessage::HandleMessage(IMessageHandler* h, llarp::Router* r) const
PathLatencyMessage::HandleMessage(IMessageHandler* h,
llarp::Router* r) const
{
return h && h->HandlePathLatencyMessage(this, r);
}

View File

@ -16,7 +16,8 @@ namespace llarp
}
bool
IServiceLookup::SendRequestViaPath(llarp::path::Path *path, llarp::Router *r)
IServiceLookup::SendRequestViaPath(llarp::path::Path *path,
llarp::Router *r)
{
auto msg = BuildRequestMessage();
if(!msg)

View File

@ -208,7 +208,7 @@ namespace llarp
struct AsyncFrameDecrypt
{
llarp::Crypto* crypto;
llarp::Crypto* crypto;
llarp::Logic* logic;
ProtocolMessage* msg;
const Identity& m_LocalIdentity;