The Great Wall of Blame

This commit reflects changes to clang-format rules. Unfortunately,
these rule changes create a massive change to the codebase, which
causes an apparent rewrite of git history.

Git blame's --ignore-rev flag can be used to ignore this commit when
attempting to `git blame` some code.
pull/1215/head
Stephen Shelton 4 years ago
parent 30e7c7f828
commit 273270916e
No known key found for this signature in database
GPG Key ID: EE4BADACCE8B631C

@ -71,18 +71,15 @@ namespace
std::string address = config.api.rpcBindAddr() + "/jsonrpc"; std::string address = config.api.rpcBindAddr() + "/jsonrpc";
const nlohmann::json request{{"method", command}, const nlohmann::json request{
{"params", nlohmann::json::object()}, {"method", command}, {"params", nlohmann::json::object()}, {"id", "foo"}};
{"id", "foo"}};
const std::string requestStr = request.dump(); const std::string requestStr = request.dump();
std::unique_ptr<curl_slist, void (*)(curl_slist*)> chunk( std::unique_ptr<curl_slist, void (*)(curl_slist*)> chunk(
curl_slist_append(nullptr, "content-type: application/json"), curl_slist_append(nullptr, "content-type: application/json"), &curl_slist_free_all);
&curl_slist_free_all);
std::unique_ptr< CURL, void (*)(CURL*) > curl(curl_easy_init(), std::unique_ptr<CURL, void (*)(CURL*)> curl(curl_easy_init(), &curl_easy_cleanup);
&curl_easy_cleanup);
curl_easy_setopt(curl.get(), CURLOPT_URL, address.c_str()); curl_easy_setopt(curl.get(), CURLOPT_URL, address.c_str());
curl_easy_setopt(curl.get(), CURLOPT_POSTFIELDS, requestStr.c_str()); curl_easy_setopt(curl.get(), CURLOPT_POSTFIELDS, requestStr.c_str());
curl_easy_setopt(curl.get(), CURLOPT_POSTFIELDSIZE, requestStr.size()); curl_easy_setopt(curl.get(), CURLOPT_POSTFIELDSIZE, requestStr.size());
@ -109,21 +106,21 @@ namespace
int int
main(int argc, char* argv[]) main(int argc, char* argv[])
{ {
cxxopts::Options options("lokinetctl", cxxopts::Options options(
"lokinetctl",
"LokiNET is a free, open source, private, " "LokiNET is a free, open source, private, "
"decentralized, \"market based sybil resistant\" " "decentralized, \"market based sybil resistant\" "
"and IP based onion routing network"); "and IP based onion routing network");
options.add_options()("v,verbose", "Verbose", cxxopts::value<bool>())( options.add_options()("v,verbose", "Verbose", cxxopts::value<bool>())(
"h,help", "help", cxxopts::value<bool>())( "h,help", "help", cxxopts::value<bool>())(
"c,config", "config file", "c,config",
cxxopts::value< std::string >()->default_value( "config file",
llarp::GetDefaultConfigPath().string())) cxxopts::value<std::string>()->default_value(llarp::GetDefaultConfigPath().string()))
#ifdef WITH_CURL #ifdef WITH_CURL
("j,jsonrpc", "hit json rpc endpoint", cxxopts::value<std::string>()) ("j,jsonrpc", "hit json rpc endpoint", cxxopts::value<std::string>())
#endif #endif
("dump", "dump rc file", ("dump", "dump rc file", cxxopts::value<std::vector<std::string>>(), "FILE");
cxxopts::value< std::vector< std::string > >(), "FILE");
try try
{ {
@ -160,8 +157,7 @@ main(int argc, char* argv[])
#ifdef WITH_CURL #ifdef WITH_CURL
if (result.count("jsonrpc") > 0) if (result.count("jsonrpc") > 0)
{ {
if(!executeJsonRpc(result["jsonrpc"].as< std::string >(), if (!executeJsonRpc(result["jsonrpc"].as<std::string>(), result["config"].as<std::string>()))
result["config"].as< std::string >()))
{ {
return 1; return 1;
} }

@ -103,22 +103,21 @@ main(int argc, char *argv[])
// SetUnhandledExceptionFilter(win32_signal_handler); // SetUnhandledExceptionFilter(win32_signal_handler);
#endif #endif
cxxopts::Options options("lokinet", cxxopts::Options options(
"lokinet",
"LokiNET is a free, open source, private, " "LokiNET is a free, open source, private, "
"decentralized, \"market based sybil resistant\" " "decentralized, \"market based sybil resistant\" "
"and IP based onion routing network"); "and IP based onion routing network");
options.add_options()("v,verbose", "Verbose", cxxopts::value<bool>())( options.add_options()("v,verbose", "Verbose", cxxopts::value<bool>())(
"h,help", "help", cxxopts::value< bool >())("version", "version", "h,help", "help", cxxopts::value<bool>())("version", "version", cxxopts::value<bool>())(
cxxopts::value< bool >())(
"g,generate", "generate client config", cxxopts::value<bool>())( "g,generate", "generate client config", cxxopts::value<bool>())(
"r,router", "generate router config", cxxopts::value<bool>())( "r,router", "generate router config", cxxopts::value<bool>())(
"f,force", "overwrite", cxxopts::value<bool>())( "f,force", "overwrite", cxxopts::value<bool>())(
"c,colour", "colour output", "c,colour", "colour output", cxxopts::value<bool>()->default_value("true"))(
cxxopts::value< bool >()->default_value("true"))(
"b,background", "b,background",
"background mode (start, but do not connect to the network)", "background mode (start, but do not connect to the network)",
cxxopts::value< bool >())("config", "path to configuration file", cxxopts::value<bool>())(
cxxopts::value< std::string >()); "config", "path to configuration file", cxxopts::value<std::string>());
options.parse_positional("config"); options.parse_positional("config");
@ -206,8 +205,7 @@ main(int argc, char *argv[])
{ {
if (ec) if (ec)
{ {
llarp::LogError("failed to create '", basedir.string(), llarp::LogError("failed to create '", basedir.string(), "': ", ec.message());
"': ", ec.message());
return 1; return 1;
} }
} }
@ -215,8 +213,7 @@ main(int argc, char *argv[])
if (genconfigOnly) if (genconfigOnly)
{ {
if(!llarp_ensure_config(conffname.c_str(), basedir.string().c_str(), if (!llarp_ensure_config(conffname.c_str(), basedir.string().c_str(), overWrite, asRouter))
overWrite, asRouter))
return 1; return 1;
} }
else else
@ -241,8 +238,7 @@ main(int argc, char *argv[])
{ {
if (ec) if (ec)
{ {
llarp::LogError("failed to create '", basepath.string(), llarp::LogError("failed to create '", basepath.string(), "': ", ec.message());
"': ", ec.message());
return 1; return 1;
} }
} }
@ -250,8 +246,8 @@ main(int argc, char *argv[])
auto fpath = llarp::GetDefaultConfigPath(); auto fpath = llarp::GetDefaultConfigPath();
// if using default INI file, we're create it even if you don't ask us too // if using default INI file, we're create it even if you don't ask us too
if(!llarp_ensure_config(fpath.string().c_str(), basepath.string().c_str(), if (!llarp_ensure_config(
overWrite, asRouter)) fpath.string().c_str(), basepath.string().c_str(), overWrite, asRouter))
return 1; return 1;
conffname = fpath.string(); conffname = fpath.string();
} }

@ -15,8 +15,7 @@ extern "C"
/// if basedir is not nullptr then use basedir as an absolute /// if basedir is not nullptr then use basedir as an absolute
/// base path for all files in config /// base path for all files in config
bool bool
llarp_ensure_config(const char *, const char *, bool overwrite, llarp_ensure_config(const char*, const char*, bool overwrite, bool asrouter);
bool asrouter);
/// llarp application context for C api /// llarp application context for C api
struct llarp_main; struct llarp_main;
@ -96,16 +95,14 @@ extern "C"
/// returns -1 on error, returns size of packet read /// returns -1 on error, returns size of packet read
/// thread safe /// thread safe
ssize_t ssize_t
llarp_vpn_io_readpkt(struct llarp_vpn_pkt_reader *r, unsigned char *dst, llarp_vpn_io_readpkt(struct llarp_vpn_pkt_reader* r, unsigned char* dst, size_t dstlen);
size_t dstlen);
/// blocking write on packet writer to lokinet internals /// blocking write on packet writer to lokinet internals
/// returns false if we can't write this packet /// returns false if we can't write this packet
/// return true if we wrote this packet /// return true if we wrote this packet
/// thread safe /// thread safe
bool bool
llarp_vpn_io_writepkt(struct llarp_vpn_pkt_writer *w, unsigned char *pktbuf, llarp_vpn_io_writepkt(struct llarp_vpn_pkt_writer* w, unsigned char* pktbuf, size_t pktlen);
size_t pktlen);
/// close vpn io and free private implementation after done /// close vpn io and free private implementation after done
/// operation is async and calls llarp_vpn_io.closed after fully closed /// operation is async and calls llarp_vpn_io.closed after fully closed
@ -123,17 +120,18 @@ extern "C"
/// deferred call to llarp_vpn_io.injected is queued unconditionally /// deferred call to llarp_vpn_io.injected is queued unconditionally
/// thread safe /// thread safe
bool bool
llarp_main_inject_vpn_by_name(struct llarp_main *m, const char *epName, llarp_main_inject_vpn_by_name(
struct llarp_main* m,
const char* epName,
struct llarp_vpn_io* io, struct llarp_vpn_io* io,
struct llarp_vpn_ifaddr_info info); struct llarp_vpn_ifaddr_info info);
/// give main context a vpn io on its default endpoint /// give main context a vpn io on its default endpoint
static bool static bool
llarp_main_inject_default_vpn(struct llarp_main *m, struct llarp_vpn_io *io, llarp_main_inject_default_vpn(
struct llarp_vpn_ifaddr_info info) struct llarp_main* m, struct llarp_vpn_io* io, struct llarp_vpn_ifaddr_info info)
{ {
return llarp_main_inject_vpn_by_name( return llarp_main_inject_vpn_by_name(m, llarp_main_get_default_endpoint_name(m), io, info);
m, llarp_main_get_default_endpoint_name(m), io, info);
} }
/// load config from file by name /// load config from file by name

@ -206,8 +206,7 @@ extern "C"
*/ */
TUNTAP_EXPORT int TUNTAP_EXPORT int
tuntap_set_ip(struct device *, const char *srcaddr, const char *dstaddr, tuntap_set_ip(struct device*, const char* srcaddr, const char* dstaddr, int netmask);
int netmask);
// TUNTAP_EXPORT int tuntap_set_ip_old(struct device *, const char // TUNTAP_EXPORT int tuntap_set_ip_old(struct device *, const char
// *, int); // *, int);
/*TUNTAP_EXPORT int tuntap_set_ip_old(struct device *, const char /*TUNTAP_EXPORT int tuntap_set_ip_old(struct device *, const char
@ -250,8 +249,8 @@ extern "C"
int int
tuntap_sys_set_ipv4_tap(struct device*, t_tun_in_addr*, uint32_t); tuntap_sys_set_ipv4_tap(struct device*, t_tun_in_addr*, uint32_t);
int int
tuntap_sys_set_ipv4_tun(struct device *dev, t_tun_in_addr *s4, tuntap_sys_set_ipv4_tun(
t_tun_in_addr *s4dest, uint32_t bits, int netmask); struct device* dev, t_tun_in_addr* s4, t_tun_in_addr* s4dest, uint32_t bits, int netmask);
#endif #endif
int int

@ -20,8 +20,7 @@ extern "C"
} }
JNIEXPORT jboolean JNICALL JNIEXPORT jboolean JNICALL
Java_network_loki_lokinet_LokinetConfig_Load(JNIEnv* env, jobject self, Java_network_loki_lokinet_LokinetConfig_Load(JNIEnv* env, jobject self, jstring fname)
jstring fname)
{ {
llarp_config* conf = GetImpl<llarp_config>(env, self); llarp_config* conf = GetImpl<llarp_config>(env, self);
if (conf == nullptr) if (conf == nullptr)

@ -22,8 +22,7 @@ extern "C"
} }
JNIEXPORT jboolean JNICALL JNIEXPORT jboolean JNICALL
Java_network_loki_lokinet_LokinetDaemon_Configure(JNIEnv *env, jobject self, Java_network_loki_lokinet_LokinetDaemon_Configure(JNIEnv* env, jobject self, jobject conf)
jobject conf)
{ {
llarp_main* ptr = GetImpl<llarp_main>(env, self); llarp_main* ptr = GetImpl<llarp_main>(env, self);
llarp_config* config = GetImpl<llarp_config>(env, conf); llarp_config* config = GetImpl<llarp_config>(env, conf);
@ -48,8 +47,7 @@ extern "C"
Java_network_loki_lokinet_LokinetDaemon_IsRunning(JNIEnv* env, jobject self) Java_network_loki_lokinet_LokinetDaemon_IsRunning(JNIEnv* env, jobject self)
{ {
llarp_main* ptr = GetImpl<llarp_main>(env, self); llarp_main* ptr = GetImpl<llarp_main>(env, self);
return (ptr != nullptr && llarp_main_is_running(ptr)) ? JNI_TRUE return (ptr != nullptr && llarp_main_is_running(ptr)) ? JNI_TRUE : JNI_FALSE;
: JNI_FALSE;
} }
JNIEXPORT jboolean JNICALL JNIEXPORT jboolean JNICALL
@ -65,8 +63,7 @@ extern "C"
} }
JNIEXPORT jboolean JNICALL JNIEXPORT jboolean JNICALL
Java_network_loki_lokinet_LokinetDaemon_InjectVPN(JNIEnv *env, jobject self, Java_network_loki_lokinet_LokinetDaemon_InjectVPN(JNIEnv* env, jobject self, jobject vpn)
jobject vpn)
{ {
llarp_main* ptr = GetImpl<llarp_main>(env, self); llarp_main* ptr = GetImpl<llarp_main>(env, self);
lokinet_jni_vpnio* impl = GetImpl<lokinet_jni_vpnio>(env, vpn); lokinet_jni_vpnio* impl = GetImpl<lokinet_jni_vpnio>(env, vpn);
@ -76,8 +73,6 @@ extern "C"
return JNI_FALSE; return JNI_FALSE;
if (not impl->Init(ptr)) if (not impl->Init(ptr))
return JNI_FALSE; return JNI_FALSE;
return llarp_main_inject_default_vpn(ptr, &impl->io, impl->info) return llarp_main_inject_default_vpn(ptr, &impl->io, impl->info) ? JNI_TRUE : JNI_FALSE;
? JNI_TRUE
: JNI_FALSE;
} }
} }

@ -12,12 +12,10 @@ static T
VisitStringAsStringView(JNIEnv* env, jobject str, V visit) VisitStringAsStringView(JNIEnv* env, jobject str, V visit)
{ {
const jclass stringClass = env->GetObjectClass(str); const jclass stringClass = env->GetObjectClass(str);
const jmethodID getBytes = const jmethodID getBytes = env->GetMethodID(stringClass, "getBytes", "(Ljava/lang/String;)[B");
env->GetMethodID(stringClass, "getBytes", "(Ljava/lang/String;)[B");
const jstring charsetName = env->NewStringUTF("UTF-8"); const jstring charsetName = env->NewStringUTF("UTF-8");
const jbyteArray stringJbytes = const jbyteArray stringJbytes = (jbyteArray)env->CallObjectMethod(str, getBytes, charsetName);
(jbyteArray)env->CallObjectMethod(str, getBytes, charsetName);
env->DeleteLocalRef(charsetName); env->DeleteLocalRef(charsetName);
const size_t length = env->GetArrayLength(stringJbytes); const size_t length = env->GetArrayLength(stringJbytes);
@ -55,8 +53,7 @@ FromObjectMember(JNIEnv* env, jobject self, const char* membername)
/// visit object string member called membername as bytes /// visit object string member called membername as bytes
template <typename T, typename V> template <typename T, typename V>
static T static T
VisitObjectMemberStringAsStringView(JNIEnv* env, jobject self, VisitObjectMemberStringAsStringView(JNIEnv* env, jobject self, const char* membername, V v)
const char* membername, V v)
{ {
jclass cl = env->GetObjectClass(self); jclass cl = env->GetObjectClass(self);
jfieldID name = env->GetFieldID(cl, membername, "Ljava/lang/String;"); jfieldID name = env->GetFieldID(cl, membername, "Ljava/lang/String;");

@ -37,8 +37,7 @@ extern "C"
} }
JNIEXPORT jint JNICALL JNIEXPORT jint JNICALL
Java_network_loki_lokinet_LokinetVPN_ReadPkt(JNIEnv *env, jobject self, Java_network_loki_lokinet_LokinetVPN_ReadPkt(JNIEnv* env, jobject self, jobject pkt)
jobject pkt)
{ {
lokinet_jni_vpnio* vpn = GetImpl<lokinet_jni_vpnio>(env, self); lokinet_jni_vpnio* vpn = GetImpl<lokinet_jni_vpnio>(env, self);
if (vpn == nullptr) if (vpn == nullptr)
@ -51,8 +50,7 @@ extern "C"
} }
JNIEXPORT jboolean JNICALL JNIEXPORT jboolean JNICALL
Java_network_loki_lokinet_LokinetVPN_WritePkt(JNIEnv *env, jobject self, Java_network_loki_lokinet_LokinetVPN_WritePkt(JNIEnv* env, jobject self, jobject pkt)
jobject pkt)
{ {
lokinet_jni_vpnio* vpn = GetImpl<lokinet_jni_vpnio>(env, self); lokinet_jni_vpnio* vpn = GetImpl<lokinet_jni_vpnio>(env, self);
if (vpn == nullptr) if (vpn == nullptr)
@ -65,8 +63,7 @@ extern "C"
} }
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_network_loki_lokinet_LokinetVPN_SetInfo(JNIEnv *env, jobject self, Java_network_loki_lokinet_LokinetVPN_SetInfo(JNIEnv* env, jobject self, jobject info)
jobject info)
{ {
lokinet_jni_vpnio* vpn = GetImpl<lokinet_jni_vpnio>(env, self); lokinet_jni_vpnio* vpn = GetImpl<lokinet_jni_vpnio>(env, self);
if (vpn == nullptr) if (vpn == nullptr)

@ -22,8 +22,7 @@ extern "C"
* Signature: (Ljava/lang/String;)Ljava/lang/String; * Signature: (Ljava/lang/String;)Ljava/lang/String;
*/ */
JNIEXPORT jstring JNICALL JNIEXPORT jstring JNICALL
Java_network_loki_lokinet_Lokinet_1JNI_startLokinet(JNIEnv *, jclass, Java_network_loki_lokinet_Lokinet_1JNI_startLokinet(JNIEnv*, jclass, jstring);
jstring);
JNIEXPORT jstring JNICALL JNIEXPORT jstring JNICALL
Java_network_loki_lokinet_Lokinet_1JNI_getIfAddr(JNIEnv*, jclass); Java_network_loki_lokinet_Lokinet_1JNI_getIfAddr(JNIEnv*, jclass);
@ -40,8 +39,7 @@ extern "C"
Java_network_loki_lokinet_Lokinet_1JNI_stopLokinet(JNIEnv*, jclass); Java_network_loki_lokinet_Lokinet_1JNI_stopLokinet(JNIEnv*, jclass);
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_network_loki_lokinet_Lokinet_1JNI_setVPNFileDescriptor(JNIEnv *, jclass, Java_network_loki_lokinet_Lokinet_1JNI_setVPNFileDescriptor(JNIEnv*, jclass, jint, jint);
jint, jint);
/* /*
* Class: network_loki_lokinet_Lokinet_JNI * Class: network_loki_lokinet_Lokinet_JNI
@ -49,8 +47,7 @@ extern "C"
* Signature: (Z)V * Signature: (Z)V
*/ */
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_network_loki_lokinet_Lokinet_1JNI_onNetworkStateChanged(JNIEnv *, jclass, Java_network_loki_lokinet_Lokinet_1JNI_onNetworkStateChanged(JNIEnv*, jclass, jboolean);
jboolean);
#ifdef __cplusplus #ifdef __cplusplus
} }

@ -73,8 +73,7 @@ namespace abyss
/// must be called after RunAsync returns true /// must be called after RunAsync returns true
/// queue a call for rpc /// queue a call for rpc
void void
QueueRPC(RPC_Method_t method, RPC_Params params, QueueRPC(RPC_Method_t method, RPC_Params params, HandlerFactory createHandler);
HandlerFactory createHandler);
/// drop all pending calls on the floor /// drop all pending calls on the floor
void void
@ -99,9 +98,7 @@ namespace abyss
struct Call struct Call
{ {
Call(RPC_Method_t&& m, RPC_Params&& p, HandlerFactory&& f) Call(RPC_Method_t&& m, RPC_Params&& p, HandlerFactory&& f)
: method(std::move(m)) : method(std::move(m)), params(std::move(p)), createHandler(std::move(f))
, params(std::move(p))
, createHandler(std::move(f))
{ {
} }
RPC_Method_t method; RPC_Method_t method;

@ -27,8 +27,7 @@ struct MD5
m.Update((const unsigned char*)str.c_str(), dist); m.Update((const unsigned char*)str.c_str(), dist);
m.Final(digest.data()); m.Final(digest.data());
std::string hex; std::string hex;
std::for_each(digest.begin(), digest.end(), std::for_each(digest.begin(), digest.end(), [&hex](const unsigned char& ch) {
[&hex](const unsigned char& ch) {
char tmpbuf[4] = {0}; char tmpbuf[4] = {0};
std::snprintf(tmpbuf, sizeof(tmpbuf), "%.2x", ch); std::snprintf(tmpbuf, sizeof(tmpbuf), "%.2x", ch);
hex += std::string(tmpbuf); hex += std::string(tmpbuf);

@ -51,8 +51,8 @@ namespace abyss
virtual ~BaseReqHandler(); virtual ~BaseReqHandler();
bool bool
ServeAsync(llarp_ev_loop_ptr loop, std::shared_ptr< llarp::Logic > logic, ServeAsync(
const sockaddr* bindaddr); llarp_ev_loop_ptr loop, std::shared_ptr<llarp::Logic> logic, const sockaddr* bindaddr);
void void
RemoveConn(IRPCHandler* handler); RemoveConn(IRPCHandler* handler);

@ -26,11 +26,11 @@ struct DemoCall : public abyss::http::IRPCClientHandler
std::function<void(void)> m_Callback; std::function<void(void)> m_Callback;
std::shared_ptr<llarp::Logic> m_Logic; std::shared_ptr<llarp::Logic> m_Logic;
DemoCall(abyss::http::ConnImpl* impl, std::shared_ptr< llarp::Logic > logic, DemoCall(
abyss::http::ConnImpl* impl,
std::shared_ptr<llarp::Logic> logic,
std::function<void(void)> callback) std::function<void(void)> callback)
: abyss::http::IRPCClientHandler(impl) : abyss::http::IRPCClientHandler(impl), m_Callback(callback), m_Logic(logic)
, m_Callback(callback)
, m_Logic(logic)
{ {
llarp::LogInfo("new call"); llarp::LogInfo("new call");
} }
@ -73,7 +73,9 @@ struct DemoClient : public abyss::http::JSONRPC
void void
DoDemoRequest() DoDemoRequest()
{ {
QueueRPC("test", nlohmann::json::object(), QueueRPC(
"test",
nlohmann::json::object(),
std::bind(&DemoClient::NewConn, this, std::placeholders::_1)); std::bind(&DemoClient::NewConn, this, std::placeholders::_1));
Flush(); Flush();
} }

@ -32,8 +32,11 @@ namespace abyss
State state; State state;
ConnImpl(llarp_tcp_conn* conn, JSONRPC* parent, ConnImpl(
const RPC_Method_t& method, const RPC_Params& params, llarp_tcp_conn* conn,
JSONRPC* parent,
const RPC_Method_t& method,
const RPC_Params& params,
JSONRPC::HandlerFactory factory) JSONRPC::HandlerFactory factory)
: m_Conn(conn) : m_Conn(conn)
, m_Parent(parent) , m_Parent(parent)
@ -153,8 +156,7 @@ namespace abyss
auto strip = [&opts](const std::string& name) -> std::string { auto strip = [&opts](const std::string& name) -> std::string {
std::string val; std::string val;
std::for_each(opts[name].begin(), opts[name].end(), std::for_each(opts[name].begin(), opts[name].end(), [&val](const char& ch) {
[&val](const char& ch) {
if (ch != '"') if (ch != '"')
val += ch; val += ch;
}); });
@ -166,28 +168,24 @@ namespace abyss
const auto qop = strip("qop"); const auto qop = strip("qop");
std::string nonceCount = "0000000" + std::to_string(m_AuthTries); std::string nonceCount = "0000000" + std::to_string(m_AuthTries);
std::string str = std::string str = m_Parent->username + ":" + realm + ":" + m_Parent->password;
m_Parent->username + ":" + realm + ":" + m_Parent->password;
std::string h1 = MD5::SumHex(str); std::string h1 = MD5::SumHex(str);
str = "POST:/json_rpc"; str = "POST:/json_rpc";
std::string h2 = MD5::SumHex(str); std::string h2 = MD5::SumHex(str);
llarp::AlignedBuffer<8> n; llarp::AlignedBuffer<8> n;
n.Randomize(); n.Randomize();
std::string cnonce = n.ToHex(); std::string cnonce = n.ToHex();
str = h1 + ":" + nonce + ":" + nonceCount + ":" + cnonce + ":" + qop str = h1 + ":" + nonce + ":" + nonceCount + ":" + cnonce + ":" + qop + ":" + h2;
+ ":" + h2;
auto responseH = MD5::SumHex(str); auto responseH = MD5::SumHex(str);
authgen << "Digest username=\"" << m_Parent->username + "\", realm=\"" authgen << "Digest username=\"" << m_Parent->username + "\", realm=\"" << realm
<< realm << "\", uri=\"/json_rpc\", algorithm=MD5, qop=auth, nonce=\"" << nonce
<< "\", uri=\"/json_rpc\", algorithm=MD5, qop=auth, nonce=\"" << "\", response=\"" << responseH << "\", nc=" << nonceCount << ", cnonce=\""
<< nonce << "\", response=\"" << responseH << cnonce << "\"";
<< "\", nc=" << nonceCount << ", cnonce=\"" << cnonce << "\"";
for (const auto& opt : opts) for (const auto& opt : opts)
{ {
if(opt.first == "algorithm" || opt.first == "realm" if (opt.first == "algorithm" || opt.first == "realm" || opt.first == "qop"
|| opt.first == "qop" || opt.first == "nonce" || opt.first == "nonce" || opt.first == "stale")
|| opt.first == "stale")
continue; continue;
authgen << ", " << opt.first << "=" << opt.second; authgen << ", " << opt.first << "=" << opt.second;
} }
@ -332,8 +330,7 @@ namespace abyss
request << "\r\n" << body; request << "\r\n" << body;
std::string buf = request.str(); std::string buf = request.str();
if(!llarp_tcp_conn_async_write(m_Conn, if (!llarp_tcp_conn_async_write(m_Conn, llarp_buffer_t(buf.c_str(), buf.size())))
llarp_buffer_t(buf.c_str(), buf.size())))
{ {
CloseError("failed to write request"); CloseError("failed to write request");
return; return;
@ -400,12 +397,10 @@ namespace abyss
} }
void void
JSONRPC::QueueRPC(RPC_Method_t method, RPC_Params params, JSONRPC::QueueRPC(RPC_Method_t method, RPC_Params params, HandlerFactory createHandler)
HandlerFactory createHandler)
{ {
if (m_Run) if (m_Run)
m_PendingCalls.emplace_back(std::move(method), std::move(params), m_PendingCalls.emplace_back(std::move(method), std::move(params), std::move(createHandler));
std::move(createHandler));
} }
bool bool
@ -446,8 +441,8 @@ namespace abyss
return; return;
} }
auto& front = m_PendingCalls.front(); auto& front = m_PendingCalls.front();
ConnImpl* connimpl = new ConnImpl(conn, this, front.method, front.params, ConnImpl* connimpl =
front.createHandler); new ConnImpl(conn, this, front.method, front.params, front.createHandler);
m_PendingCalls.pop_front(); m_PendingCalls.pop_front();
m_Conns.emplace_back(connimpl->handler); m_Conns.emplace_back(connimpl->handler);
connimpl->SendRequest(); connimpl->SendRequest();

@ -7,12 +7,10 @@ void
Transform(uint32_t* buf, uint32_t* in); Transform(uint32_t* buf, uint32_t* in);
static unsigned char PADDING[64] = { static unsigned char PADDING[64] = {
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
/* F, G and H are basic MD5 functions: selection, majority, parity */ /* F, G and H are basic MD5 functions: selection, majority, parity */
#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))

@ -95,21 +95,25 @@ namespace abyss
ShouldProcessHeader(const string_view& name) const ShouldProcessHeader(const string_view& name) const
{ {
// TODO: header whitelist // TODO: header whitelist
return name == string_view("content-type") return name == string_view("content-type") || name == string_view("content-length")
|| name == string_view("content-length")
|| name == string_view("host"); || name == string_view("host");
} }
bool bool
WriteResponseSimple(int code, const std::string& msg, WriteResponseSimple(
const char* contentType, const char* content) int code, const std::string& msg, const char* contentType, const char* content)
{ {
char buf[512] = {0}; char buf[512] = {0};
size_t contentLength = strlen(content); size_t contentLength = strlen(content);
int sz = snprintf(buf, sizeof(buf), int sz = snprintf(
buf,
sizeof(buf),
"HTTP/1.0 %d %s\r\nContent-Type: " "HTTP/1.0 %d %s\r\nContent-Type: "
"%s\r\nContent-Length: %zu\r\n\r\n", "%s\r\nContent-Length: %zu\r\n\r\n",
code, msg.c_str(), contentType, contentLength); code,
msg.c_str(),
contentType,
contentLength);
if (sz <= 0) if (sz <= 0)
return false; return false;
if (!llarp_tcp_conn_async_write(_conn, llarp_buffer_t(buf, sz))) if (!llarp_tcp_conn_async_write(_conn, llarp_buffer_t(buf, sz)))
@ -117,8 +121,7 @@ namespace abyss
m_State = eWriteHTTPBody; m_State = eWriteHTTPBody;
return llarp_tcp_conn_async_write( return llarp_tcp_conn_async_write(_conn, llarp_buffer_t(content, contentLength));
_conn, llarp_buffer_t(content, contentLength));
} }
bool bool
@ -126,22 +129,19 @@ namespace abyss
{ {
if (Header.Method != "POST") if (Header.Method != "POST")
{ {
return WriteResponseSimple(405, "Method Not Allowed", "text/plain", return WriteResponseSimple(405, "Method Not Allowed", "text/plain", "nope");
"nope");
} }
{ {
auto itr = Header.Headers.find("content-type"); auto itr = Header.Headers.find("content-type");
if (itr == Header.Headers.end()) if (itr == Header.Headers.end())
{ {
return WriteResponseSimple(415, "Unsupported Media Type", return WriteResponseSimple(
"text/plain", 415, "Unsupported Media Type", "text/plain", "no content type provided");
"no content type provided");
} }
else if (itr->second != string_view("application/json")) else if (itr->second != string_view("application/json"))
{ {
return WriteResponseSimple(415, "Unsupported Media Type", return WriteResponseSimple(
"text/plain", 415, "Unsupported Media Type", "text/plain", "this does not look like jsonrpc 2.0");
"this does not look like jsonrpc 2.0");
} }
} }
// initialize body parser // initialize body parser
@ -150,14 +150,12 @@ namespace abyss
auto itr = Header.Headers.find("content-length"); auto itr = Header.Headers.find("content-length");
if (itr == Header.Headers.end()) if (itr == Header.Headers.end())
{ {
return WriteResponseSimple(400, "Bad Request", "text/plain", return WriteResponseSimple(400, "Bad Request", "text/plain", "no content length");
"no content length");
} }
ssize_t contentLength = std::stoll(itr->second); ssize_t contentLength = std::stoll(itr->second);
if (contentLength <= 0) if (contentLength <= 0)
{ {
return WriteResponseSimple(400, "Bad Request", "text/plain", return WriteResponseSimple(400, "Bad Request", "text/plain", "bad content length");
"bad content length");
} }
else else
{ {
@ -166,19 +164,16 @@ namespace abyss
itr = Header.Headers.find("host"); itr = Header.Headers.find("host");
if (itr == Header.Headers.end()) if (itr == Header.Headers.end())
{ {
return WriteResponseSimple(400, "Bad Request", "text/plain", return WriteResponseSimple(400, "Bad Request", "text/plain", "no host header provided");
"no host header provided");
} }
if (not handler->ValidateHost(itr->second)) if (not handler->ValidateHost(itr->second))
{ {
return WriteResponseSimple(400, "Bad Request", "text/plain", return WriteResponseSimple(400, "Bad Request", "text/plain", "invalid host header");
"invalid host header");
} }
} }
if (!m_BodyParser->FeedData(buf, sz)) if (!m_BodyParser->FeedData(buf, sz))
{ {
return WriteResponseSimple(400, "Bad Request", "text/plain", return WriteResponseSimple(400, "Bad Request", "text/plain", "invalid body size");
"invalid body size");
} }
switch (m_BodyParser->Parse(m_Request)) switch (m_BodyParser->Parse(m_Request))
@ -186,28 +181,24 @@ namespace abyss
case json::IParser::eNeedData: case json::IParser::eNeedData:
return true; return true;
case json::IParser::eParseError: case json::IParser::eParseError:
return WriteResponseSimple(400, "Bad Request", "text/plain", return WriteResponseSimple(400, "Bad Request", "text/plain", "bad json object");
"bad json object");
case json::IParser::eDone: case json::IParser::eDone:
if(m_Request.is_object() && m_Request.count("params") if (m_Request.is_object() && m_Request.count("params") && m_Request.count("method")
&& m_Request.count("method") && m_Request.count("id") && m_Request.count("id") && m_Request["id"].is_string()
&& m_Request["id"].is_string() && m_Request["method"].is_string() && m_Request["method"].is_string() && m_Request["params"].is_object())
&& m_Request["params"].is_object())
{ {
nlohmann::json response; nlohmann::json response;
response["jsonrpc"] = "2.0"; response["jsonrpc"] = "2.0";
response["id"] = m_Request["id"].get<std::string>(); response["id"] = m_Request["id"].get<std::string>();
auto value = handler->HandleJSONRPC( auto value = handler->HandleJSONRPC(
m_Request["method"].get< std::string >(), m_Request["method"].get<std::string>(), m_Request["params"]);
m_Request["params"]);
if (!value.is_null()) if (!value.is_null())
response["result"] = std::move(value); response["result"] = std::move(value);
return WriteResponseJSON(response); return WriteResponseJSON(response);
} }
return WriteResponseSimple(500, "internal error", "text/plain", return WriteResponseSimple(500, "internal error", "text/plain", "nope");
"nope");
default: default:
return false; return false;
} }
@ -217,8 +208,7 @@ namespace abyss
WriteResponseJSON(const nlohmann::json& response) WriteResponseJSON(const nlohmann::json& response)
{ {
std::string responseStr = response.dump(); std::string responseStr = response.dump();
return WriteResponseSimple(200, "OK", "application/json", return WriteResponseSimple(200, "OK", "application/json", responseStr.c_str());
responseStr.c_str());
} }
bool bool
@ -309,8 +299,7 @@ namespace abyss
bool bool
ShouldClose(llarp_time_t now) const ShouldClose(llarp_time_t now) const
{ {
return now - m_LastActive > m_ReadTimeout || m_Bad return now - m_LastActive > m_ReadTimeout || m_Bad || m_State == eCloseMe;
|| m_State == eCloseMe;
} }
void void
@ -340,8 +329,7 @@ namespace abyss
return m_Impl->ShouldClose(now); return m_Impl->ShouldClose(now);
} }
BaseReqHandler::BaseReqHandler(llarp_time_t reqtimeout) BaseReqHandler::BaseReqHandler(llarp_time_t reqtimeout) : m_ReqTimeout(reqtimeout)
: m_ReqTimeout(reqtimeout)
{ {
m_acceptor.accepted = &BaseReqHandler::OnAccept; m_acceptor.accepted = &BaseReqHandler::OnAccept;
m_acceptor.user = this; m_acceptor.user = this;
@ -350,9 +338,8 @@ namespace abyss
} }
bool bool
BaseReqHandler::ServeAsync(llarp_ev_loop_ptr loop, BaseReqHandler::ServeAsync(
std::shared_ptr< llarp::Logic > logic, llarp_ev_loop_ptr loop, std::shared_ptr<llarp::Logic> logic, const sockaddr* bindaddr)
const sockaddr* bindaddr)
{ {
m_loop = loop; m_loop = loop;
m_Logic = logic; m_Logic = logic;

@ -85,8 +85,13 @@ netlink_send(int p_socket, int p_request)
struct sockaddr_nl l_addr; struct sockaddr_nl l_addr;
memset(&l_addr, 0, sizeof(l_addr)); memset(&l_addr, 0, sizeof(l_addr));
l_addr.nl_family = AF_NETLINK; l_addr.nl_family = AF_NETLINK;
return (sendto(p_socket, &l_data.m_hdr, l_data.m_hdr.nlmsg_len, 0, return (sendto(
(struct sockaddr *)&l_addr, sizeof(l_addr))); p_socket,
&l_data.m_hdr,
l_data.m_hdr.nlmsg_len,
0,
(struct sockaddr*)&l_addr,
sizeof(l_addr)));
} }
static int static int
@ -150,12 +155,10 @@ getNetlinkResponse(int p_socket, int *p_size, int *p_done)
{ {
pid_t l_pid = getpid(); pid_t l_pid = getpid();
struct nlmsghdr* l_hdr; struct nlmsghdr* l_hdr;
for(l_hdr = (struct nlmsghdr *)l_buffer; for (l_hdr = (struct nlmsghdr*)l_buffer; NLMSG_OK(l_hdr, (unsigned int)l_read);
NLMSG_OK(l_hdr, (unsigned int)l_read);
l_hdr = (struct nlmsghdr*)NLMSG_NEXT(l_hdr, l_read)) l_hdr = (struct nlmsghdr*)NLMSG_NEXT(l_hdr, l_read))
{ {
if((pid_t)l_hdr->nlmsg_pid != l_pid if ((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket)
|| (int)l_hdr->nlmsg_seq != p_socket)
{ {
continue; continue;
} }
@ -263,17 +266,15 @@ calcAddrLen(sa_family_t p_family, int p_dataSize)
case AF_INET6: case AF_INET6:
return sizeof(struct sockaddr_in6); return sizeof(struct sockaddr_in6);
case AF_PACKET: case AF_PACKET:
return maxSize(sizeof(struct sockaddr_ll), return maxSize(
offsetof(struct sockaddr_ll, sll_addr) + p_dataSize); sizeof(struct sockaddr_ll), offsetof(struct sockaddr_ll, sll_addr) + p_dataSize);
default: default:
return maxSize(sizeof(struct sockaddr), return maxSize(sizeof(struct sockaddr), offsetof(struct sockaddr, sa_data) + p_dataSize);
offsetof(struct sockaddr, sa_data) + p_dataSize);
} }
} }
static void static void
makeSockaddr(sa_family_t p_family, struct sockaddr *p_dest, void *p_data, makeSockaddr(sa_family_t p_family, struct sockaddr* p_dest, void* p_data, size_t p_size)
size_t p_size)
{ {
switch (p_family) switch (p_family)
{ {
@ -323,8 +324,7 @@ interpretLink(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList)
size_t l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifinfomsg)); size_t l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifinfomsg));
struct rtattr* l_rta; struct rtattr* l_rta;
for(l_rta = IFLA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); for (l_rta = IFLA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
l_rta = RTA_NEXT(l_rta, l_rtaSize))
{ {
void* l_rtaData = RTA_DATA(l_rta); void* l_rtaData = RTA_DATA(l_rta);
(void)l_rtaData; (void)l_rtaData;
@ -346,8 +346,8 @@ interpretLink(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList)
} }
} }
struct ifaddrs *l_entry = malloc(sizeof(struct ifaddrs) + sizeof(int) struct ifaddrs* l_entry =
+ l_nameSize + l_addrSize + l_dataSize); malloc(sizeof(struct ifaddrs) + sizeof(int) + l_nameSize + l_addrSize + l_dataSize);
if (l_entry == NULL) if (l_entry == NULL)
{ {
return -1; return -1;
@ -366,8 +366,7 @@ interpretLink(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList)
l_entry->ifa_flags = l_info->ifi_flags; l_entry->ifa_flags = l_info->ifi_flags;
l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifinfomsg)); l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifinfomsg));
for(l_rta = IFLA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); for (l_rta = IFLA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
l_rta = RTA_NEXT(l_rta, l_rtaSize))
{ {
void* l_rtaData = RTA_DATA(l_rta); void* l_rtaData = RTA_DATA(l_rta);
size_t l_rtaDataSize = RTA_PAYLOAD(l_rta); size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
@ -377,8 +376,7 @@ interpretLink(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList)
case IFLA_BROADCAST: case IFLA_BROADCAST:
{ {
size_t l_addrLen = calcAddrLen(AF_PACKET, l_rtaDataSize); size_t l_addrLen = calcAddrLen(AF_PACKET, l_rtaDataSize);
makeSockaddr(AF_PACKET, (struct sockaddr *)l_addr, l_rtaData, makeSockaddr(AF_PACKET, (struct sockaddr*)l_addr, l_rtaData, l_rtaDataSize);
l_rtaDataSize);
((struct sockaddr_ll*)l_addr)->sll_ifindex = l_info->ifi_index; ((struct sockaddr_ll*)l_addr)->sll_ifindex = l_info->ifi_index;
((struct sockaddr_ll*)l_addr)->sll_hatype = l_info->ifi_type; ((struct sockaddr_ll*)l_addr)->sll_hatype = l_info->ifi_type;
if (l_rta->rta_type == IFLA_ADDRESS) if (l_rta->rta_type == IFLA_ADDRESS)
@ -432,12 +430,10 @@ findInterface(int p_index, struct ifaddrs **p_links, int p_numLinks)
} }
static int static int
interpretAddr(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList, interpretAddr(struct nlmsghdr* p_hdr, struct ifaddrs** p_resultList, int p_numLinks)
int p_numLinks)
{ {
struct ifaddrmsg* l_info = (struct ifaddrmsg*)NLMSG_DATA(p_hdr); struct ifaddrmsg* l_info = (struct ifaddrmsg*)NLMSG_DATA(p_hdr);
struct ifaddrs *l_interface = struct ifaddrs* l_interface = findInterface(l_info->ifa_index, p_resultList, p_numLinks);
findInterface(l_info->ifa_index, p_resultList, p_numLinks);
if (l_info->ifa_family == AF_PACKET) if (l_info->ifa_family == AF_PACKET)
{ {
@ -451,8 +447,7 @@ interpretAddr(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList,
size_t l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifaddrmsg)); size_t l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifaddrmsg));
struct rtattr* l_rta; struct rtattr* l_rta;
for(l_rta = IFA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); for (l_rta = IFA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
l_rta = RTA_NEXT(l_rta, l_rtaSize))
{ {
void* l_rtaData = RTA_DATA(l_rta); void* l_rtaData = RTA_DATA(l_rta);
(void)l_rtaData; (void)l_rtaData;
@ -462,16 +457,13 @@ interpretAddr(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList,
{ {
case IFA_ADDRESS: case IFA_ADDRESS:
case IFA_LOCAL: case IFA_LOCAL:
if((l_info->ifa_family == AF_INET || l_info->ifa_family == AF_INET6) if ((l_info->ifa_family == AF_INET || l_info->ifa_family == AF_INET6) && !l_addedNetmask)
&& !l_addedNetmask)
{ // make room for netmask { // make room for netmask
l_addrSize += l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize));
NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize));
l_addedNetmask = 1; l_addedNetmask = 1;
} }
case IFA_BROADCAST: case IFA_BROADCAST:
l_addrSize += l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize));
NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize));
break; break;
case IFA_LABEL: case IFA_LABEL:
l_nameSize += NLMSG_ALIGN(l_rtaSize + 1); l_nameSize += NLMSG_ALIGN(l_rtaSize + 1);
@ -481,8 +473,7 @@ interpretAddr(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList,
} }
} }
struct ifaddrs *l_entry = struct ifaddrs* l_entry = malloc(sizeof(struct ifaddrs) + l_nameSize + l_addrSize);
malloc(sizeof(struct ifaddrs) + l_nameSize + l_addrSize);
if (l_entry == NULL) if (l_entry == NULL)
{ {
return -1; return -1;
@ -500,8 +491,7 @@ interpretAddr(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList,
} }
l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifaddrmsg)); l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifaddrmsg));
for(l_rta = IFA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); for (l_rta = IFA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
l_rta = RTA_NEXT(l_rta, l_rtaSize))
{ {
void* l_rtaData = RTA_DATA(l_rta); void* l_rtaData = RTA_DATA(l_rta);
size_t l_rtaDataSize = RTA_PAYLOAD(l_rta); size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
@ -512,8 +502,7 @@ interpretAddr(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList,
case IFA_LOCAL: case IFA_LOCAL:
{ {
size_t l_addrLen = calcAddrLen(l_info->ifa_family, l_rtaDataSize); size_t l_addrLen = calcAddrLen(l_info->ifa_family, l_rtaDataSize);
makeSockaddr(l_info->ifa_family, (struct sockaddr *)l_addr, l_rtaData, makeSockaddr(l_info->ifa_family, (struct sockaddr*)l_addr, l_rtaData, l_rtaDataSize);
l_rtaDataSize);
if (l_info->ifa_family == AF_INET6) if (l_info->ifa_family == AF_INET6)
{ {
if (IN6_IS_ADDR_LINKLOCAL((struct in6_addr*)l_rtaData) if (IN6_IS_ADDR_LINKLOCAL((struct in6_addr*)l_rtaData)
@ -561,13 +550,10 @@ interpretAddr(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList,
} }
if (l_entry->ifa_addr if (l_entry->ifa_addr
&& (l_entry->ifa_addr->sa_family == AF_INET && (l_entry->ifa_addr->sa_family == AF_INET || l_entry->ifa_addr->sa_family == AF_INET6))
|| l_entry->ifa_addr->sa_family == AF_INET6))
{ {
unsigned l_maxPrefix = (l_entry->ifa_addr->sa_family == AF_INET ? 32 : 128); unsigned l_maxPrefix = (l_entry->ifa_addr->sa_family == AF_INET ? 32 : 128);
unsigned l_prefix = unsigned l_prefix = (l_info->ifa_prefixlen > l_maxPrefix ? l_maxPrefix : l_info->ifa_prefixlen);
(l_info->ifa_prefixlen > l_maxPrefix ? l_maxPrefix
: l_info->ifa_prefixlen);
char l_mask[16] = {0}; char l_mask[16] = {0};
unsigned i; unsigned i;
for (i = 0; i < (l_prefix / 8); ++i) for (i = 0; i < (l_prefix / 8); ++i)
@ -579,8 +565,7 @@ interpretAddr(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList,
l_mask[i] = 0xff << (8 - (l_prefix % 8)); l_mask[i] = 0xff << (8 - (l_prefix % 8));
} }
makeSockaddr(l_entry->ifa_addr->sa_family, (struct sockaddr *)l_addr, makeSockaddr(l_entry->ifa_addr->sa_family, (struct sockaddr*)l_addr, l_mask, l_maxPrefix / 8);
l_mask, l_maxPrefix / 8);
l_entry->ifa_netmask = (struct sockaddr*)l_addr; l_entry->ifa_netmask = (struct sockaddr*)l_addr;
} }
@ -589,8 +574,7 @@ interpretAddr(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList,
} }
static int static int
interpretLinks(int p_socket, NetlinkList *p_netlinkList, interpretLinks(int p_socket, NetlinkList* p_netlinkList, struct ifaddrs** p_resultList)
struct ifaddrs **p_resultList)
{ {
int l_numLinks = 0; int l_numLinks = 0;
pid_t l_pid = getpid(); pid_t l_pid = getpid();
@ -625,8 +609,8 @@ interpretLinks(int p_socket, NetlinkList *p_netlinkList,
} }
static int static int
interpretAddrs(int p_socket, NetlinkList *p_netlinkList, interpretAddrs(
struct ifaddrs **p_resultList, int p_numLinks) int p_socket, NetlinkList* p_netlinkList, struct ifaddrs** p_resultList, int p_numLinks)
{ {
pid_t l_pid = getpid(); pid_t l_pid = getpid();
for (; p_netlinkList; p_netlinkList = p_netlinkList->m_next) for (; p_netlinkList; p_netlinkList = p_netlinkList->m_next)
@ -690,8 +674,7 @@ getifaddrs(struct ifaddrs **ifap)
int l_result = 0; int l_result = 0;
int l_numLinks = interpretLinks(l_socket, l_linkResults, ifap); int l_numLinks = interpretLinks(l_socket, l_linkResults, ifap);
if(l_numLinks == -1 if (l_numLinks == -1 || interpretAddrs(l_socket, l_addrResults, ifap, l_numLinks) == -1)
|| interpretAddrs(l_socket, l_addrResults, ifap, l_numLinks) == -1)
{ {
l_result = -1; l_result = -1;
} }

@ -309,8 +309,8 @@ namespace llarp
if (key == "*") if (key == "*")
{ {
m_OutboundLink = std::make_tuple( m_OutboundLink =
"*", AF_INET, fromEnv(proto, "OUTBOUND_PORT"), std::move(opts)); std::make_tuple("*", AF_INET, fromEnv(proto, "OUTBOUND_PORT"), std::move(opts));
} }
else else
{ {
@ -438,8 +438,8 @@ namespace llarp
} }
else else
{ {
LogError("failed to open log file at '", val, LogError(
"' for an unknown reason, bailing tf out kbai"); "failed to open log file at '", val, "' for an unknown reason, bailing tf out kbai");
::abort(); ::abort();
} }
} }
@ -533,8 +533,7 @@ namespace llarp
/// fname should be a relative path (from CWD) or absolute path to the config /// fname should be a relative path (from CWD) or absolute path to the config
/// file /// file
extern "C" bool extern "C" bool
llarp_ensure_config(const char *fname, const char *basedir, bool overwrite, llarp_ensure_config(const char* fname, const char* basedir, bool overwrite, bool asRouter)
bool asRouter)
{ {
if (Lokinet_INIT()) if (Lokinet_INIT())
return false; return false;
@ -578,8 +577,7 @@ llarp_ensure_config(const char *fname, const char *basedir, bool overwrite,
} }
// write fname ini // write fname ini
auto optional_f = auto optional_f = llarp::util::OpenFileStream<std::ofstream>(fname, std::ios::binary);
llarp::util::OpenFileStream< std::ofstream >(fname, std::ios::binary);
if (!optional_f || !optional_f.value().is_open()) if (!optional_f || !optional_f.value().is_open())
{ {
llarp::LogError("failed to open ", fname, " for writing"); llarp::LogError("failed to open ", fname, " for writing");
@ -600,8 +598,7 @@ llarp_ensure_config(const char *fname, const char *basedir, bool overwrite,
} }
void void
llarp_generic_ensure_config(std::ofstream &f, std::string basepath, llarp_generic_ensure_config(std::ofstream& f, std::string basepath, bool isRouter)
bool isRouter)
{ {
f << "# this configuration was auto generated with 'sane' defaults\n"; f << "# this configuration was auto generated with 'sane' defaults\n";
f << "# change these values as desired\n"; f << "# change these values as desired\n";
@ -618,8 +615,7 @@ llarp_generic_ensure_config(std::ofstream &f, std::string basepath,
f << "# encryption key for onion routing\n"; f << "# encryption key for onion routing\n";
f << "encryption-privkey=" << basepath << "encryption.private\n"; f << "encryption-privkey=" << basepath << "encryption.private\n";
f << std::endl; f << std::endl;
f << "# uncomment following line to set router nickname to 'lokinet'" f << "# uncomment following line to set router nickname to 'lokinet'" << std::endl;
<< std::endl;
f << "#nickname=lokinet\n"; f << "#nickname=lokinet\n";
const auto limits = isRouter ? llarp::limits::snode : llarp::limits::client; const auto limits = isRouter ? llarp::limits::snode : llarp::limits::client;
@ -739,8 +735,7 @@ llarp_ensure_client_config(std::ofstream &f, std::string basepath)
// write snapp-example.ini // write snapp-example.ini
const std::string snappExample_fpath = basepath + "snapp-example.ini"; const std::string snappExample_fpath = basepath + "snapp-example.ini";
{ {
auto stream = llarp::util::OpenFileStream< std::ofstream >( auto stream = llarp::util::OpenFileStream<std::ofstream>(snappExample_fpath, std::ios::binary);
snappExample_fpath, std::ios::binary);
if (!stream) if (!stream)
{ {
return false; return false;

@ -271,8 +271,7 @@ namespace llarp
} // namespace llarp } // namespace llarp
void void
llarp_generic_ensure_config(std::ofstream& f, std::string basepath, llarp_generic_ensure_config(std::ofstream& f, std::string basepath, bool isRouter);
bool isRouter);
void void
llarp_ensure_router_config(std::ofstream& f, std::string basepath); llarp_ensure_router_config(std::ofstream& f, std::string basepath);

@ -143,8 +143,7 @@ namespace llarp
} }
void void
ConfigParser::IterAll( ConfigParser::IterAll(std::function<void(string_view, const Section_t&)> visit)
std::function< void(string_view, const Section_t&) > visit)
{ {
for (const auto& item : m_Config) for (const auto& item : m_Config)
visit(item.first, item.second); visit(item.first, item.second);
@ -152,8 +151,7 @@ namespace llarp
bool bool
ConfigParser::VisitSection( ConfigParser::VisitSection(
const char* name, const char* name, std::function<bool(const Section_t& sect)> visit) const
std::function< bool(const Section_t& sect) > visit) const
{ {
auto itr = m_Config.find(name); auto itr = m_Config.find(name);
if (itr == m_Config.end()) if (itr == m_Config.end())

@ -37,8 +37,7 @@ namespace llarp
/// visit a section in config read only by name /// visit a section in config read only by name
/// return false if no section or value propagated from visitor /// return false if no section or value propagated from visitor
bool bool
VisitSection(const char* name, VisitSection(const char* name, std::function<bool(const Section_t&)> visit) const;
std::function< bool(const Section_t&) > visit) const;
private: private:
bool bool

@ -65,7 +65,9 @@ namespace llarp
} }
else else
{ {
LogWarn("Our RouterContact ", m_rcPath, LogWarn(
"Our RouterContact ",
m_rcPath,
" seems out of date, backing up and regenerating private keys"); " seems out of date, backing up and regenerating private keys");
if (!backupKeyFilesByMoving()) if (!backupKeyFilesByMoving())
@ -133,8 +135,7 @@ namespace llarp
bool exists = fs::exists(filepath, ec); bool exists = fs::exists(filepath, ec);
if (ec) if (ec)
{ {
LogError("Could not determine status of file ", filepath, ": ", LogError("Could not determine status of file ", filepath, ": ", ec.message());
ec.message());
return false; return false;
} }
@ -151,8 +152,7 @@ namespace llarp
return false; return false;
} }
LogInfo("Backing up (moving) key file ", filepath, " to ", newFilepath, LogInfo("Backing up (moving) key file ", filepath, " to ", newFilepath, "...");
"...");
fs::rename(filepath, newFilepath, ec); fs::rename(filepath, newFilepath, ec);
if (ec) if (ec)
@ -167,8 +167,7 @@ namespace llarp
bool bool
KeyManager::backupKeyFilesByMoving() const KeyManager::backupKeyFilesByMoving() const
{ {
std::vector< std::string > files = {m_rcPath, m_idKeyPath, m_encKeyPath, std::vector<std::string> files = {m_rcPath, m_idKeyPath, m_encKeyPath, m_transportKeyPath};
m_transportKeyPath};
for (auto& filepath : files) for (auto& filepath : files)
{ {
@ -181,7 +180,8 @@ namespace llarp
bool bool
KeyManager::loadOrCreateKey( KeyManager::loadOrCreateKey(
const std::string& filepath, llarp::SecretKey& key, const std::string& filepath,
llarp::SecretKey& key,
std::function<void(llarp::SecretKey& key)> keygen) std::function<void(llarp::SecretKey& key)> keygen)
{ {
fs::path path(filepath); fs::path path(filepath);
@ -230,9 +230,8 @@ namespace llarp
list = curl_slist_append(list, "Content-Type: application/json"); list = curl_slist_append(list, "Content-Type: application/json");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);
nlohmann::json request = {{"id", "0"}, nlohmann::json request = {
{"jsonrpc", "2.0"}, {"id", "0"}, {"jsonrpc", "2.0"}, {"method", "get_service_node_privkey"}};
{"method", "get_service_node_privkey"}};
const auto data = request.dump(); const auto data = request.dump();
std::vector<char> resp; std::vector<char> resp;
@ -256,8 +255,7 @@ namespace llarp
return false; return false;
if (not itr->is_object()) if (not itr->is_object())
return false; return false;
const auto k = const auto k = (*itr)["service_node_ed25519_privkey"].get<std::string>();
(*itr)["service_node_ed25519_privkey"].get< std::string >();
if (k.size() != (identityKey.size() * 2)) if (k.size() != (identityKey.size() * 2))
{ {
if (k.empty()) if (k.empty())
@ -292,8 +290,7 @@ namespace llarp
} }
if (ret) if (ret)
{ {
LogInfo("Got Identity Keys from lokid: ", LogInfo("Got Identity Keys from lokid: ", RouterID(seckey_topublic(identityKey)));
RouterID(seckey_topublic(identityKey)));
} }
curl_easy_cleanup(curl); curl_easy_cleanup(curl);
curl_slist_free_all(list); curl_slist_free_all(list);

@ -87,7 +87,9 @@ namespace llarp
/// ///
/// @param keygen is a function that will generate the key if needed /// @param keygen is a function that will generate the key if needed
static bool static bool
loadOrCreateKey(const std::string& filepath, llarp::SecretKey& key, loadOrCreateKey(
const std::string& filepath,
llarp::SecretKey& key,
std::function<void(llarp::SecretKey& key)> keygen); std::function<void(llarp::SecretKey& key)> keygen);
/// Requests the identity key from lokid via HTTP (curl) /// Requests the identity key from lokid via HTTP (curl)

@ -20,11 +20,9 @@ namespace llarp
/// default path lifetime in ms /// default path lifetime in ms
constexpr std::chrono::milliseconds default_lifetime = 20min; constexpr std::chrono::milliseconds default_lifetime = 20min;
/// minimum into lifetime we will advertise /// minimum into lifetime we will advertise
constexpr std::chrono::milliseconds min_intro_lifetime = constexpr std::chrono::milliseconds min_intro_lifetime = default_lifetime / 2;
default_lifetime / 2;
/// spacing frequency at which we try to build paths for introductions /// spacing frequency at which we try to build paths for introductions
constexpr std::chrono::milliseconds intro_path_spread = constexpr std::chrono::milliseconds intro_path_spread = default_lifetime / 5;
default_lifetime / 5;
/// Minimum paths to keep around for intros; mainly used at startup (the /// Minimum paths to keep around for intros; mainly used at startup (the
/// spread, above, should be able to maintain more than this number of paths /// spread, above, should be able to maintain more than this number of paths
/// normally once things are going). /// normally once things are going).

@ -13,8 +13,7 @@
#endif #endif
#if defined(_WIN32) && defined(RC_INVOKED) #if defined(_WIN32) && defined(RC_INVOKED)
#define LLARP_VERSION \ #define LLARP_VERSION LLARP_VERSION_MAJOR, LLARP_VERSION_MINOR, LLARP_VERSION_PATCH, 0
LLARP_VERSION_MAJOR, LLARP_VERSION_MINOR, LLARP_VERSION_PATCH, 0
#define MAKE_TRIPLET(X, Y, Z) TRIPLET_CAT(X, ., Y, ., Z) #define MAKE_TRIPLET(X, Y, Z) TRIPLET_CAT(X, ., Y, ., Z)
#define TRIPLET_CAT(X, D1, Y, D2, Z) X##D1##Y##D2##Z #define TRIPLET_CAT(X, D1, Y, D2, Z) X##D1##Y##D2##Z

@ -49,8 +49,7 @@ namespace llarp
auto threads = config->router.workerThreads(); auto threads = config->router.workerThreads();
if (threads <= 0) if (threads <= 0)
threads = 1; threads = 1;
worker = std::make_shared< llarp::thread::ThreadPool >(threads, 1024, worker = std::make_shared<llarp::thread::ThreadPool>(threads, 1024, "llarp-worker");
"llarp-worker");
auto jobQueueSize = config->router.jobQueueSize(); auto jobQueueSize = config->router.jobQueueSize();
if (jobQueueSize < 1024) if (jobQueueSize < 1024)
jobQueueSize = 1024; jobQueueSize = 1024;
@ -219,8 +218,7 @@ namespace llarp
if (router) if (router)
{ {
router->hiddenServiceContext().ForEachService( router->hiddenServiceContext().ForEachService(
[](const std::string &name, [](const std::string& name, const llarp::service::Endpoint_ptr& ep) -> bool {
const llarp::service::Endpoint_ptr &ep) -> bool {
ep->ResetInternalState(); ep->ResetInternalState();
llarp::LogInfo("Reset internal state for ", name); llarp::LogInfo("Reset internal state for ", name);
return true; return true;
@ -409,8 +407,7 @@ extern "C"
void void
llarp_main_signal(struct llarp_main* ptr, int sig) llarp_main_signal(struct llarp_main* ptr, int sig)
{ {
LogicCall(ptr->ctx->logic, LogicCall(ptr->ctx->logic, std::bind(&llarp::Context::HandleSignal, ptr->ctx.get(), sig));
std::bind(&llarp::Context::HandleSignal, ptr->ctx.get(), sig));
} }
int int
@ -432,8 +429,7 @@ extern "C"
} }
ssize_t ssize_t
llarp_vpn_io_readpkt(struct llarp_vpn_pkt_reader *r, unsigned char *dst, llarp_vpn_io_readpkt(struct llarp_vpn_pkt_reader* r, unsigned char* dst, size_t dstlen)
size_t dstlen)
{ {
if (r == nullptr) if (r == nullptr)
return -1; return -1;
@ -449,8 +445,7 @@ extern "C"
} }
bool bool
llarp_vpn_io_writepkt(struct llarp_vpn_pkt_writer *w, unsigned char *pktbuf, llarp_vpn_io_writepkt(struct llarp_vpn_pkt_writer* w, unsigned char* pktbuf, size_t pktlen)
size_t pktlen)
{ {
if (pktlen == 0 || pktbuf == nullptr) if (pktlen == 0 || pktbuf == nullptr)
return false; return false;
@ -460,12 +455,13 @@ extern "C"
llarp_buffer_t buf(pktbuf, pktlen); llarp_buffer_t buf(pktbuf, pktlen);
if (not pkt.Load(buf)) if (not pkt.Load(buf))
return false; return false;
return w->queue.pushBack(std::move(pkt)) return w->queue.pushBack(std::move(pkt)) == llarp::thread::QueueReturn::Success;
== llarp::thread::QueueReturn::Success;
} }
bool bool
llarp_main_inject_vpn_by_name(struct llarp_main *ptr, const char *name, llarp_main_inject_vpn_by_name(
struct llarp_main* ptr,
const char* name,
struct llarp_vpn_io* io, struct llarp_vpn_io* io,
struct llarp_vpn_ifaddr_info info) struct llarp_vpn_ifaddr_info info)
{ {

@ -26,30 +26,25 @@ namespace llarp
/// xchacha symmetric cipher /// xchacha symmetric cipher
virtual bool virtual bool
xchacha20(const llarp_buffer_t &, const SharedSecret &, xchacha20(const llarp_buffer_t&, const SharedSecret&, const TunnelNonce&) = 0;
const TunnelNonce &) = 0;
/// xchacha symmetric cipher (multibuffer) /// xchacha symmetric cipher (multibuffer)
virtual bool virtual bool
xchacha20_alt(const llarp_buffer_t &, const llarp_buffer_t &, xchacha20_alt(
const SharedSecret &, const byte_t *) = 0; const llarp_buffer_t&, const llarp_buffer_t&, const SharedSecret&, const byte_t*) = 0;
/// path dh creator's side /// path dh creator's side
virtual bool virtual bool
dh_client(SharedSecret &, const PubKey &, const SecretKey &, dh_client(SharedSecret&, const PubKey&, const SecretKey&, const TunnelNonce&) = 0;
const TunnelNonce &) = 0;
/// path dh relay side /// path dh relay side
virtual bool virtual bool
dh_server(SharedSecret &, const PubKey &, const SecretKey &, dh_server(SharedSecret&, const PubKey&, const SecretKey&, const TunnelNonce&) = 0;
const TunnelNonce &) = 0;
/// transport dh client side /// transport dh client side
virtual bool virtual bool
transport_dh_client(SharedSecret &, const PubKey &, const SecretKey &, transport_dh_client(SharedSecret&, const PubKey&, const SecretKey&, const TunnelNonce&) = 0;
const TunnelNonce &) = 0;
/// transport dh server side /// transport dh server side
virtual bool virtual bool
transport_dh_server(SharedSecret &, const PubKey &, const SecretKey &, transport_dh_server(SharedSecret&, const PubKey&, const SecretKey&, const TunnelNonce&) = 0;
const TunnelNonce &) = 0;
/// blake2b 256 bit /// blake2b 256 bit
virtual bool virtual bool
shorthash(ShortHash&, const llarp_buffer_t&) = 0; shorthash(ShortHash&, const llarp_buffer_t&) = 0;
@ -68,13 +63,12 @@ namespace llarp
/// derive sub keys for public keys /// derive sub keys for public keys
virtual bool virtual bool
derive_subkey(PubKey &, const PubKey &, uint64_t, derive_subkey(PubKey&, const PubKey&, uint64_t, const AlignedBuffer<32>* = nullptr) = 0;
const AlignedBuffer< 32 > * = nullptr) = 0;
/// derive sub keys for private keys /// derive sub keys for private keys
virtual bool virtual bool
derive_subkey_private(PrivateKey &, const SecretKey &, uint64_t, derive_subkey_private(
const AlignedBuffer< 32 > * = nullptr) = 0; PrivateKey&, const SecretKey&, uint64_t, const AlignedBuffer<32>* = nullptr) = 0;
/// seed to secretkey /// seed to secretkey
virtual bool virtual bool

@ -23,8 +23,11 @@ namespace llarp
namespace sodium namespace sodium
{ {
static bool static bool
dh(llarp::SharedSecret &out, const PubKey &client_pk, dh(llarp::SharedSecret& out,
const PubKey &server_pk, const uint8_t *themPub, const SecretKey &usSec) const PubKey& client_pk,
const PubKey& server_pk,
const uint8_t* themPub,
const SecretKey& usSec)
{ {
llarp::SharedSecret shared; llarp::SharedSecret shared;
crypto_generichash_state h; crypto_generichash_state h;
@ -42,15 +45,14 @@ namespace llarp
} }
static bool static bool
dh_client_priv(llarp::SharedSecret &shared, const PubKey &pk, dh_client_priv(
const SecretKey &sk, const TunnelNonce &n) llarp::SharedSecret& shared, const PubKey& pk, const SecretKey& sk, const TunnelNonce& n)
{ {
llarp::SharedSecret dh_result; llarp::SharedSecret dh_result;
if (dh(dh_result, sk.toPublic(), pk, pk.data(), sk)) if (dh(dh_result, sk.toPublic(), pk, pk.data(), sk))
{ {
return crypto_generichash_blake2b(shared.data(), 32, n.data(), 32, return crypto_generichash_blake2b(shared.data(), 32, n.data(), 32, dh_result.data(), 32)
dh_result.data(), 32)
!= -1; != -1;
} }
llarp::LogWarn("crypto::dh_client - dh failed"); llarp::LogWarn("crypto::dh_client - dh failed");
@ -58,14 +60,13 @@ namespace llarp
} }
static bool static bool
dh_server_priv(llarp::SharedSecret &shared, const PubKey &pk, dh_server_priv(
const SecretKey &sk, const TunnelNonce &n) llarp::SharedSecret& shared, const PubKey& pk, const SecretKey& sk, const TunnelNonce& n)
{ {
llarp::SharedSecret dh_result; llarp::SharedSecret dh_result;
if (dh(dh_result, pk, sk.toPublic(), pk.data(), sk)) if (dh(dh_result, pk, sk.toPublic(), pk.data(), sk))
{ {
return crypto_generichash_blake2b(shared.data(), 32, n.data(), 32, return crypto_generichash_blake2b(shared.data(), 32, n.data(), 32, dh_result.data(), 32)
dh_result.data(), 32)
!= -1; != -1;
} }
llarp::LogWarn("crypto::dh_server - dh failed"); llarp::LogWarn("crypto::dh_server - dh failed");
@ -93,51 +94,45 @@ namespace llarp
} }
bool bool
CryptoLibSodium::xchacha20(const llarp_buffer_t &buff, CryptoLibSodium::xchacha20(
const SharedSecret &k, const TunnelNonce &n) const llarp_buffer_t& buff, const SharedSecret& k, const TunnelNonce& n)
{ {
return crypto_stream_xchacha20_xor(buff.base, buff.base, buff.sz, return crypto_stream_xchacha20_xor(buff.base, buff.base, buff.sz, n.data(), k.data()) == 0;
n.data(), k.data())
== 0;
} }
bool bool
CryptoLibSodium::xchacha20_alt(const llarp_buffer_t &out, CryptoLibSodium::xchacha20_alt(
const llarp_buffer_t &in, const llarp_buffer_t& out, const llarp_buffer_t& in, const SharedSecret& k, const byte_t* n)
const SharedSecret &k, const byte_t *n)
{ {
if (in.sz > out.sz) if (in.sz > out.sz)
return false; return false;
return crypto_stream_xchacha20_xor(out.base, in.base, in.sz, n, k.data()) return crypto_stream_xchacha20_xor(out.base, in.base, in.sz, n, k.data()) == 0;
== 0;
} }
bool bool
CryptoLibSodium::dh_client(llarp::SharedSecret &shared, const PubKey &pk, CryptoLibSodium::dh_client(
const SecretKey &sk, const TunnelNonce &n) llarp::SharedSecret& shared, const PubKey& pk, const SecretKey& sk, const TunnelNonce& n)
{ {
return dh_client_priv(shared, pk, sk, n); return dh_client_priv(shared, pk, sk, n);
} }
/// path dh relay side /// path dh relay side
bool bool
CryptoLibSodium::dh_server(llarp::SharedSecret &shared, const PubKey &pk, CryptoLibSodium::dh_server(
const SecretKey &sk, const TunnelNonce &n) llarp::SharedSecret& shared, const PubKey& pk, const SecretKey& sk, const TunnelNonce& n)
{ {
return dh_server_priv(shared, pk, sk, n); return dh_server_priv(shared, pk, sk, n);
} }
/// transport dh client side /// transport dh client side
bool bool
CryptoLibSodium::transport_dh_client(llarp::SharedSecret &shared, CryptoLibSodium::transport_dh_client(
const PubKey &pk, const SecretKey &sk, llarp::SharedSecret& shared, const PubKey& pk, const SecretKey& sk, const TunnelNonce& n)
const TunnelNonce &n)
{ {
return dh_client_priv(shared, pk, sk, n); return dh_client_priv(shared, pk, sk, n);
} }
/// transport dh server side /// transport dh server side
bool bool
CryptoLibSodium::transport_dh_server(llarp::SharedSecret &shared, CryptoLibSodium::transport_dh_server(
const PubKey &pk, const SecretKey &sk, llarp::SharedSecret& shared, const PubKey& pk, const SecretKey& sk, const TunnelNonce& n)
const TunnelNonce &n)
{ {
return dh_server_priv(shared, pk, sk, n); return dh_server_priv(shared, pk, sk, n);
} }
@ -145,40 +140,33 @@ namespace llarp
bool bool
CryptoLibSodium::shorthash(ShortHash& result, const llarp_buffer_t& buff) CryptoLibSodium::shorthash(ShortHash& result, const llarp_buffer_t& buff)
{ {
return crypto_generichash_blake2b(result.data(), ShortHash::SIZE, return crypto_generichash_blake2b(
buff.base, buff.sz, nullptr, 0) result.data(), ShortHash::SIZE, buff.base, buff.sz, nullptr, 0)
!= -1; != -1;
} }
bool bool
CryptoLibSodium::hmac(byte_t *result, const llarp_buffer_t &buff, CryptoLibSodium::hmac(byte_t* result, const llarp_buffer_t& buff, const SharedSecret& secret)
const SharedSecret &secret)
{ {
return crypto_generichash_blake2b(result, HMACSIZE, buff.base, buff.sz, return crypto_generichash_blake2b(
secret.data(), HMACSECSIZE) result, HMACSIZE, buff.base, buff.sz, secret.data(), HMACSECSIZE)
!= -1; != -1;
} }
static bool static bool
hash(uint8_t* result, const llarp_buffer_t& buff) hash(uint8_t* result, const llarp_buffer_t& buff)
{ {
return crypto_generichash_blake2b(result, HASHSIZE, buff.base, buff.sz, return crypto_generichash_blake2b(result, HASHSIZE, buff.base, buff.sz, nullptr, 0) != -1;
nullptr, 0)
!= -1;
} }
bool bool
CryptoLibSodium::sign(Signature &sig, const SecretKey &secret, CryptoLibSodium::sign(Signature& sig, const SecretKey& secret, const llarp_buffer_t& buf)
const llarp_buffer_t &buf)
{ {
return crypto_sign_detached(sig.data(), nullptr, buf.base, buf.sz, return crypto_sign_detached(sig.data(), nullptr, buf.base, buf.sz, secret.data()) != -1;
secret.data())
!= -1;
} }
bool bool
CryptoLibSodium::sign(Signature &sig, const PrivateKey &privkey, CryptoLibSodium::sign(Signature& sig, const PrivateKey& privkey, const llarp_buffer_t& buf)
const llarp_buffer_t &buf)
{ {
PubKey pubkey; PubKey pubkey;
@ -222,12 +210,9 @@ namespace llarp
} }
bool bool
CryptoLibSodium::verify(const PubKey &pub, const llarp_buffer_t &buf, CryptoLibSodium::verify(const PubKey& pub, const llarp_buffer_t& buf, const Signature& sig)
const Signature &sig)
{ {
return crypto_sign_verify_detached(sig.data(), buf.base, buf.sz, return crypto_sign_verify_detached(sig.data(), buf.base, buf.sz, pub.data()) != -1;
pub.data())
!= -1;
} }
/// clamp a 32 byte ec point /// clamp a 32 byte ec point
@ -263,7 +248,8 @@ namespace llarp
"to read? lokinet yolo!"; "to read? lokinet yolo!";
template <typename K> template <typename K>
static bool make_scalar(AlignedBuffer< 32 > &out, const K &k, uint64_t i) static bool
make_scalar(AlignedBuffer<32>& out, const K& k, uint64_t i)
{ {
// b = BLIND-STRING || k || i // b = BLIND-STRING || k || i
std::array<byte_t, 160 + K::SIZE + sizeof(uint64_t)> buf; std::array<byte_t, 160 + K::SIZE + sizeof(uint64_t)> buf;
@ -274,16 +260,18 @@ namespace llarp
// h = make_point(n) // h = make_point(n)
ShortHash n; ShortHash n;
return -1 return -1
!= crypto_generichash_blake2b(n.data(), ShortHash::SIZE, buf.data(), != crypto_generichash_blake2b(
buf.size(), nullptr, 0) n.data(), ShortHash::SIZE, buf.data(), buf.size(), nullptr, 0)
&& -1 != crypto_core_ed25519_from_uniform(out.data(), n.data()); && -1 != crypto_core_ed25519_from_uniform(out.data(), n.data());
} }
static AlignedBuffer<32> zero; static AlignedBuffer<32> zero;
bool bool
CryptoLibSodium::derive_subkey(PubKey &out_pubkey, CryptoLibSodium::derive_subkey(
const PubKey &root_pubkey, uint64_t key_n, PubKey& out_pubkey,
const PubKey& root_pubkey,
uint64_t key_n,
const AlignedBuffer<32>* hash) const AlignedBuffer<32>* hash)
{ {
// scalar h = H( BLIND-STRING || root_pubkey || key_n ) // scalar h = H( BLIND-STRING || root_pubkey || key_n )
@ -296,13 +284,12 @@ namespace llarp
return false; return false;
} }
return 0 return 0 == crypto_scalarmult_ed25519(out_pubkey.data(), h.data(), root_pubkey.data());
== crypto_scalarmult_ed25519(out_pubkey.data(), h.data(),
root_pubkey.data());
} }
bool bool
CryptoLibSodium::derive_subkey_private(PrivateKey &out_key, CryptoLibSodium::derive_subkey_private(
PrivateKey& out_key,
const SecretKey& root_key, const SecretKey& root_key,
uint64_t key_n, uint64_t key_n,
const AlignedBuffer<32>* hash) const AlignedBuffer<32>* hash)
@ -364,19 +351,16 @@ namespace llarp
std::copy(h.begin(), h.end(), buf.begin()); std::copy(h.begin(), h.end(), buf.begin());
std::copy(a.signingHash(), a.signingHash() + 32, buf.begin() + 32); std::copy(a.signingHash(), a.signingHash() + 32, buf.begin() + 32);
return -1 return -1
!= crypto_generichash_blake2b(out_key.signingHash(), 32, buf.data(), != crypto_generichash_blake2b(
buf.size(), nullptr, 0); out_key.signingHash(), 32, buf.data(), buf.size(), nullptr, 0);
return true; return true;
} }
bool bool
CryptoLibSodium::seed_to_secretkey(llarp::SecretKey &secret, CryptoLibSodium::seed_to_secretkey(llarp::SecretKey& secret, const llarp::IdentitySecret& seed)
const llarp::IdentitySecret &seed)
{ {
return crypto_sign_ed25519_seed_keypair(secret.data() + 32, secret.data(), return crypto_sign_ed25519_seed_keypair(secret.data() + 32, secret.data(), seed.data()) != -1;
seed.data())
!= -1;
} }
void void
CryptoLibSodium::randomize(const llarp_buffer_t& buff) CryptoLibSodium::randomize(const llarp_buffer_t& buff)
@ -426,20 +410,16 @@ namespace llarp
} }
bool bool
CryptoLibSodium::pqe_encrypt(PQCipherBlock &ciphertext, CryptoLibSodium::pqe_encrypt(
SharedSecret &sharedkey, PQCipherBlock& ciphertext, SharedSecret& sharedkey, const PQPubKey& pubkey)
const PQPubKey &pubkey)
{ {
return crypto_kem_enc(ciphertext.data(), sharedkey.data(), pubkey.data()) return crypto_kem_enc(ciphertext.data(), sharedkey.data(), pubkey.data()) != -1;
!= -1;
} }
bool bool
CryptoLibSodium::pqe_decrypt(const PQCipherBlock &ciphertext, CryptoLibSodium::pqe_decrypt(
SharedSecret &sharedkey, const PQCipherBlock& ciphertext, SharedSecret& sharedkey, const byte_t* secretkey)
const byte_t *secretkey)
{ {
return crypto_kem_dec(sharedkey.data(), ciphertext.data(), secretkey) return crypto_kem_dec(sharedkey.data(), ciphertext.data(), secretkey) != -1;
!= -1;
} }
void void

@ -15,30 +15,30 @@ namespace llarp
/// xchacha symmetric cipher /// xchacha symmetric cipher
bool bool
xchacha20(const llarp_buffer_t &, const SharedSecret &, xchacha20(const llarp_buffer_t&, const SharedSecret&, const TunnelNonce&) override;
const TunnelNonce &) override;
/// xchacha symmetric cipher (multibuffer) /// xchacha symmetric cipher (multibuffer)
bool bool
xchacha20_alt(const llarp_buffer_t &, const llarp_buffer_t &, xchacha20_alt(
const SharedSecret &, const byte_t *) override; const llarp_buffer_t&,
const llarp_buffer_t&,
const SharedSecret&,
const byte_t*) override;
/// path dh creator's side /// path dh creator's side
bool bool
dh_client(SharedSecret &, const PubKey &, const SecretKey &, dh_client(SharedSecret&, const PubKey&, const SecretKey&, const TunnelNonce&) override;
const TunnelNonce &) override;
/// path dh relay side /// path dh relay side
bool bool
dh_server(SharedSecret &, const PubKey &, const SecretKey &, dh_server(SharedSecret&, const PubKey&, const SecretKey&, const TunnelNonce&) override;
const TunnelNonce &) override;
/// transport dh client side /// transport dh client side
bool bool
transport_dh_client(SharedSecret &, const PubKey &, const SecretKey &, transport_dh_client(
const TunnelNonce &) override; SharedSecret&, const PubKey&, const SecretKey&, const TunnelNonce&) override;
/// transport dh server side /// transport dh server side
bool bool
transport_dh_server(SharedSecret &, const PubKey &, const SecretKey &, transport_dh_server(
const TunnelNonce &) override; SharedSecret&, const PubKey&, const SecretKey&, const TunnelNonce&) override;
/// blake2b 256 bit /// blake2b 256 bit
bool bool
shorthash(ShortHash&, const llarp_buffer_t&) override; shorthash(ShortHash&, const llarp_buffer_t&) override;
@ -53,26 +53,29 @@ namespace llarp
sign(Signature&, const PrivateKey&, const llarp_buffer_t&) override; sign(Signature&, const PrivateKey&, const llarp_buffer_t&) override;
/// ed25519 verify /// ed25519 verify
bool bool
verify(const PubKey &, const llarp_buffer_t &, verify(const PubKey&, const llarp_buffer_t&, const Signature&) override;
const Signature &) override;
/// derive sub keys for public keys. hash is really only intended for /// derive sub keys for public keys. hash is really only intended for
/// testing and overrides key_n if given. /// testing and overrides key_n if given.
bool bool
derive_subkey(PubKey &derived, const PubKey &root, uint64_t key_n, derive_subkey(
PubKey& derived,
const PubKey& root,
uint64_t key_n,
const AlignedBuffer<32>* hash = nullptr) override; const AlignedBuffer<32>* hash = nullptr) override;
/// derive sub keys for private keys. hash is really only intended for /// derive sub keys for private keys. hash is really only intended for
/// testing and overrides key_n if given. /// testing and overrides key_n if given.
bool bool
derive_subkey_private(PrivateKey &derived, const SecretKey &root, derive_subkey_private(
PrivateKey& derived,
const SecretKey& root,
uint64_t key_n, uint64_t key_n,
const AlignedBuffer<32>* hash = nullptr) override; const AlignedBuffer<32>* hash = nullptr) override;
/// seed to secretkey /// seed to secretkey
bool bool
seed_to_secretkey(llarp::SecretKey &, seed_to_secretkey(llarp::SecretKey&, const llarp::IdentitySecret&) override;
const llarp::IdentitySecret &) override;
/// randomize buffer /// randomize buffer
void void
randomize(const llarp_buffer_t&) override; randomize(const llarp_buffer_t&) override;
@ -90,8 +93,7 @@ namespace llarp
pqe_keygen(PQKeyPair&) override; pqe_keygen(PQKeyPair&) override;
/// post quantum decrypt (buffer, sharedkey_dst, sec) /// post quantum decrypt (buffer, sharedkey_dst, sec)
bool bool
pqe_decrypt(const PQCipherBlock &, SharedSecret &, pqe_decrypt(const PQCipherBlock&, SharedSecret&, const byte_t*) override;
const byte_t *) override;
/// post quantum encrypt (buffer, sharedkey_dst, pub) /// post quantum encrypt (buffer, sharedkey_dst, pub)
bool bool
pqe_encrypt(PQCipherBlock&, SharedSecret&, const PQPubKey&) override; pqe_encrypt(PQCipherBlock&, SharedSecret&, const PQPubKey&) override;

@ -23,15 +23,17 @@ namespace llarp
~NoOpCrypto() override = default; ~NoOpCrypto() override = default;
bool bool
xchacha20(const llarp_buffer_t &, const SharedSecret &, xchacha20(const llarp_buffer_t&, const SharedSecret&, const TunnelNonce&) override
const TunnelNonce &) override
{ {
return true; return true;
} }
bool bool
xchacha20_alt(const llarp_buffer_t &out, const llarp_buffer_t &in, xchacha20_alt(
const SharedSecret &, const byte_t *) override const llarp_buffer_t& out,
const llarp_buffer_t& in,
const SharedSecret&,
const byte_t*) override
{ {
if (in.sz > out.sz) if (in.sz > out.sz)
{ {
@ -43,32 +45,30 @@ namespace llarp
} }
bool bool
dh_client(SharedSecret &shared, const PubKey &pk, const SecretKey &, dh_client(SharedSecret& shared, const PubKey& pk, const SecretKey&, const TunnelNonce&) override
const TunnelNonce &) override
{ {
std::copy_n(pk.begin(), pk.size(), shared.begin()); std::copy_n(pk.begin(), pk.size(), shared.begin());
return true; return true;
} }
bool bool
dh_server(SharedSecret &shared, const PubKey &pk, const SecretKey &, dh_server(SharedSecret& shared, const PubKey& pk, const SecretKey&, const TunnelNonce&) override
const TunnelNonce &) override
{ {
std::copy_n(pk.begin(), pk.size(), shared.begin()); std::copy_n(pk.begin(), pk.size(), shared.begin());
return true; return true;
} }
bool bool
transport_dh_client(SharedSecret &shared, const PubKey &pk, transport_dh_client(
const SecretKey &, const TunnelNonce &) override SharedSecret& shared, const PubKey& pk, const SecretKey&, const TunnelNonce&) override
{ {
std::copy_n(pk.begin(), pk.size(), shared.begin()); std::copy_n(pk.begin(), pk.size(), shared.begin());
return true; return true;
} }
bool bool
transport_dh_server(SharedSecret &shared, const PubKey &pk, transport_dh_server(
const SecretKey &, const TunnelNonce &) override SharedSecret& shared, const PubKey& pk, const SecretKey&, const TunnelNonce&) override
{ {
std::copy_n(pk.begin(), pk.size(), shared.begin()); std::copy_n(pk.begin(), pk.size(), shared.begin());
return true; return true;
@ -130,8 +130,7 @@ namespace llarp
{ {
static_assert(SecretKey::SIZE == (2 * IdentitySecret::SIZE), ""); static_assert(SecretKey::SIZE == (2 * IdentitySecret::SIZE), "");
std::copy(secret.begin(), secret.end(), key.begin()); std::copy(secret.begin(), secret.end(), key.begin());
std::copy(secret.begin(), secret.end(), std::copy(secret.begin(), secret.end(), key.begin() + IdentitySecret::SIZE);
key.begin() + IdentitySecret::SIZE);
return true; return true;
} }
@ -172,16 +171,14 @@ namespace llarp
} }
bool bool
pqe_decrypt(const PQCipherBlock &block, SharedSecret &secret, pqe_decrypt(const PQCipherBlock& block, SharedSecret& secret, const byte_t*) override
const byte_t *) override
{ {
std::copy_n(block.begin(), SharedSecret::SIZE, secret.begin()); std::copy_n(block.begin(), SharedSecret::SIZE, secret.begin());
return true; return true;
} }
bool bool
pqe_encrypt(PQCipherBlock &block, SharedSecret &secret, pqe_encrypt(PQCipherBlock& block, SharedSecret& secret, const PQPubKey&) override
const PQPubKey &) override
{ {
std::copy_n(secret.begin(), SharedSecret::SIZE, block.begin()); std::copy_n(secret.begin(), SharedSecret::SIZE, block.begin());
return true; return true;

@ -54,8 +54,7 @@ namespace llarp
} }
bool bool
EncryptedFrame::EncryptInPlace(const SecretKey& ourSecretKey, EncryptedFrame::EncryptInPlace(const SecretKey& ourSecretKey, const PubKey& otherPubkey)
const PubKey& otherPubkey)
{ {
// format of frame is // format of frame is
// <32 bytes keyed hash of following data> // <32 bytes keyed hash of following data>

@ -10,11 +10,9 @@
namespace llarp namespace llarp
{ {
static constexpr size_t EncryptedFrameOverheadSize = static constexpr size_t EncryptedFrameOverheadSize = PUBKEYSIZE + TUNNONCESIZE + SHORTHASHSIZE;
PUBKEYSIZE + TUNNONCESIZE + SHORTHASHSIZE;
static constexpr size_t EncryptedFrameBodySize = 128 * 6; static constexpr size_t EncryptedFrameBodySize = 128 * 6;
static constexpr size_t EncryptedFrameSize = static constexpr size_t EncryptedFrameSize = EncryptedFrameOverheadSize + EncryptedFrameBodySize;
EncryptedFrameOverheadSize + EncryptedFrameBodySize;
struct EncryptedFrame : public Encrypted<EncryptedFrameSize> struct EncryptedFrame : public Encrypted<EncryptedFrameSize>
{ {
@ -23,8 +21,8 @@ namespace llarp
} }
EncryptedFrame(size_t sz) EncryptedFrame(size_t sz)
: Encrypted< EncryptedFrameSize >(std::min(sz, EncryptedFrameBodySize) : Encrypted<EncryptedFrameSize>(
+ EncryptedFrameOverheadSize) std::min(sz, EncryptedFrameBodySize) + EncryptedFrameOverheadSize)
{ {
} }
@ -81,12 +79,11 @@ namespace llarp
EncryptedFrame target; EncryptedFrame target;
void void
AsyncDecrypt(const std::shared_ptr< thread::ThreadPool >& worker, AsyncDecrypt(
const EncryptedFrame& frame, User_ptr u) const std::shared_ptr<thread::ThreadPool>& worker, const EncryptedFrame& frame, User_ptr u)
{ {
target = frame; target = frame;
worker->addJob( worker->addJob(std::bind(&AsyncFrameDecrypter<User>::Decrypt, this, std::move(u)));
std::bind(&AsyncFrameDecrypter< User >::Decrypt, this, std::move(u)));
} }
}; };
} // namespace llarp } // namespace llarp

@ -98,8 +98,7 @@ namespace llarp
return false; return false;
} }
const fs::path fpath = std::string(fname); const fs::path fpath = std::string(fname);
auto optional_f = auto optional_f = llarp::util::OpenFileStream<std::ofstream>(fpath, std::ios::binary);
llarp::util::OpenFileStream< std::ofstream >(fpath, std::ios::binary);
if (!optional_f) if (!optional_f)
return false; return false;
auto& f = optional_f.value(); auto& f = optional_f.value();
@ -113,8 +112,7 @@ namespace llarp
IdentitySecret::LoadFromFile(const char* fname) IdentitySecret::LoadFromFile(const char* fname)
{ {
const fs::path fpath = std::string(fname); const fs::path fpath = std::string(fname);
auto optional = util::OpenFileStream< std::ifstream >( auto optional = util::OpenFileStream<std::ifstream>(fpath, std::ios::binary | std::ios::in);
fpath, std::ios::binary | std::ios::in);
if (!optional) if (!optional)
return false; return false;
auto& f = optional.value(); auto& f = optional.value();

@ -26,8 +26,7 @@ namespace llarp
{ {
} }
explicit PubKey(const AlignedBuffer< SIZE > &other) explicit PubKey(const AlignedBuffer<SIZE>& other) : AlignedBuffer<SIZE>(other)
: AlignedBuffer< SIZE >(other)
{ {
} }
@ -88,8 +87,7 @@ namespace llarp
} }
// The full data // The full data
explicit SecretKey(const AlignedBuffer< SECKEYSIZE > &seed) explicit SecretKey(const AlignedBuffer<SECKEYSIZE>& seed) : AlignedBuffer<SECKEYSIZE>(seed)
: AlignedBuffer< SECKEYSIZE >(seed)
{ {
} }
@ -151,8 +149,7 @@ namespace llarp
{ {
} }
explicit PrivateKey(const AlignedBuffer< 64 > &key_and_hash) explicit PrivateKey(const AlignedBuffer<64>& key_and_hash) : AlignedBuffer<64>(key_and_hash)
: AlignedBuffer< 64 >(key_and_hash)
{ {
} }
@ -244,16 +241,15 @@ namespace llarp
using PQKeyPair = AlignedBuffer<PQ_KEYPAIRSIZE>; using PQKeyPair = AlignedBuffer<PQ_KEYPAIRSIZE>;
/// PKE(result, publickey, secretkey, nonce) /// PKE(result, publickey, secretkey, nonce)
using path_dh_func = std::function< bool( using path_dh_func =
SharedSecret &, const PubKey &, const SecretKey &, const TunnelNonce &) >; std::function<bool(SharedSecret&, const PubKey&, const SecretKey&, const TunnelNonce&)>;
/// TKE(result, publickey, secretkey, nonce) /// TKE(result, publickey, secretkey, nonce)
using transport_dh_func = std::function< bool( using transport_dh_func =
SharedSecret &, const PubKey &, const SecretKey &, const TunnelNonce &) >; std::function<bool(SharedSecret&, const PubKey&, const SecretKey&, const TunnelNonce&)>;
/// SH(result, body) /// SH(result, body)
using shorthash_func = using shorthash_func = std::function<bool(ShortHash&, const llarp_buffer_t&)>;
std::function< bool(ShortHash &, const llarp_buffer_t &) >;
} // namespace llarp } // namespace llarp
#endif #endif

@ -19,8 +19,7 @@ namespace llarp
using BucketStorage_t = std::map<Key_t, Val_t, XorMetric>; using BucketStorage_t = std::map<Key_t, Val_t, XorMetric>;
using Random_t = std::function<uint64_t()>; using Random_t = std::function<uint64_t()>;
Bucket(const Key_t& us, Random_t r) Bucket(const Key_t& us, Random_t r) : nodes(XorMetric(us)), random(std::move(r))
: nodes(XorMetric(us)), random(std::move(r))
{ {
} }
@ -44,27 +43,28 @@ namespace llarp
struct SetIntersector struct SetIntersector
{ {
bool bool
operator()(const typename BucketStorage_t::value_type& lhs, operator()(const typename BucketStorage_t::value_type& lhs, const Key_t& rhs)
const Key_t& rhs)
{ {
return lhs.first < rhs; return lhs.first < rhs;
} }
bool bool
operator()(const Key_t& lhs, operator()(const Key_t& lhs, const typename BucketStorage_t::value_type& rhs)
const typename BucketStorage_t::value_type& rhs)
{ {
return lhs < rhs.first; return lhs < rhs.first;
} }
}; };
bool bool
GetRandomNodeExcluding(Key_t& result, GetRandomNodeExcluding(Key_t& result, const std::set<Key_t>& exclude) const
const std::set< Key_t >& exclude) const
{ {
std::vector<typename BucketStorage_t::value_type> candidates; std::vector<typename BucketStorage_t::value_type> candidates;
std::set_difference(nodes.begin(), nodes.end(), exclude.begin(), std::set_difference(
exclude.end(), std::back_inserter(candidates), nodes.begin(),
nodes.end(),
exclude.begin(),
exclude.end(),
std::back_inserter(candidates),
SetIntersector()); SetIntersector());
if (candidates.empty()) if (candidates.empty())
@ -97,15 +97,15 @@ namespace llarp
{ {
if (nodes.size() < N || nodes.empty()) if (nodes.size() < N || nodes.empty())
{ {
llarp::LogWarn("Not enough dht nodes, have ", nodes.size(), " want ", llarp::LogWarn("Not enough dht nodes, have ", nodes.size(), " want ", N);
N);
return false; return false;
} }
if (nodes.size() == N) if (nodes.size() == N)
{ {
std::transform(nodes.begin(), nodes.end(), std::transform(
std::inserter(result, result.end()), nodes.begin(), nodes.end(), std::inserter(result, result.end()), [](const auto& a) {
[](const auto& a) { return a.first; }); return a.first;
});
return true; return true;
} }
@ -124,8 +124,7 @@ namespace llarp
} }
bool bool
FindCloseExcluding(const Key_t& target, Key_t& result, FindCloseExcluding(const Key_t& target, Key_t& result, const std::set<Key_t>& exclude) const
const std::set< Key_t >& exclude) const
{ {
Key_t maxdist; Key_t maxdist;
maxdist.Fill(0xff); maxdist.Fill(0xff);
@ -149,8 +148,11 @@ namespace llarp
} }
bool bool
GetManyNearExcluding(const Key_t& target, std::set< Key_t >& result, GetManyNearExcluding(
size_t N, const std::set< Key_t >& exclude) const const Key_t& target,
std::set<Key_t>& result,
size_t N,
const std::set<Key_t>& exclude) const
{ {
std::set<Key_t> s(exclude.begin(), exclude.end()); std::set<Key_t> s(exclude.begin(), exclude.end());

@ -47,21 +47,29 @@ namespace llarp
void void
LookupIntroSetRelayed( LookupIntroSetRelayed(
const Key_t& target, const Key_t& whoasked, uint64_t whoaskedTX, const Key_t& target,
const Key_t& askpeer, uint64_t relayOrder, const Key_t& whoasked,
uint64_t whoaskedTX,
const Key_t& askpeer,
uint64_t relayOrder,
service::EncryptedIntroSetLookupHandler result = nullptr) override; service::EncryptedIntroSetLookupHandler result = nullptr) override;
void void
LookupIntroSetDirect( LookupIntroSetDirect(
const Key_t& target, const Key_t& whoasked, uint64_t whoaskedTX, const Key_t& target,
const Key_t& whoasked,
uint64_t whoaskedTX,
const Key_t& askpeer, const Key_t& askpeer,
service::EncryptedIntroSetLookupHandler result = nullptr) override; service::EncryptedIntroSetLookupHandler result = nullptr) override;
/// on behalf of whoasked request router with public key target from dht /// on behalf of whoasked request router with public key target from dht
/// router with key askpeer /// router with key askpeer
void void
LookupRouterRecursive(const RouterID& target, const Key_t& whoasked, LookupRouterRecursive(
uint64_t whoaskedTX, const Key_t& askpeer, const RouterID& target,
const Key_t& whoasked,
uint64_t whoaskedTX,
const Key_t& askpeer,
RouterLookupHandler result = nullptr) override; RouterLookupHandler result = nullptr) override;
bool bool
@ -84,51 +92,65 @@ namespace llarp
/// issue dht lookup for router via askpeer and send reply to local path /// issue dht lookup for router via askpeer and send reply to local path
void void
LookupRouterForPath(const RouterID& target, uint64_t txid, LookupRouterForPath(
const PathID_t& path, const Key_t& askpeer) override; const RouterID& target,
uint64_t txid,
const PathID_t& path,
const Key_t& askpeer) override;
/// issue dht lookup for introset for addr via askpeer and send reply to /// issue dht lookup for introset for addr via askpeer and send reply to
/// local path /// local path
void void
LookupIntroSetForPath(const Key_t& addr, uint64_t txid, LookupIntroSetForPath(
const llarp::PathID_t& path, const Key_t& askpeer, const Key_t& addr,
uint64_t txid,
const llarp::PathID_t& path,
const Key_t& askpeer,
uint64_t relayOrder) override; uint64_t relayOrder) override;
/// send a dht message to peer, if keepalive is true then keep the session /// send a dht message to peer, if keepalive is true then keep the session
/// with that peer alive for 10 seconds /// with that peer alive for 10 seconds
void void
DHTSendTo(const RouterID& peer, IMessage* msg, DHTSendTo(const RouterID& peer, IMessage* msg, bool keepalive = true) override;
bool keepalive = true) override;
/// get routers closest to target excluding requester /// get routers closest to target excluding requester
bool bool
HandleExploritoryRouterLookup( HandleExploritoryRouterLookup(
const Key_t& requester, uint64_t txid, const RouterID& target, const Key_t& requester,
uint64_t txid,
const RouterID& target,
std::vector<std::unique_ptr<IMessage>>& reply) override; std::vector<std::unique_ptr<IMessage>>& reply) override;
/// handle rc lookup from requester for target /// handle rc lookup from requester for target
void void
LookupRouterRelayed( LookupRouterRelayed(
const Key_t& requester, uint64_t txid, const Key_t& target, const Key_t& requester,
uint64_t txid,
const Key_t& target,
bool recursive, bool recursive,
std::vector<std::unique_ptr<IMessage>>& replies) override; std::vector<std::unique_ptr<IMessage>>& replies) override;
/// relay a dht message from a local path to the main network /// relay a dht message from a local path to the main network
bool bool
RelayRequestForPath(const llarp::PathID_t& localPath, RelayRequestForPath(const llarp::PathID_t& localPath, const IMessage& msg) override;
const IMessage& msg) override;
/// send introset to peer as R/S /// send introset to peer as R/S
void void
PropagateLocalIntroSet(const PathID_t& from, uint64_t txid, PropagateLocalIntroSet(
const PathID_t& from,
uint64_t txid,
const service::EncryptedIntroSet& introset, const service::EncryptedIntroSet& introset,
const Key_t& tellpeer, uint64_t relayOrder); const Key_t& tellpeer,
uint64_t relayOrder);
/// send introset to peer from source with S counter and excluding peers /// send introset to peer from source with S counter and excluding peers
void void
PropagateIntroSetTo(const Key_t& from, uint64_t txid, PropagateIntroSetTo(
const Key_t& from,
uint64_t txid,
const service::EncryptedIntroSet& introset, const service::EncryptedIntroSet& introset,
const Key_t& tellpeer, uint64_t relayOrder); const Key_t& tellpeer,
uint64_t relayOrder);
/// initialize dht context and explore every exploreInterval milliseconds /// initialize dht context and explore every exploreInterval milliseconds
void void
@ -291,8 +313,7 @@ namespace llarp
ExploreNetworkVia(peer); ExploreNetworkVia(peer);
} }
else else
llarp::LogError("failed to select ", N, llarp::LogError("failed to select ", N, " random nodes for exploration");
" random nodes for exploration");
} }
void void
@ -333,14 +354,16 @@ namespace llarp
void void
Context::LookupRouterRelayed( Context::LookupRouterRelayed(
const Key_t& requester, uint64_t txid, const Key_t& target, const Key_t& requester,
bool recursive, std::vector< std::unique_ptr< IMessage > >& replies) uint64_t txid,
const Key_t& target,
bool recursive,
std::vector<std::unique_ptr<IMessage>>& replies)
{ {
if (target == ourKey) if (target == ourKey)
{ {
// we are the target, give them our RC // we are the target, give them our RC
replies.emplace_back( replies.emplace_back(new GotRouterMessage(requester, txid, {router->rc()}, false));
new GotRouterMessage(requester, txid, {router->rc()}, false));
return; return;
} }
if (not GetRouter()->ConnectionToRouterAllowed(target.as_array())) if (not GetRouter()->ConnectionToRouterAllowed(target.as_array()))
@ -363,8 +386,7 @@ namespace llarp
else else
{ {
// send reply with rc we know of // send reply with rc we know of
replies.emplace_back( replies.emplace_back(new GotRouterMessage(requester, txid, {rc}, false));
new GotRouterMessage(requester, txid, {rc}, false));
} }
} }
else if (recursive) // are we doing a recursive lookup? else if (recursive) // are we doing a recursive lookup?
@ -379,15 +401,13 @@ namespace llarp
{ {
// no we are closer to the target so tell requester it's not there // no we are closer to the target so tell requester it's not there
// so they switch to iterative lookup // so they switch to iterative lookup
replies.emplace_back( replies.emplace_back(new GotRouterMessage(requester, txid, {}, false));
new GotRouterMessage(requester, txid, {}, false));
} }
} }
else else
{ {
// iterative lookup and we don't have it tell them who is closer // iterative lookup and we don't have it tell them who is closer
replies.emplace_back( replies.emplace_back(new GotRouterMessage(requester, next, txid, false));
new GotRouterMessage(requester, next, txid, false));
} }
} }
} }
@ -415,8 +435,7 @@ namespace llarp
util::StatusObject util::StatusObject
Context::ExtractStatus() const Context::ExtractStatus() const
{ {
util::StatusObject obj{ util::StatusObject obj{{"pendingRouterLookups", pendingRouterLookups().ExtractStatus()},
{"pendingRouterLookups", pendingRouterLookups().ExtractStatus()},
{"pendingIntrosetLookups", _pendingIntrosetLookups.ExtractStatus()}, {"pendingIntrosetLookups", _pendingIntrosetLookups.ExtractStatus()},
{"pendingExploreLookups", pendingExploreLookups().ExtractStatus()}, {"pendingExploreLookups", pendingExploreLookups().ExtractStatus()},
{"nodes", _nodes->ExtractStatus()}, {"nodes", _nodes->ExtractStatus()},
@ -441,8 +460,7 @@ namespace llarp
Context::ScheduleCleanupTimer() Context::ScheduleCleanupTimer()
{ {
router->logic()->call_later( router->logic()->call_later(
1s, 1s, std::bind(&llarp::dht::Context::handle_cleaner_timer, this, 1000));
std::bind(&llarp::dht::Context::handle_cleaner_timer, this, 1000));
} }
void void
@ -477,71 +495,87 @@ namespace llarp
} }
void void
Context::LookupIntroSetForPath(const Key_t& addr, uint64_t txid, Context::LookupIntroSetForPath(
const Key_t& addr,
uint64_t txid,
const llarp::PathID_t& path, const llarp::PathID_t& path,
const Key_t& askpeer, uint64_t relayOrder) const Key_t& askpeer,
uint64_t relayOrder)
{ {
const TXOwner asker(OurKey(), txid); const TXOwner asker(OurKey(), txid);
const TXOwner peer(askpeer, ++ids); const TXOwner peer(askpeer, ++ids);
_pendingIntrosetLookups.NewTX( _pendingIntrosetLookups.NewTX(
peer, asker, asker, peer,
new LocalServiceAddressLookup(path, txid, relayOrder, addr, this, asker,
askpeer)); asker,
new LocalServiceAddressLookup(path, txid, relayOrder, addr, this, askpeer));
} }
void void
Context::PropagateIntroSetTo(const Key_t& from, uint64_t txid, Context::PropagateIntroSetTo(
const Key_t& from,
uint64_t txid,
const service::EncryptedIntroSet& introset, const service::EncryptedIntroSet& introset,
const Key_t& tellpeer, uint64_t relayOrder) const Key_t& tellpeer,
uint64_t relayOrder)
{ {
const TXOwner asker(from, txid); const TXOwner asker(from, txid);
const TXOwner peer(tellpeer, ++ids); const TXOwner peer(tellpeer, ++ids);
_pendingIntrosetLookups.NewTX( _pendingIntrosetLookups.NewTX(
peer, asker, asker, peer, asker, asker, new PublishServiceJob(asker, introset, this, relayOrder));
new PublishServiceJob(asker, introset, this, relayOrder));
} }
void void
Context::PropagateLocalIntroSet(const PathID_t& from, uint64_t txid, Context::PropagateLocalIntroSet(
const PathID_t& from,
uint64_t txid,
const service::EncryptedIntroSet& introset, const service::EncryptedIntroSet& introset,
const Key_t& tellpeer, uint64_t relayOrder) const Key_t& tellpeer,
uint64_t relayOrder)
{ {
const TXOwner asker(OurKey(), txid); const TXOwner asker(OurKey(), txid);
const TXOwner peer(tellpeer, ++ids); const TXOwner peer(tellpeer, ++ids);
_pendingIntrosetLookups.NewTX( _pendingIntrosetLookups.NewTX(
peer, asker, peer, peer,
new LocalPublishServiceJob(peer, from, txid, introset, this, asker,
relayOrder)); peer,
new LocalPublishServiceJob(peer, from, txid, introset, this, relayOrder));
} }
void void
Context::LookupIntroSetRelayed( Context::LookupIntroSetRelayed(
const Key_t& addr, const Key_t& whoasked, uint64_t txid, const Key_t& addr,
const Key_t& askpeer, uint64_t relayOrder, const Key_t& whoasked,
uint64_t txid,
const Key_t& askpeer,
uint64_t relayOrder,
service::EncryptedIntroSetLookupHandler handler) service::EncryptedIntroSetLookupHandler handler)
{ {
const TXOwner asker(whoasked, txid); const TXOwner asker(whoasked, txid);
const TXOwner peer(askpeer, ++ids); const TXOwner peer(askpeer, ++ids);
_pendingIntrosetLookups.NewTX( _pendingIntrosetLookups.NewTX(
peer, asker, asker, peer, asker, asker, new ServiceAddressLookup(asker, addr, this, relayOrder, handler));
new ServiceAddressLookup(asker, addr, this, relayOrder, handler));
} }
void void
Context::LookupIntroSetDirect( Context::LookupIntroSetDirect(
const Key_t& addr, const Key_t& whoasked, uint64_t txid, const Key_t& addr,
const Key_t& askpeer, service::EncryptedIntroSetLookupHandler handler) const Key_t& whoasked,
uint64_t txid,
const Key_t& askpeer,
service::EncryptedIntroSetLookupHandler handler)
{ {
const TXOwner asker(whoasked, txid); const TXOwner asker(whoasked, txid);
const TXOwner peer(askpeer, ++ids); const TXOwner peer(askpeer, ++ids);
_pendingIntrosetLookups.NewTX( _pendingIntrosetLookups.NewTX(
peer, asker, asker, peer, asker, asker, new ServiceAddressLookup(asker, addr, this, 0, handler), 1s);
new ServiceAddressLookup(asker, addr, this, 0, handler), 1s);
} }
bool bool
Context::HandleExploritoryRouterLookup( Context::HandleExploritoryRouterLookup(
const Key_t& requester, uint64_t txid, const RouterID& target, const Key_t& requester,
uint64_t txid,
const RouterID& target,
std::vector<std::unique_ptr<IMessage>>& reply) std::vector<std::unique_ptr<IMessage>>& reply)
{ {
std::vector<RouterID> closer; std::vector<RouterID> closer;
@ -553,23 +587,21 @@ namespace llarp
const size_t nodeCount = _nodes->size(); const size_t nodeCount = _nodes->size();
if (nodeCount == 0) if (nodeCount == 0)
{ {
llarp::LogError( llarp::LogError("cannot handle exploritory router lookup, no dht peers");
"cannot handle exploritory router lookup, no dht peers");
return false; return false;
} }
llarp::LogDebug("We have ", _nodes->size(), llarp::LogDebug("We have ", _nodes->size(), " connected nodes into the DHT");
" connected nodes into the DHT");
// ourKey should never be in the connected list // ourKey should never be in the connected list
// requester is likely in the connected list // requester is likely in the connected list
// 4 or connection nodes (minus a potential requestor), whatever is less // 4 or connection nodes (minus a potential requestor), whatever is less
if(!_nodes->GetManyNearExcluding(t, foundRouters, if (!_nodes->GetManyNearExcluding(
std::min(nodeCount, size_t{4}), t, foundRouters, std::min(nodeCount, size_t{4}), std::set<Key_t>{ourKey, requester}))
std::set< Key_t >{ourKey, requester}))
{ {
llarp::LogError( llarp::LogError(
"not enough dht nodes to handle exploritory router lookup, " "not enough dht nodes to handle exploritory router lookup, "
"have ", "have ",
nodeCount, " dht peers"); nodeCount,
" dht peers");
return false; return false;
} }
for (const auto& f : foundRouters) for (const auto& f : foundRouters)
@ -586,29 +618,28 @@ namespace llarp
} }
void void
Context::LookupRouterForPath(const RouterID& target, uint64_t txid, Context::LookupRouterForPath(
const llarp::PathID_t& path, const RouterID& target, uint64_t txid, const llarp::PathID_t& path, const Key_t& askpeer)
const Key_t& askpeer)
{ {
const TXOwner peer(askpeer, ++ids); const TXOwner peer(askpeer, ++ids);
const TXOwner whoasked(OurKey(), txid); const TXOwner whoasked(OurKey(), txid);
_pendingRouterLookups.NewTX( _pendingRouterLookups.NewTX(
peer, whoasked, target, peer, whoasked, target, new LocalRouterLookup(path, txid, target, this));
new LocalRouterLookup(path, txid, target, this));
} }
void void
Context::LookupRouterRecursive(const RouterID& target, Context::LookupRouterRecursive(
const Key_t& whoasked, uint64_t txid, const RouterID& target,
const Key_t& whoasked,
uint64_t txid,
const Key_t& askpeer, const Key_t& askpeer,
RouterLookupHandler handler) RouterLookupHandler handler)
{ {
const TXOwner asker(whoasked, txid); const TXOwner asker(whoasked, txid);
const TXOwner peer(askpeer, ++ids); const TXOwner peer(askpeer, ++ids);
_pendingRouterLookups.NewTX( _pendingRouterLookups.NewTX(
peer, asker, target, peer, asker, target, new RecursiveRouterLookup(asker, target, this, handler));
new RecursiveRouterLookup(asker, target, this, handler));
} }
llarp_time_t llarp_time_t

@ -34,12 +34,9 @@ namespace llarp
struct AbstractContext struct AbstractContext
{ {
using PendingIntrosetLookups = using PendingIntrosetLookups = TXHolder<TXOwner, service::EncryptedIntroSet, TXOwner::Hash>;
TXHolder< TXOwner, service::EncryptedIntroSet, TXOwner::Hash >; using PendingRouterLookups = TXHolder<RouterID, RouterContact, RouterID::Hash>;
using PendingRouterLookups = using PendingExploreLookups = TXHolder<RouterID, RouterID, RouterID::Hash>;
TXHolder< RouterID, RouterContact, RouterID::Hash >;
using PendingExploreLookups =
TXHolder< RouterID, RouterID, RouterID::Hash >;
virtual ~AbstractContext() = 0; virtual ~AbstractContext() = 0;
@ -47,22 +44,31 @@ namespace llarp
LookupRouter(const RouterID& target, RouterLookupHandler result) = 0; LookupRouter(const RouterID& target, RouterLookupHandler result) = 0;
virtual void virtual void
LookupRouterRecursive(const RouterID& target, const Key_t& whoasked, LookupRouterRecursive(
uint64_t whoaskedTX, const Key_t& askpeer, const RouterID& target,
const Key_t& whoasked,
uint64_t whoaskedTX,
const Key_t& askpeer,
RouterLookupHandler result = nullptr) = 0; RouterLookupHandler result = nullptr) = 0;
/// Ask a Service Node to perform an Introset lookup for us /// Ask a Service Node to perform an Introset lookup for us
virtual void virtual void
LookupIntroSetRelayed(const Key_t& target, const Key_t& whoasked, LookupIntroSetRelayed(
uint64_t whoaskedTX, const Key_t& askpeer, const Key_t& target,
const Key_t& whoasked,
uint64_t whoaskedTX,
const Key_t& askpeer,
uint64_t relayOrder, uint64_t relayOrder,
service::EncryptedIntroSetLookupHandler result = service::EncryptedIntroSetLookupHandler result =
service::EncryptedIntroSetLookupHandler()) = 0; service::EncryptedIntroSetLookupHandler()) = 0;
/// Directly as a Service Node for an Introset /// Directly as a Service Node for an Introset
virtual void virtual void
LookupIntroSetDirect(const Key_t& target, const Key_t& whoasked, LookupIntroSetDirect(
uint64_t whoaskedTX, const Key_t& askpeer, const Key_t& target,
const Key_t& whoasked,
uint64_t whoaskedTX,
const Key_t& askpeer,
service::EncryptedIntroSetLookupHandler result = service::EncryptedIntroSetLookupHandler result =
service::EncryptedIntroSetLookupHandler()) = 0; service::EncryptedIntroSetLookupHandler()) = 0;
@ -71,12 +77,15 @@ namespace llarp
/// issue dht lookup for router via askpeer and send reply to local path /// issue dht lookup for router via askpeer and send reply to local path
virtual void virtual void
LookupRouterForPath(const RouterID& target, uint64_t txid, LookupRouterForPath(
const PathID_t& path, const Key_t& askpeer) = 0; const RouterID& target, uint64_t txid, const PathID_t& path, const Key_t& askpeer) = 0;
virtual void virtual void
LookupIntroSetForPath(const Key_t& addr, uint64_t txid, LookupIntroSetForPath(
const PathID_t& path, const Key_t& askpeer, const Key_t& addr,
uint64_t txid,
const PathID_t& path,
const Key_t& askpeer,
uint64_t relayOrder) = 0; uint64_t relayOrder) = 0;
virtual void virtual void
@ -85,13 +94,17 @@ namespace llarp
/// get routers closest to target excluding requester /// get routers closest to target excluding requester
virtual bool virtual bool
HandleExploritoryRouterLookup( HandleExploritoryRouterLookup(
const Key_t& requester, uint64_t txid, const RouterID& target, const Key_t& requester,
uint64_t txid,
const RouterID& target,
std::vector<std::unique_ptr<IMessage>>& reply) = 0; std::vector<std::unique_ptr<IMessage>>& reply) = 0;
/// handle rc lookup from requester for target /// handle rc lookup from requester for target
virtual void virtual void
LookupRouterRelayed( LookupRouterRelayed(
const Key_t& requester, uint64_t txid, const Key_t& target, const Key_t& requester,
uint64_t txid,
const Key_t& target,
bool recursive, bool recursive,
std::vector<std::unique_ptr<IMessage>>& replies) = 0; std::vector<std::unique_ptr<IMessage>>& replies) = 0;
@ -100,15 +113,21 @@ namespace llarp
/// send introset to peer from source with S counter and excluding peers /// send introset to peer from source with S counter and excluding peers
virtual void virtual void
PropagateLocalIntroSet(const PathID_t& path, uint64_t sourceTX, PropagateLocalIntroSet(
const PathID_t& path,
uint64_t sourceTX,
const service::EncryptedIntroSet& introset, const service::EncryptedIntroSet& introset,
const Key_t& peer, uint64_t relayOrder) = 0; const Key_t& peer,
uint64_t relayOrder) = 0;
/// send introset to peer from source with S counter and excluding peers /// send introset to peer from source with S counter and excluding peers
virtual void virtual void
PropagateIntroSetTo(const Key_t& source, uint64_t sourceTX, PropagateIntroSetTo(
const Key_t& source,
uint64_t sourceTX,
const service::EncryptedIntroSet& introset, const service::EncryptedIntroSet& introset,
const Key_t& peer, uint64_t relayOrder) = 0; const Key_t& peer,
uint64_t relayOrder) = 0;
virtual void virtual void
Init(const Key_t& us, AbstractRouter* router) = 0; Init(const Key_t& us, AbstractRouter* router) = 0;

@ -39,8 +39,7 @@ llarp_dht_context_start(struct llarp_dht_context *ctx, const byte_t *key)
} }
void void
llarp_dht_lookup_router(struct llarp_dht_context *ctx, llarp_dht_lookup_router(struct llarp_dht_context* ctx, struct llarp_router_lookup_job* job)
struct llarp_router_lookup_job *job)
{ {
job->dht = ctx; job->dht = ctx;
job->found = false; job->found = false;

@ -59,7 +59,6 @@ void
__llarp_dht_remove_peer(struct llarp_dht_context* ctx, const byte_t* id); __llarp_dht_remove_peer(struct llarp_dht_context* ctx, const byte_t* id);
void void
llarp_dht_lookup_router(struct llarp_dht_context* ctx, llarp_dht_lookup_router(struct llarp_dht_context* ctx, struct llarp_router_lookup_job* job);
struct llarp_router_lookup_job* job);
#endif #endif

@ -15,12 +15,9 @@ namespace llarp
void void
ExploreNetworkJob::Start(const TXOwner& peer) ExploreNetworkJob::Start(const TXOwner& peer)
{ {
auto msg = new FindRouterMessage(peer.txid); auto msg = new FindRouterMessage(peer.txid);
auto router = parent->GetRouter(); auto router = parent->GetRouter();
router->NotifyRouterEvent< tooling::FindRouterSentEvent >( router->NotifyRouterEvent<tooling::FindRouterSentEvent>(router->pubkey(), msg);
router->pubkey(),
msg);
parent->DHTSendTo(peer.node.as_array(), msg); parent->DHTSendTo(peer.node.as_array(), msg);
} }
@ -38,9 +35,7 @@ namespace llarp
if (router and router->nodedb()->Has(pk)) if (router and router->nodedb()->Has(pk))
continue; continue;
parent->LookupRouter( parent->LookupRouter(
pk, pk, std::bind(&AbstractRouter::HandleDHTLookupForExplore, router, pk, _1));
std::bind(&AbstractRouter::HandleDHTLookupForExplore, router, pk,
_1));
} }
} }
} // namespace dht } // namespace dht

@ -20,8 +20,7 @@ namespace llarp
{ {
} }
explicit Key_t(const AlignedBuffer< SIZE >& data) explicit Key_t(const AlignedBuffer<SIZE>& data) : AlignedBuffer<SIZE>(data)
: AlignedBuffer< SIZE >(data)
{ {
} }
@ -50,8 +49,7 @@ namespace llarp
operator^(const Key_t& other) const operator^(const Key_t& other) const
{ {
Key_t dist; Key_t dist;
std::transform(begin(), end(), other.begin(), dist.begin(), std::transform(begin(), end(), other.begin(), dist.begin(), std::bit_xor<byte_t>());
std::bit_xor< byte_t >());
return dist; return dist;
} }

@ -12,11 +12,9 @@ namespace llarp
{ {
namespace dht namespace dht
{ {
LocalRouterLookup::LocalRouterLookup(const PathID_t &path, uint64_t txid, LocalRouterLookup::LocalRouterLookup(
const RouterID &_target, const PathID_t& path, uint64_t txid, const RouterID& _target, AbstractContext* ctx)
AbstractContext *ctx) : RecursiveRouterLookup(TXOwner{ctx->OurKey(), txid}, _target, ctx, nullptr)
: RecursiveRouterLookup(TXOwner{ctx->OurKey(), txid}, _target, ctx,
nullptr)
, localPath(path) , localPath(path)
{ {
} }
@ -24,8 +22,8 @@ namespace llarp
void void
LocalRouterLookup::SendReply() LocalRouterLookup::SendReply()
{ {
auto path = parent->GetRouter()->pathContext().GetByUpstream( auto path =
parent->OurKey().as_array(), localPath); parent->GetRouter()->pathContext().GetByUpstream(parent->OurKey().as_array(), localPath);
if (!path) if (!path)
{ {
llarp::LogWarn( llarp::LogWarn(
@ -54,8 +52,7 @@ namespace llarp
} }
} }
routing::DHTMessage msg; routing::DHTMessage msg;
msg.M.emplace_back(new GotRouterMessage(parent->OurKey(), whoasked.txid, msg.M.emplace_back(new GotRouterMessage(parent->OurKey(), whoasked.txid, valuesFound, true));
valuesFound, true));
if (!path->SendRoutingMessage(msg, parent->GetRouter())) if (!path->SendRoutingMessage(msg, parent->GetRouter()))
{ {
llarp::LogWarn( llarp::LogWarn(

@ -15,8 +15,8 @@ namespace llarp
{ {
PathID_t localPath; PathID_t localPath;
LocalRouterLookup(const PathID_t &path, uint64_t txid, LocalRouterLookup(
const RouterID &target, AbstractContext *ctx); const PathID_t& path, uint64_t txid, const RouterID& target, AbstractContext* ctx);
void void
SendReply() override; SendReply() override;

@ -12,11 +12,13 @@ namespace llarp
namespace dht namespace dht
{ {
LocalServiceAddressLookup::LocalServiceAddressLookup( LocalServiceAddressLookup::LocalServiceAddressLookup(
const PathID_t &pathid, uint64_t txid, uint64_t relayOrder, const PathID_t& pathid,
const Key_t &addr, AbstractContext *ctx, uint64_t txid,
uint64_t relayOrder,
const Key_t& addr,
AbstractContext* ctx,
__attribute__((unused)) const Key_t& askpeer) __attribute__((unused)) const Key_t& askpeer)
: ServiceAddressLookup(TXOwner{ctx->OurKey(), txid}, addr, ctx, : ServiceAddressLookup(TXOwner{ctx->OurKey(), txid}, addr, ctx, relayOrder, nullptr)
relayOrder, nullptr)
, localPath(pathid) , localPath(pathid)
{ {
} }
@ -24,8 +26,8 @@ namespace llarp
void void
LocalServiceAddressLookup::SendReply() LocalServiceAddressLookup::SendReply()
{ {
auto path = parent->GetRouter()->pathContext().GetByUpstream( auto path =
parent->OurKey().as_array(), localPath); parent->GetRouter()->pathContext().GetByUpstream(parent->OurKey().as_array(), localPath);
if (!path) if (!path)
{ {
llarp::LogWarn( llarp::LogWarn(

@ -13,8 +13,11 @@ namespace llarp
{ {
PathID_t localPath; PathID_t localPath;
LocalServiceAddressLookup(const PathID_t &pathid, uint64_t txid, LocalServiceAddressLookup(
uint64_t relayOrder, const Key_t &addr, const PathID_t& pathid,
uint64_t txid,
uint64_t relayOrder,
const Key_t& addr,
AbstractContext* ctx, AbstractContext* ctx,
__attribute__((unused)) const Key_t& askpeer); __attribute__((unused)) const Key_t& askpeer);

@ -10,19 +10,17 @@ namespace llarp
{ {
namespace dht namespace dht
{ {
LocalTagLookup::LocalTagLookup(const PathID_t &path, uint64_t txid, LocalTagLookup::LocalTagLookup(
const service::Tag &_target, const PathID_t& path, uint64_t txid, const service::Tag& _target, AbstractContext* ctx)
AbstractContext *ctx) : TagLookup(TXOwner{ctx->OurKey(), txid}, _target, ctx, 0), localPath(path)
: TagLookup(TXOwner{ctx->OurKey(), txid}, _target, ctx, 0)
, localPath(path)
{ {
} }
void void
LocalTagLookup::SendReply() LocalTagLookup::SendReply()
{ {
auto path = parent->GetRouter()->pathContext().GetByUpstream( auto path =
parent->OurKey().as_array(), localPath); parent->GetRouter()->pathContext().GetByUpstream(parent->OurKey().as_array(), localPath);
if (!path) if (!path)
{ {
llarp::LogWarn( llarp::LogWarn(

@ -11,8 +11,8 @@ namespace llarp
{ {
PathID_t localPath; PathID_t localPath;
LocalTagLookup(const PathID_t &path, uint64_t txid, LocalTagLookup(
const service::Tag &target, AbstractContext *ctx); const PathID_t& path, uint64_t txid, const service::Tag& target, AbstractContext* ctx);
void void
SendReply() override; SendReply() override;

@ -19,8 +19,7 @@ namespace llarp
bool firstKey = true; bool firstKey = true;
bool relayed = false; bool relayed = false;
MessageDecoder(const Key_t &from, bool wasRelayed) MessageDecoder(const Key_t& from, bool wasRelayed) : From(from), relayed(wasRelayed)
: From(from), relayed(wasRelayed)
{ {
} }
@ -42,8 +41,7 @@ namespace llarp
// bad msg size? // bad msg size?
if (strbuf.sz != 1) if (strbuf.sz != 1)
return false; return false;
llarp::LogDebug("Handle DHT message ", *strbuf.base, llarp::LogDebug("Handle DHT message ", *strbuf.base, " relayed=", relayed);
" relayed=", relayed);
switch (*strbuf.base) switch (*strbuf.base)
{ {
case 'F': case 'F':
@ -97,8 +95,7 @@ namespace llarp
struct ListDecoder struct ListDecoder
{ {
ListDecoder(bool hasRelayed, const Key_t &from, ListDecoder(bool hasRelayed, const Key_t& from, std::vector<IMessage::Ptr_t>& list)
std::vector< IMessage::Ptr_t > &list)
: relayed(hasRelayed), From(from), l(list) : relayed(hasRelayed), From(from), l(list)
{ {
} }
@ -124,8 +121,8 @@ namespace llarp
}; };
bool bool
DecodeMesssageList(Key_t from, llarp_buffer_t *buf, DecodeMesssageList(
std::vector< IMessage::Ptr_t > &list, bool relayed) Key_t from, llarp_buffer_t* buf, std::vector<IMessage::Ptr_t>& list, bool relayed)
{ {
ListDecoder dec(relayed, from, list); ListDecoder dec(relayed, from, list);
return bencode_read_list(dec, buf); return bencode_read_list(dec, buf);

@ -26,8 +26,7 @@ namespace llarp
using Ptr_t = std::unique_ptr<IMessage>; using Ptr_t = std::unique_ptr<IMessage>;
virtual bool virtual bool
HandleMessage(struct llarp_dht_context* dht, HandleMessage(struct llarp_dht_context* dht, std::vector<Ptr_t>& replies) const = 0;
std::vector< Ptr_t >& replies) const = 0;
virtual bool virtual bool
BEncode(llarp_buffer_t* buf) const = 0; BEncode(llarp_buffer_t* buf) const = 0;
@ -44,9 +43,8 @@ namespace llarp
DecodeMessage(const Key_t& from, llarp_buffer_t* buf, bool relayed = false); DecodeMessage(const Key_t& from, llarp_buffer_t* buf, bool relayed = false);
bool bool
DecodeMesssageList(Key_t from, llarp_buffer_t* buf, DecodeMesssageList(
std::vector< IMessage::Ptr_t >& dst, Key_t from, llarp_buffer_t* buf, std::vector<IMessage::Ptr_t>& dst, bool relayed = false);
bool relayed = false);
} // namespace dht } // namespace dht
} // namespace llarp } // namespace llarp

@ -28,8 +28,7 @@ namespace llarp
if (!BEncodeMaybeReadDictInt("T", txID, read, k, val)) if (!BEncodeMaybeReadDictInt("T", txID, read, k, val))
return false; return false;
if(!BEncodeMaybeVerifyVersion("V", version, LLARP_PROTO_VERSION, read, k, if (!BEncodeMaybeVerifyVersion("V", version, LLARP_PROTO_VERSION, read, k, val))
val))
return false; return false;
return read; return read;
@ -105,13 +104,12 @@ namespace llarp
return true; return true;
} }
auto closestRCs = dht.GetRouter()->nodedb()->FindClosestTo( auto closestRCs =
location, IntroSetStorageRedundancy); dht.GetRouter()->nodedb()->FindClosestTo(location, IntroSetStorageRedundancy);
if (closestRCs.size() <= relayOrder) if (closestRCs.size() <= relayOrder)
{ {
llarp::LogWarn("Can't fulfill FindIntro for relayOrder: ", llarp::LogWarn("Can't fulfill FindIntro for relayOrder: ", relayOrder);
relayOrder);
replies.emplace_back(new GotIntroMessage({}, txID)); replies.emplace_back(new GotIntroMessage({}, txID));
return true; return true;
} }

@ -18,8 +18,7 @@ namespace llarp
bool relayed = false; bool relayed = false;
uint64_t relayOrder = 0; uint64_t relayOrder = 0;
FindIntroMessage(const Key_t& from, bool relay, uint64_t order) FindIntroMessage(const Key_t& from, bool relay, uint64_t order) : IMessage(from)
: IMessage(from)
{ {
relayed = relay; relayed = relay;
relayOrder = order; relayOrder = order;
@ -30,8 +29,7 @@ namespace llarp
{ {
} }
explicit FindIntroMessage(uint64_t txid, const Key_t& addr, explicit FindIntroMessage(uint64_t txid, const Key_t& addr, uint64_t order)
uint64_t order)
: IMessage({}), location(addr), txID(txid), relayOrder(order) : IMessage({}), location(addr), txID(txid), relayOrder(order)
{ {
tagName.Zero(); tagName.Zero();
@ -46,8 +44,7 @@ namespace llarp
DecodeKey(const llarp_buffer_t& key, llarp_buffer_t* val) override; DecodeKey(const llarp_buffer_t& key, llarp_buffer_t* val) override;
bool bool
HandleMessage(llarp_dht_context* ctx, HandleMessage(llarp_dht_context* ctx, std::vector<IMessage::Ptr_t>& replies) const override;
std::vector< IMessage::Ptr_t >& replies) const override;
}; };
} // namespace dht } // namespace dht
} // namespace llarp } // namespace llarp

@ -15,8 +15,7 @@ namespace llarp
{ {
bool bool
RelayedFindRouterMessage::HandleMessage( RelayedFindRouterMessage::HandleMessage(
llarp_dht_context *ctx, llarp_dht_context* ctx, std::vector<std::unique_ptr<IMessage>>& replies) const
std::vector< std::unique_ptr< IMessage > > &replies) const
{ {
auto& dht = *ctx->impl; auto& dht = *ctx->impl;
/// lookup for us, send an immeidate reply /// lookup for us, send an immeidate reply
@ -24,12 +23,10 @@ namespace llarp
const Key_t k{targetKey}; const Key_t k{targetKey};
if (k == us) if (k == us)
{ {
auto path = auto path = dht.GetRouter()->pathContext().GetByUpstream(targetKey, pathID);
dht.GetRouter()->pathContext().GetByUpstream(targetKey, pathID);
if (path) if (path)
{ {
replies.emplace_back( replies.emplace_back(new GotRouterMessage(k, txid, {dht.GetRouter()->rc()}, false));
new GotRouterMessage(k, txid, {dht.GetRouter()->rc()}, false));
return true; return true;
} }
return false; return false;
@ -150,20 +147,16 @@ namespace llarp
bool bool
FindRouterMessage::HandleMessage( FindRouterMessage::HandleMessage(
llarp_dht_context *ctx, llarp_dht_context* ctx, std::vector<std::unique_ptr<IMessage>>& replies) const
std::vector< std::unique_ptr< IMessage > > &replies) const
{ {
auto& dht = *ctx->impl; auto& dht = *ctx->impl;
auto router = dht.GetRouter(); auto router = dht.GetRouter();
router->NotifyRouterEvent< tooling::FindRouterReceivedEvent >( router->NotifyRouterEvent<tooling::FindRouterReceivedEvent>(router->pubkey(), this);
router->pubkey(),
this);
if (!dht.AllowTransit()) if (!dht.AllowTransit())
{ {
llarp::LogWarn("Got DHT lookup from ", From, llarp::LogWarn("Got DHT lookup from ", From, " when we are not allowing dht transit");
" when we are not allowing dht transit");
return false; return false;
} }
if (dht.pendingRouterLookups().HasPendingLookupFrom({From, txid})) if (dht.pendingRouterLookups().HasPendingLookupFrom({From, txid}))
@ -179,8 +172,7 @@ namespace llarp
} }
const Key_t k(targetKey); const Key_t k(targetKey);
if (exploritory) if (exploritory)
return dht.HandleExploritoryRouterLookup(From, txid, targetKey, return dht.HandleExploritoryRouterLookup(From, txid, targetKey, replies);
replies);
dht.LookupRouterRelayed(From, txid, k, !iterative, replies); dht.LookupRouterRelayed(From, txid, k, !iterative, replies);
return true; return true;
} }

@ -35,8 +35,7 @@ namespace llarp
bool bool
HandleMessage( HandleMessage(
llarp_dht_context* ctx, llarp_dht_context* ctx, std::vector<std::unique_ptr<IMessage>>& replies) const override;
std::vector< std::unique_ptr< IMessage > >& replies) const override;
RouterID targetKey; RouterID targetKey;
bool iterative = false; bool iterative = false;
@ -56,8 +55,7 @@ namespace llarp
/// the path of the result /// the path of the result
/// TODO: smart path expiration logic needs to be implemented /// TODO: smart path expiration logic needs to be implemented
bool bool
HandleMessage(llarp_dht_context* ctx, HandleMessage(llarp_dht_context* ctx, std::vector<IMessage::Ptr_t>& replies) const override;
std::vector< IMessage::Ptr_t >& replies) const override;
}; };
} // namespace dht } // namespace dht
} // namespace llarp } // namespace llarp

@ -13,22 +13,21 @@ namespace llarp
{ {
namespace dht namespace dht
{ {
GotIntroMessage::GotIntroMessage( GotIntroMessage::GotIntroMessage(std::vector<service::EncryptedIntroSet> results, uint64_t tx)
std::vector< service::EncryptedIntroSet > results, uint64_t tx)
: IMessage({}), found(std::move(results)), txid(tx) : IMessage({}), found(std::move(results)), txid(tx)
{ {
} }
bool bool
GotIntroMessage::HandleMessage( GotIntroMessage::HandleMessage(
llarp_dht_context *ctx, llarp_dht_context* ctx, std::vector<std::unique_ptr<IMessage>>& /*replies*/) const
std::vector< std::unique_ptr< IMessage > > & /*replies*/) const
{ {
auto& dht = *ctx->impl; auto& dht = *ctx->impl;
auto* router = dht.GetRouter(); auto* router = dht.GetRouter();
router->NotifyRouterEvent<tooling::GotIntroReceivedEvent>( router->NotifyRouterEvent<tooling::GotIntroReceivedEvent>(
router->pubkey(), Key_t(From.data()), router->pubkey(),
Key_t(From.data()),
(found.size() > 0 ? found[0] : llarp::service::EncryptedIntroSet{}), (found.size() > 0 ? found[0] : llarp::service::EncryptedIntroSet{}),
txid); txid);
@ -45,14 +44,12 @@ namespace llarp
} }
TXOwner owner(From, txid); TXOwner owner(From, txid);
auto serviceLookup = auto serviceLookup = dht.pendingIntrosetLookups().GetPendingLookupFrom(owner);
dht.pendingIntrosetLookups().GetPendingLookupFrom(owner);
if (serviceLookup) if (serviceLookup)
{ {
if (not found.empty()) if (not found.empty())
{ {
dht.pendingIntrosetLookups().Found(owner, serviceLookup->target, dht.pendingIntrosetLookups().Found(owner, serviceLookup->target, found);
found);
} }
else else
{ {
@ -67,12 +64,10 @@ namespace llarp
bool bool
RelayedGotIntroMessage::HandleMessage( RelayedGotIntroMessage::HandleMessage(
llarp_dht_context* ctx, llarp_dht_context* ctx,
__attribute__((unused)) __attribute__((unused)) std::vector<std::unique_ptr<IMessage>>& replies) const
std::vector< std::unique_ptr< IMessage > > &replies) const
{ {
// TODO: implement me better? // TODO: implement me better?
auto pathset = auto pathset = ctx->impl->GetRouter()->pathContext().GetLocalPathSet(pathID);
ctx->impl->GetRouter()->pathContext().GetLocalPathSet(pathID);
if (pathset) if (pathset)
{ {
auto copy = std::make_shared<const RelayedGotIntroMessage>(*this); auto copy = std::make_shared<const RelayedGotIntroMessage>(*this);

@ -27,10 +27,7 @@ namespace llarp
} }
GotIntroMessage(const GotIntroMessage& other) GotIntroMessage(const GotIntroMessage& other)
: IMessage(other.From) : IMessage(other.From), found(other.found), txid(other.txid), closer(other.closer)
, found(other.found)
, txid(other.txid)
, closer(other.closer)
{ {
version = other.version; version = other.version;
} }
@ -42,8 +39,7 @@ namespace llarp
} }
/// for recursive reply /// for recursive reply
GotIntroMessage(std::vector< service::EncryptedIntroSet > results, GotIntroMessage(std::vector<service::EncryptedIntroSet> results, uint64_t txid);
uint64_t txid);
~GotIntroMessage() override = default; ~GotIntroMessage() override = default;
@ -54,8 +50,7 @@ namespace llarp
DecodeKey(const llarp_buffer_t& key, llarp_buffer_t* val) override; DecodeKey(const llarp_buffer_t& key, llarp_buffer_t* val) override;
bool bool
HandleMessage(llarp_dht_context* ctx, HandleMessage(llarp_dht_context* ctx, std::vector<IMessage::Ptr_t>& replies) const override;
std::vector< IMessage::Ptr_t >& replies) const override;
}; };
struct RelayedGotIntroMessage final : public GotIntroMessage struct RelayedGotIntroMessage final : public GotIntroMessage
@ -65,8 +60,7 @@ namespace llarp
} }
bool bool
HandleMessage(llarp_dht_context* ctx, HandleMessage(llarp_dht_context* ctx, std::vector<IMessage::Ptr_t>& replies) const override;
std::vector< IMessage::Ptr_t >& replies) const override;
}; };
using GotIntroMessage_constptr = std::shared_ptr<const GotIntroMessage>; using GotIntroMessage_constptr = std::shared_ptr<const GotIntroMessage>;

@ -73,8 +73,7 @@ namespace llarp
return bencode_read_integer(val, &txid); return bencode_read_integer(val, &txid);
} }
bool read = false; bool read = false;
if(!BEncodeMaybeVerifyVersion("V", version, LLARP_PROTO_VERSION, read, if (!BEncodeMaybeVerifyVersion("V", version, LLARP_PROTO_VERSION, read, key, val))
key, val))
return false; return false;
return read; return read;
@ -83,14 +82,12 @@ namespace llarp
bool bool
GotRouterMessage::HandleMessage( GotRouterMessage::HandleMessage(
llarp_dht_context* ctx, llarp_dht_context* ctx,
__attribute__((unused)) __attribute__((unused)) std::vector<std::unique_ptr<IMessage>>& replies) const
std::vector< std::unique_ptr< IMessage > > &replies) const
{ {
auto& dht = *ctx->impl; auto& dht = *ctx->impl;
if (relayed) if (relayed)
{ {
auto pathset = auto pathset = ctx->impl->GetRouter()->pathContext().GetLocalPathSet(pathID);
ctx->impl->GetRouter()->pathContext().GetLocalPathSet(pathID);
auto copy = std::make_shared<const GotRouterMessage>(*this); auto copy = std::make_shared<const GotRouterMessage>(*this);
return pathset && pathset->HandleGotRouterMessage(copy); return pathset && pathset->HandleGotRouterMessage(copy);
} }
@ -129,8 +126,7 @@ namespace llarp
{ {
LogWarn("Received Gossiped RC, generating RCGossipReceivedEvent"); LogWarn("Received Gossiped RC, generating RCGossipReceivedEvent");
auto* router = dht.GetRouter(); auto* router = dht.GetRouter();
router->NotifyRouterEvent< tooling::RCGossipReceivedEvent >( router->NotifyRouterEvent<tooling::RCGossipReceivedEvent>(router->pubkey(), rc);
router->pubkey(), rc);
router->GossipRCIfNeeded(rc); router->GossipRCIfNeeded(rc);
} }
} }

@ -13,38 +13,27 @@ namespace llarp
{ {
struct GotRouterMessage final : public IMessage struct GotRouterMessage final : public IMessage
{ {
GotRouterMessage(const Key_t& from, bool tunneled) GotRouterMessage(const Key_t& from, bool tunneled) : IMessage(from), relayed(tunneled)
: IMessage(from), relayed(tunneled)
{ {
} }
GotRouterMessage(const Key_t& from, uint64_t id, GotRouterMessage(
const std::vector< RouterContact >& results, const Key_t& from, uint64_t id, const std::vector<RouterContact>& results, bool tunneled)
bool tunneled)
: IMessage(from), foundRCs(results), txid(id), relayed(tunneled) : IMessage(from), foundRCs(results), txid(id), relayed(tunneled)
{ {
} }
GotRouterMessage(const Key_t& from, const Key_t& closer, uint64_t id, GotRouterMessage(const Key_t& from, const Key_t& closer, uint64_t id, bool tunneled)
bool tunneled) : IMessage(from), closerTarget(new Key_t(closer)), txid(id), relayed(tunneled)
: IMessage(from)
, closerTarget(new Key_t(closer))
, txid(id)
, relayed(tunneled)
{ {
} }
GotRouterMessage(uint64_t id, std::vector< RouterID > _near, GotRouterMessage(uint64_t id, std::vector<RouterID> _near, bool tunneled)
bool tunneled) : IMessage({}), nearKeys(std::move(_near)), txid(id), relayed(tunneled)
: IMessage({})
, nearKeys(std::move(_near))
, txid(id)
, relayed(tunneled)
{ {
} }
/// gossip message /// gossip message
GotRouterMessage(const RouterContact rc) GotRouterMessage(const RouterContact rc) : IMessage({}), foundRCs({rc}), txid(0)
: IMessage({}), foundRCs({rc}), txid(0)
{ {
version = LLARP_PROTO_VERSION; version = LLARP_PROTO_VERSION;
} }
@ -70,8 +59,7 @@ namespace llarp
bool bool
HandleMessage( HandleMessage(
llarp_dht_context* ctx, llarp_dht_context* ctx, std::vector<std::unique_ptr<IMessage>>& replies) const override;
std::vector< std::unique_ptr< IMessage > >& replies) const override;
std::vector<RouterContact> foundRCs; std::vector<RouterContact> foundRCs;
std::vector<RouterID> nearKeys; std::vector<RouterID> nearKeys;

@ -17,8 +17,7 @@ namespace llarp
PublishIntroMessage::~PublishIntroMessage() = default; PublishIntroMessage::~PublishIntroMessage() = default;
bool bool
PublishIntroMessage::DecodeKey(const llarp_buffer_t &key, PublishIntroMessage::DecodeKey(const llarp_buffer_t& key, llarp_buffer_t* val)
llarp_buffer_t *val)
{ {
bool read = false; bool read = false;
if (!BEncodeMaybeReadDictEntry("I", introset, read, key, val)) if (!BEncodeMaybeReadDictEntry("I", introset, read, key, val))
@ -55,8 +54,7 @@ namespace llarp
bool bool
PublishIntroMessage::HandleMessage( PublishIntroMessage::HandleMessage(
llarp_dht_context *ctx, llarp_dht_context* ctx, std::vector<std::unique_ptr<IMessage>>& replies) const
std::vector< std::unique_ptr< IMessage > > &replies) const
{ {
const auto now = ctx->impl->Now(); const auto now = ctx->impl->Now();
const llarp::dht::Key_t addr(introset.derivedSigningKey); const llarp::dht::Key_t addr(introset.derivedSigningKey);
@ -64,14 +62,16 @@ namespace llarp
auto router = ctx->impl->GetRouter(); auto router = ctx->impl->GetRouter();
router->NotifyRouterEvent<tooling::PubIntroReceivedEvent>( router->NotifyRouterEvent<tooling::PubIntroReceivedEvent>(
router->pubkey(), Key_t(relayed ? router->pubkey() : From.data()), router->pubkey(),
addr, txID, relayOrder); Key_t(relayed ? router->pubkey() : From.data()),
addr,
txID,
relayOrder);
auto& dht = *ctx->impl; auto& dht = *ctx->impl;
if (!introset.Verify(now)) if (!introset.Verify(now))
{ {
llarp::LogWarn("Received PublishIntroMessage with invalid introset: ", llarp::LogWarn("Received PublishIntroMessage with invalid introset: ", introset);
introset);
// don't propogate or store // don't propogate or store
replies.emplace_back(new GotIntroMessage({}, txID)); replies.emplace_back(new GotIntroMessage({}, txID));
return true; return true;
@ -80,19 +80,16 @@ namespace llarp
if (introset.IsExpired(now + llarp::service::MAX_INTROSET_TIME_DELTA)) if (introset.IsExpired(now + llarp::service::MAX_INTROSET_TIME_DELTA))
{ {
// don't propogate or store // don't propogate or store
llarp::LogWarn("Received PublishIntroMessage with expired Introset: ", llarp::LogWarn("Received PublishIntroMessage with expired Introset: ", introset);
introset);
replies.emplace_back(new GotIntroMessage({}, txID)); replies.emplace_back(new GotIntroMessage({}, txID));
return true; return true;
} }
// identify closest 4 routers // identify closest 4 routers
auto closestRCs = dht.GetRouter()->nodedb()->FindClosestTo( auto closestRCs = dht.GetRouter()->nodedb()->FindClosestTo(addr, IntroSetStorageRedundancy);
addr, IntroSetStorageRedundancy);
if (closestRCs.size() != IntroSetStorageRedundancy) if (closestRCs.size() != IntroSetStorageRedundancy)
{ {
llarp::LogWarn("Received PublishIntroMessage but only know ", llarp::LogWarn("Received PublishIntroMessage but only know ", closestRCs.size(), " nodes");
closestRCs.size(), " nodes");
replies.emplace_back(new GotIntroMessage({}, txID)); replies.emplace_back(new GotIntroMessage({}, txID));
return true; return true;
} }
@ -108,8 +105,7 @@ namespace llarp
if (peer == us) if (peer == us)
{ {
llarp::LogInfo("we are peer ", index, llarp::LogInfo("we are peer ", index, " so storing instead of propagating");
" so storing instead of propagating");
dht.services()->PutNode(introset); dht.services()->PutNode(introset);
replies.emplace_back(new GotIntroMessage({introset}, txID)); replies.emplace_back(new GotIntroMessage({introset}, txID));
@ -132,15 +128,12 @@ namespace llarp
{ {
if (relayOrder >= IntroSetStorageRedundancy) if (relayOrder >= IntroSetStorageRedundancy)
{ {
llarp::LogWarn( llarp::LogWarn("Received PublishIntroMessage with invalid relayOrder: ", relayOrder);
"Received PublishIntroMessage with invalid relayOrder: ",
relayOrder);
replies.emplace_back(new GotIntroMessage({}, txID)); replies.emplace_back(new GotIntroMessage({}, txID));
return true; return true;
} }
llarp::LogInfo("Relaying PublishIntroMessage for ", keyStr, llarp::LogInfo("Relaying PublishIntroMessage for ", keyStr, ", txid=", txID);
", txid=", txID);
propagateIfNotUs(relayOrder); propagateIfNotUs(relayOrder);
} }
@ -160,8 +153,13 @@ namespace llarp
if (candidateNumber >= 0) if (candidateNumber >= 0)
{ {
LogInfo("Received PubIntro for ", keyStr, ", txid=", txID, LogInfo(
" and we are candidate ", candidateNumber); "Received PubIntro for ",
keyStr,
", txid=",
txID,
" and we are candidate ",
candidateNumber);
dht.services()->PutNode(introset); dht.services()->PutNode(introset);
replies.emplace_back(new GotIntroMessage({introset}, txID)); replies.emplace_back(new GotIntroMessage({introset}, txID));
} }
@ -170,7 +168,11 @@ namespace llarp
LogWarn( LogWarn(
"!!! Received PubIntro with relayed==false but we aren't" "!!! Received PubIntro with relayed==false but we aren't"
" candidate, intro derived key: ", " candidate, intro derived key: ",
keyStr, ", txid=", txID, ", message from: ", From); keyStr,
", txid=",
txID,
", message from: ",
From);
} }
} }

@ -17,18 +17,16 @@ namespace llarp
bool relayed = false; bool relayed = false;
uint64_t relayOrder = 0; uint64_t relayOrder = 0;
uint64_t txID = 0; uint64_t txID = 0;
PublishIntroMessage(const Key_t& from, bool relayed_) PublishIntroMessage(const Key_t& from, bool relayed_) : IMessage(from), relayed(relayed_)
: IMessage(from), relayed(relayed_)
{ {
} }
PublishIntroMessage(const llarp::service::EncryptedIntroSet& introset_, PublishIntroMessage(
uint64_t tx, bool relayed_, uint64_t relayOrder_) const llarp::service::EncryptedIntroSet& introset_,
: IMessage({}) uint64_t tx,
, introset(introset_) bool relayed_,
, relayed(relayed_) uint64_t relayOrder_)
, relayOrder(relayOrder_) : IMessage({}), introset(introset_), relayed(relayed_), relayOrder(relayOrder_), txID(tx)
, txID(tx)
{ {
} }
@ -42,8 +40,7 @@ namespace llarp
bool bool
HandleMessage( HandleMessage(
llarp_dht_context* ctx, llarp_dht_context* ctx, std::vector<std::unique_ptr<IMessage>>& replies) const override;
std::vector< std::unique_ptr< IMessage > >& replies) const override;
}; };
} // namespace dht } // namespace dht
} // namespace llarp } // namespace llarp

@ -13,8 +13,10 @@ namespace llarp
namespace dht namespace dht
{ {
PublishServiceJob::PublishServiceJob( PublishServiceJob::PublishServiceJob(
const TXOwner &asker, const service::EncryptedIntroSet &introset_, const TXOwner& asker,
AbstractContext *ctx, uint64_t relayOrder_) const service::EncryptedIntroSet& introset_,
AbstractContext* ctx,
uint64_t relayOrder_)
: TX<TXOwner, service::EncryptedIntroSet>(asker, asker, ctx) : TX<TXOwner, service::EncryptedIntroSet>(asker, asker, ctx)
, relayOrder(relayOrder_) , relayOrder(relayOrder_)
, introset(introset_) , introset(introset_)
@ -26,8 +28,7 @@ namespace llarp
{ {
if (value.derivedSigningKey != introset.derivedSigningKey) if (value.derivedSigningKey != introset.derivedSigningKey)
{ {
llarp::LogWarn( llarp::LogWarn("publish introset acknowledgement acked a different service");
"publish introset acknowledgement acked a different service");
return false; return false;
} }
const llarp_time_t now = llarp::time_now_ms(); const llarp_time_t now = llarp::time_now_ms();
@ -38,32 +39,31 @@ namespace llarp
PublishServiceJob::Start(const TXOwner& peer) PublishServiceJob::Start(const TXOwner& peer)
{ {
parent->DHTSendTo( parent->DHTSendTo(
peer.node.as_array(), peer.node.as_array(), new PublishIntroMessage(introset, peer.txid, false, relayOrder));
new PublishIntroMessage(introset, peer.txid, false, relayOrder));
} }
void void
PublishServiceJob::SendReply() PublishServiceJob::SendReply()
{ {
parent->DHTSendTo(whoasked.node.as_array(), parent->DHTSendTo(whoasked.node.as_array(), new GotIntroMessage({introset}, whoasked.txid));
new GotIntroMessage({introset}, whoasked.txid));
} }
LocalPublishServiceJob::LocalPublishServiceJob( LocalPublishServiceJob::LocalPublishServiceJob(
const TXOwner &peer, const PathID_t &fromID, uint64_t _txid, const TXOwner& peer,
const service::EncryptedIntroSet &introset, AbstractContext *ctx, const PathID_t& fromID,
uint64_t _txid,
const service::EncryptedIntroSet& introset,
AbstractContext* ctx,
uint64_t relayOrder) uint64_t relayOrder)
: PublishServiceJob(peer, introset, ctx, relayOrder) : PublishServiceJob(peer, introset, ctx, relayOrder), localPath(fromID), txid(_txid)
, localPath(fromID)
, txid(_txid)
{ {
} }
void void
LocalPublishServiceJob::SendReply() LocalPublishServiceJob::SendReply()
{ {
auto path = parent->GetRouter()->pathContext().GetByUpstream( auto path =
parent->OurKey().as_array(), localPath); parent->GetRouter()->pathContext().GetByUpstream(parent->OurKey().as_array(), localPath);
if (!path) if (!path)
{ {
llarp::LogWarn( llarp::LogWarn(

@ -17,9 +17,11 @@ namespace llarp
uint64_t relayOrder; uint64_t relayOrder;
service::EncryptedIntroSet introset; service::EncryptedIntroSet introset;
PublishServiceJob(const TXOwner &asker, PublishServiceJob(
const TXOwner& asker,
const service::EncryptedIntroSet& introset, const service::EncryptedIntroSet& introset,
AbstractContext *ctx, uint64_t relayOrder); AbstractContext* ctx,
uint64_t relayOrder);
bool bool
Validate(const service::EncryptedIntroSet& introset) const override; Validate(const service::EncryptedIntroSet& introset) const override;
@ -35,10 +37,13 @@ namespace llarp
{ {
PathID_t localPath; PathID_t localPath;
uint64_t txid; uint64_t txid;
LocalPublishServiceJob(const TXOwner &peer, const PathID_t &fromID, LocalPublishServiceJob(
const TXOwner& peer,
const PathID_t& fromID,
uint64_t txid, uint64_t txid,
const service::EncryptedIntroSet& introset, const service::EncryptedIntroSet& introset,
AbstractContext *ctx, uint64_t relayOrder); AbstractContext* ctx,
uint64_t relayOrder);
void void
SendReply() override; SendReply() override;

@ -13,12 +13,12 @@ namespace llarp
{ {
namespace dht namespace dht
{ {
RecursiveRouterLookup::RecursiveRouterLookup(const TXOwner &_whoasked, RecursiveRouterLookup::RecursiveRouterLookup(
const TXOwner& _whoasked,
const RouterID& _target, const RouterID& _target,
AbstractContext* ctx, AbstractContext* ctx,
RouterLookupHandler result) RouterLookupHandler result)
: TX< RouterID, RouterContact >(_whoasked, _target, ctx) : TX<RouterID, RouterContact>(_whoasked, _target, ctx), resultHandler(std::move(result))
, resultHandler(std::move(result))
{ {
peersAsked.insert(ctx->OurKey()); peersAsked.insert(ctx->OurKey());
@ -38,8 +38,7 @@ namespace llarp
void void
RecursiveRouterLookup::Start(const TXOwner& peer) RecursiveRouterLookup::Start(const TXOwner& peer)
{ {
parent->DHTSendTo(peer.node.as_array(), parent->DHTSendTo(peer.node.as_array(), new FindRouterMessage(peer.txid, target));
new FindRouterMessage(peer.txid, target));
} }
void void
@ -50,8 +49,7 @@ namespace llarp
RouterContact found; RouterContact found;
for (const auto& rc : valuesFound) for (const auto& rc : valuesFound)
{ {
if(found.OtherIsNewer(rc) if (found.OtherIsNewer(rc) && parent->GetRouter()->rcLookupHandler().CheckRC(rc))
&& parent->GetRouter()->rcLookupHandler().CheckRC(rc))
found = rc; found = rc;
} }
valuesFound.clear(); valuesFound.clear();
@ -65,7 +63,8 @@ namespace llarp
{ {
parent->DHTSendTo( parent->DHTSendTo(
whoasked.node.as_array(), whoasked.node.as_array(),
new GotRouterMessage({}, whoasked.txid, valuesFound, false), false); new GotRouterMessage({}, whoasked.txid, valuesFound, false),
false);
} }
} }
} // namespace dht } // namespace dht

@ -13,8 +13,11 @@ namespace llarp
struct RecursiveRouterLookup : public TX<RouterID, RouterContact> struct RecursiveRouterLookup : public TX<RouterID, RouterContact>
{ {
RouterLookupHandler resultHandler; RouterLookupHandler resultHandler;
RecursiveRouterLookup(const TXOwner &whoasked, const RouterID &target, RecursiveRouterLookup(
AbstractContext *ctx, RouterLookupHandler result); const TXOwner& whoasked,
const RouterID& target,
AbstractContext* ctx,
RouterLookupHandler result);
bool bool
Validate(const RouterContact& rc) const override; Validate(const RouterContact& rc) const override;

@ -10,8 +10,11 @@ namespace llarp
namespace dht namespace dht
{ {
ServiceAddressLookup::ServiceAddressLookup( ServiceAddressLookup::ServiceAddressLookup(
const TXOwner &asker, const Key_t &addr, AbstractContext *ctx, const TXOwner& asker,
uint32_t order, service::EncryptedIntroSetLookupHandler handler) const Key_t& addr,
AbstractContext* ctx,
uint32_t order,
service::EncryptedIntroSetLookupHandler handler)
: TX<TXOwner, service::EncryptedIntroSet>(asker, asker, ctx) : TX<TXOwner, service::EncryptedIntroSet>(asker, asker, ctx)
, location(addr) , location(addr)
, handleResult(std::move(handler)) , handleResult(std::move(handler))
@ -21,8 +24,7 @@ namespace llarp
} }
bool bool
ServiceAddressLookup::Validate( ServiceAddressLookup::Validate(const service::EncryptedIntroSet& value) const
const service::EncryptedIntroSet &value) const
{ {
if (!value.Verify(parent->Now())) if (!value.Verify(parent->Now()))
{ {
@ -40,8 +42,8 @@ namespace llarp
void void
ServiceAddressLookup::Start(const TXOwner& peer) ServiceAddressLookup::Start(const TXOwner& peer)
{ {
parent->DHTSendTo(peer.node.as_array(), parent->DHTSendTo(
new FindIntroMessage(peer.txid, location, relayOrder)); peer.node.as_array(), new FindIntroMessage(peer.txid, location, relayOrder));
} }
void void
@ -63,8 +65,7 @@ namespace llarp
{ {
handleResult(valuesFound); handleResult(valuesFound);
} }
parent->DHTSendTo(whoasked.node.as_array(), parent->DHTSendTo(whoasked.node.as_array(), new GotIntroMessage(valuesFound, whoasked.txid));
new GotIntroMessage(valuesFound, whoasked.txid));
} }
} // namespace dht } // namespace dht
} // namespace llarp } // namespace llarp

@ -12,15 +12,17 @@ namespace llarp
{ {
struct TXOwner; struct TXOwner;
struct ServiceAddressLookup struct ServiceAddressLookup : public TX<TXOwner, service::EncryptedIntroSet>
: public TX< TXOwner, service::EncryptedIntroSet >
{ {
Key_t location; Key_t location;
service::EncryptedIntroSetLookupHandler handleResult; service::EncryptedIntroSetLookupHandler handleResult;
uint32_t relayOrder; uint32_t relayOrder;
ServiceAddressLookup(const TXOwner &asker, const Key_t &addr, ServiceAddressLookup(
AbstractContext *ctx, uint32_t relayOrder, const TXOwner& asker,
const Key_t& addr,
AbstractContext* ctx,
uint32_t relayOrder,
service::EncryptedIntroSetLookupHandler handler); service::EncryptedIntroSetLookupHandler handler);
bool bool

@ -28,15 +28,13 @@ namespace llarp
void void
TagLookup::Start(const TXOwner& peer) TagLookup::Start(const TXOwner& peer)
{ {
parent->DHTSendTo(peer.node.as_array(), parent->DHTSendTo(peer.node.as_array(), new FindIntroMessage(target, peer.txid));
new FindIntroMessage(target, peer.txid));
} }
void void
TagLookup::SendReply() TagLookup::SendReply()
{ {
parent->DHTSendTo(whoasked.node.as_array(), parent->DHTSendTo(whoasked.node.as_array(), new GotIntroMessage({}, whoasked.txid));
new GotIntroMessage({}, whoasked.txid));
} }
} // namespace dht } // namespace dht
} // namespace llarp } // namespace llarp

@ -12,10 +12,9 @@ namespace llarp
struct TagLookup : public TX<service::Tag, service::EncryptedIntroSet> struct TagLookup : public TX<service::Tag, service::EncryptedIntroSet>
{ {
uint64_t recursionDepth; uint64_t recursionDepth;
TagLookup(const TXOwner &asker, const service::Tag &tag, TagLookup(
AbstractContext *ctx, uint64_t recursion) const TXOwner& asker, const service::Tag& tag, AbstractContext* ctx, uint64_t recursion)
: TX< service::Tag, service::EncryptedIntroSet >(asker, tag, ctx) : TX<service::Tag, service::EncryptedIntroSet>(asker, tag, ctx), recursionDepth(recursion)
, recursionDepth(recursion)
{ {
} }

@ -40,16 +40,18 @@ namespace llarp
util::StatusObject obj{{"whoasked", whoasked.ExtractStatus()}, util::StatusObject obj{{"whoasked", whoasked.ExtractStatus()},
{"target", target.ExtractStatus()}}; {"target", target.ExtractStatus()}};
std::vector<util::StatusObject> foundObjs; std::vector<util::StatusObject> foundObjs;
std::transform(valuesFound.begin(), valuesFound.end(), std::transform(
valuesFound.begin(),
valuesFound.end(),
std::back_inserter(foundObjs), std::back_inserter(foundObjs),
[](const auto& item) -> util::StatusObject { [](const auto& item) -> util::StatusObject { return item.ExtractStatus(); });
return item.ExtractStatus();
});
obj["found"] = foundObjs; obj["found"] = foundObjs;
std::vector<std::string> asked; std::vector<std::string> asked;
std::transform( std::transform(
peersAsked.begin(), peersAsked.end(), std::back_inserter(asked), peersAsked.begin(),
peersAsked.end(),
std::back_inserter(asked),
[](const auto& item) -> std::string { return item.ToString(); }); [](const auto& item) -> std::string { return item.ToString(); });
obj["asked"] = asked; obj["asked"] = asked;
return obj; return obj;

@ -32,25 +32,30 @@ namespace llarp
{ {
util::StatusObject obj{}; util::StatusObject obj{};
std::vector<util::StatusObject> txObjs, timeoutsObjs, waitingObjs; std::vector<util::StatusObject> txObjs, timeoutsObjs, waitingObjs;
std::transform(tx.begin(), tx.end(), std::back_inserter(txObjs), std::transform(
tx.begin(),
tx.end(),
std::back_inserter(txObjs),
[](const auto& item) -> util::StatusObject { [](const auto& item) -> util::StatusObject {
return util::StatusObject{ return util::StatusObject{{"owner", item.first.ExtractStatus()},
{"owner", item.first.ExtractStatus()},
{"tx", item.second->ExtractStatus()}}; {"tx", item.second->ExtractStatus()}};
}); });
obj["tx"] = txObjs; obj["tx"] = txObjs;
std::transform( std::transform(
timeouts.begin(), timeouts.end(), std::back_inserter(timeoutsObjs), timeouts.begin(),
timeouts.end(),
std::back_inserter(timeoutsObjs),
[](const auto& item) -> util::StatusObject { [](const auto& item) -> util::StatusObject {
return util::StatusObject{{"time", to_json(item.second)}, return util::StatusObject{{"time", to_json(item.second)},
{"target", item.first.ExtractStatus()}}; {"target", item.first.ExtractStatus()}};
}); });
obj["timeouts"] = timeoutsObjs; obj["timeouts"] = timeoutsObjs;
std::transform(waiting.begin(), waiting.end(), std::transform(
waiting.begin(),
waiting.end(),
std::back_inserter(waitingObjs), std::back_inserter(waitingObjs),
[](const auto& item) -> util::StatusObject { [](const auto& item) -> util::StatusObject {
return util::StatusObject{ return util::StatusObject{{"target", item.first.ExtractStatus()},
{"target", item.first.ExtractStatus()},
{"whoasked", item.second.ExtractStatus()}}; {"whoasked", item.second.ExtractStatus()}};
}); });
obj["waiting"] = waitingObjs; obj["waiting"] = waitingObjs;
@ -70,8 +75,12 @@ namespace llarp
} }
void void
NewTX(const TXOwner& askpeer, const TXOwner& whoasked, const K& k, NewTX(
TX< K, V >* t, llarp_time_t requestTimeoutMS = 15s); const TXOwner& askpeer,
const TXOwner& whoasked,
const K& k,
TX<K, V>* t,
llarp_time_t requestTimeoutMS = 15s);
/// mark tx as not fond /// mark tx as not fond
void void
@ -85,8 +94,12 @@ namespace llarp
/// inform all watches for key of values found /// inform all watches for key of values found
void void
Inform(TXOwner from, K key, std::vector< V > values, Inform(
bool sendreply = false, bool removeTimeouts = true); TXOwner from,
K key,
std::vector<V> values,
bool sendreply = false,
bool removeTimeouts = true);
void void
Expire(llarp_time_t now); Expire(llarp_time_t now);
@ -107,8 +120,10 @@ namespace llarp
template <typename K, typename V, typename K_Hash> template <typename K, typename V, typename K_Hash>
void void
TXHolder< K, V, K_Hash >::NewTX(const TXOwner& askpeer, TXHolder<K, V, K_Hash>::NewTX(
const TXOwner& whoasked, const K& k, const TXOwner& askpeer,
const TXOwner& whoasked,
const K& k,
TX<K, V>* t, TX<K, V>* t,
llarp_time_t requestTimeoutMS) llarp_time_t requestTimeoutMS)
{ {
@ -130,8 +145,7 @@ namespace llarp
template <typename K, typename V, typename K_Hash> template <typename K, typename V, typename K_Hash>
void void
TXHolder< K, V, K_Hash >::NotFound(const TXOwner& from, TXHolder<K, V, K_Hash>::NotFound(const TXOwner& from, const std::unique_ptr<Key_t>&)
const std::unique_ptr< Key_t >&)
{ {
auto txitr = tx.find(from); auto txitr = tx.find(from);
if (txitr == tx.end()) if (txitr == tx.end())
@ -143,9 +157,8 @@ namespace llarp
template <typename K, typename V, typename K_Hash> template <typename K, typename V, typename K_Hash>
void void
TXHolder< K, V, K_Hash >::Inform(TXOwner from, K key, TXHolder<K, V, K_Hash>::Inform(
std::vector< V > values, bool sendreply, TXOwner from, K key, std::vector<V> values, bool sendreply, bool removeTimeouts)
bool removeTimeouts)
{ {
auto range = waiting.equal_range(key); auto range = waiting.equal_range(key);
auto itr = range.first; auto itr = range.first;

@ -67,8 +67,7 @@ namespace llarp
{ {
} }
Message::Message(const MessageHeader& hdr) Message::Message(const MessageHeader& hdr) : hdr_id(hdr.id), hdr_fields(hdr.fields)
: hdr_id(hdr.id), hdr_fields(hdr.fields)
{ {
questions.resize(size_t(hdr.qd_count)); questions.resize(size_t(hdr.qd_count));
answers.resize(size_t(hdr.an_count)); answers.resize(size_t(hdr.an_count));

@ -35,9 +35,9 @@ namespace llarp
bool bool
operator==(const MessageHeader& other) const operator==(const MessageHeader& other) const
{ {
return id == other.id && fields == other.fields return id == other.id && fields == other.fields && qd_count == other.qd_count
&& qd_count == other.qd_count && an_count == other.an_count && an_count == other.an_count && ns_count == other.ns_count
&& ns_count == other.ns_count && ar_count == other.ar_count; && ar_count == other.ar_count;
} }
}; };

@ -29,8 +29,7 @@ namespace llarp
bool bool
operator==(const Question& other) const operator==(const Question& other) const
{ {
return qname == other.qname && qtype == other.qtype return qname == other.qname && qtype == other.qtype && qclass == other.qclass;
&& qclass == other.qclass;
} }
Name_t qname; Name_t qname;

@ -9,8 +9,11 @@ namespace llarp
{ {
namespace dns namespace dns
{ {
Proxy::Proxy(llarp_ev_loop_ptr serverLoop, Logic_ptr serverLogic, Proxy::Proxy(
llarp_ev_loop_ptr clientLoop, Logic_ptr clientLogic, llarp_ev_loop_ptr serverLoop,
Logic_ptr serverLogic,
llarp_ev_loop_ptr clientLoop,
Logic_ptr clientLogic,
IQueryHandler* h) IQueryHandler* h)
: m_ServerLoop(std::move(serverLoop)) : m_ServerLoop(std::move(serverLoop))
, m_ClientLoop(std::move(clientLoop)) , m_ClientLoop(std::move(clientLoop))
@ -32,8 +35,7 @@ namespace llarp
} }
bool bool
Proxy::Start(const llarp::Addr addr, Proxy::Start(const llarp::Addr addr, const std::vector<llarp::Addr>& resolvers)
const std::vector< llarp::Addr >& resolvers)
{ {
m_Resolvers.clear(); m_Resolvers.clear();
m_Resolvers = resolvers; m_Resolvers = resolvers;
@ -57,29 +59,25 @@ namespace llarp
} }
void void
Proxy::HandleUDPRecv_server(llarp_udp_io* u, const sockaddr* from, Proxy::HandleUDPRecv_server(llarp_udp_io* u, const sockaddr* from, ManagedBuffer buf)
ManagedBuffer buf)
{ {
const llarp::Addr addr(*from); const llarp::Addr addr(*from);
Buffer_t msgbuf = CopyBuffer(buf.underlying); Buffer_t msgbuf = CopyBuffer(buf.underlying);
auto self = static_cast<Proxy*>(u->user)->shared_from_this(); auto self = static_cast<Proxy*>(u->user)->shared_from_this();
// yes we use the server loop here because if the server loop is not the // yes we use the server loop here because if the server loop is not the
// client loop we'll crash again // client loop we'll crash again
LogicCall(self->m_ServerLogic, [self, addr, msgbuf]() { LogicCall(
self->HandlePktServer(addr, msgbuf); self->m_ServerLogic, [self, addr, msgbuf]() { self->HandlePktServer(addr, msgbuf); });
});
} }
void void
Proxy::HandleUDPRecv_client(llarp_udp_io* u, const sockaddr* from, Proxy::HandleUDPRecv_client(llarp_udp_io* u, const sockaddr* from, ManagedBuffer buf)
ManagedBuffer buf)
{ {
const llarp::Addr addr(*from); const llarp::Addr addr(*from);
Buffer_t msgbuf = CopyBuffer(buf.underlying); Buffer_t msgbuf = CopyBuffer(buf.underlying);
auto self = static_cast<Proxy*>(u->user)->shared_from_this(); auto self = static_cast<Proxy*>(u->user)->shared_from_this();
LogicCall(self->m_ServerLogic, [self, addr, msgbuf]() { LogicCall(
self->HandlePktClient(addr, msgbuf); self->m_ServerLogic, [self, addr, msgbuf]() { self->HandlePktClient(addr, msgbuf); });
});
} }
llarp::Addr llarp::Addr
@ -158,8 +156,7 @@ namespace llarp
msg.hdr_id = itr->first.txid; msg.hdr_id = itr->first.txid;
if (!m_QueryHandler->HandleHookedDNSMessage( if (!m_QueryHandler->HandleHookedDNSMessage(
std::move(msg), std::move(msg),
std::bind(&Proxy::SendServerMessageTo, self, requester, std::bind(&Proxy::SendServerMessageTo, self, requester, std::placeholders::_1)))
std::placeholders::_1)))
{ {
llarp::LogWarn("failed to handle hooked dns"); llarp::LogWarn("failed to handle hooked dns");
} }
@ -218,8 +215,7 @@ namespace llarp
{ {
if (!m_QueryHandler->HandleHookedDNSMessage( if (!m_QueryHandler->HandleHookedDNSMessage(
std::move(msg), std::move(msg),
std::bind(&Proxy::SendServerMessageTo, self, from, std::bind(&Proxy::SendServerMessageTo, self, from, std::placeholders::_1)))
std::placeholders::_1)))
{ {
llarp::LogWarn("failed to handle hooked dns"); llarp::LogWarn("failed to handle hooked dns");
} }

@ -24,20 +24,21 @@ namespace llarp
/// handle a hooked message /// handle a hooked message
virtual bool virtual bool
HandleHookedDNSMessage(Message query, HandleHookedDNSMessage(Message query, std::function<void(Message)> sendReply) = 0;
std::function< void(Message) > sendReply) = 0;
}; };
struct Proxy : public std::enable_shared_from_this<Proxy> struct Proxy : public std::enable_shared_from_this<Proxy>
{ {
using Logic_ptr = std::shared_ptr<Logic>; using Logic_ptr = std::shared_ptr<Logic>;
Proxy(llarp_ev_loop_ptr serverLoop, Logic_ptr serverLogic, Proxy(
llarp_ev_loop_ptr clientLoop, Logic_ptr clientLogic, llarp_ev_loop_ptr serverLoop,
Logic_ptr serverLogic,
llarp_ev_loop_ptr clientLoop,
Logic_ptr clientLogic,
IQueryHandler* handler); IQueryHandler* handler);
bool bool
Start(const llarp::Addr addr, Start(const llarp::Addr addr, const std::vector<llarp::Addr>& resolvers);
const std::vector< llarp::Addr >& resolvers);
void void
Stop(); Stop();
@ -47,11 +48,9 @@ namespace llarp
private: private:
/// low level packet handler /// low level packet handler
static void static void
HandleUDPRecv_client(llarp_udp_io*, const struct sockaddr*, HandleUDPRecv_client(llarp_udp_io*, const struct sockaddr*, ManagedBuffer);
ManagedBuffer);
static void static void
HandleUDPRecv_server(llarp_udp_io*, const struct sockaddr*, HandleUDPRecv_server(llarp_udp_io*, const struct sockaddr*, ManagedBuffer);
ManagedBuffer);
/// low level ticker /// low level ticker
static void static void

@ -24,8 +24,7 @@ llarp_make_ev_loop()
} }
void void
llarp_ev_loop_run_single_process(llarp_ev_loop_ptr ev, llarp_ev_loop_run_single_process(llarp_ev_loop_ptr ev, std::shared_ptr<llarp::Logic> logic)
std::shared_ptr< llarp::Logic > logic)
{ {
while (ev->running()) while (ev->running())
{ {
@ -38,8 +37,7 @@ llarp_ev_loop_run_single_process(llarp_ev_loop_ptr ev,
} }
int int
llarp_ev_add_udp(struct llarp_ev_loop *ev, struct llarp_udp_io *udp, llarp_ev_add_udp(struct llarp_ev_loop* ev, struct llarp_udp_io* udp, const struct sockaddr* src)
const struct sockaddr *src)
{ {
udp->parent = ev; udp->parent = ev;
if (ev->udp_listen(udp, src)) if (ev->udp_listen(udp, src))
@ -70,8 +68,7 @@ llarp_ev_loop_stop(const llarp_ev_loop_ptr &loop)
} }
int int
llarp_ev_udp_sendto(struct llarp_udp_io *udp, const sockaddr *to, llarp_ev_udp_sendto(struct llarp_udp_io* udp, const sockaddr* to, const llarp_buffer_t& buf)
const llarp_buffer_t &buf)
{ {
return udp->sendto(udp, to, buf.base, buf.sz); return udp->sendto(udp, to, buf.base, buf.sz);
} }
@ -117,8 +114,7 @@ llarp_ev_tun_async_write(struct llarp_tun_io *tun, const llarp_buffer_t &buf)
#ifndef _WIN32 #ifndef _WIN32
return tun->writepkt(tun, buf.base, buf.sz); return tun->writepkt(tun, buf.base, buf.sz);
#else #else
return static_cast< win32_tun_io * >(tun->impl)->queue_write(buf.base, return static_cast<win32_tun_io*>(tun->impl)->queue_write(buf.base, buf.sz);
buf.sz);
#endif #endif
} }
@ -145,8 +141,7 @@ llarp_tcp_conn_async_write(struct llarp_tcp_conn *conn, const llarp_buffer_t &b)
} }
void void
llarp_tcp_async_try_connect(struct llarp_ev_loop *loop, llarp_tcp_async_try_connect(struct llarp_ev_loop* loop, struct llarp_tcp_connecter* tcp)
struct llarp_tcp_connecter *tcp)
{ {
tcp->loop = loop; tcp->loop = loop;
llarp::string_view addr_str, port_str; llarp::string_view addr_str, port_str;
@ -182,8 +177,8 @@ llarp_tcp_async_try_connect(struct llarp_ev_loop *loop,
} }
bool bool
llarp_tcp_serve(struct llarp_ev_loop *loop, struct llarp_tcp_acceptor *tcp, llarp_tcp_serve(
const struct sockaddr *bindaddr) struct llarp_ev_loop* loop, struct llarp_tcp_acceptor* tcp, const struct sockaddr* bindaddr)
{ {
tcp->loop = loop; tcp->loop = loop;
return loop->tcp_listen(tcp, bindaddr); return loop->tcp_listen(tcp, bindaddr);

@ -51,8 +51,7 @@ llarp_make_ev_loop();
// run mainloop // run mainloop
void void
llarp_ev_loop_run_single_process(llarp_ev_loop_ptr ev, llarp_ev_loop_run_single_process(llarp_ev_loop_ptr ev, std::shared_ptr<llarp::Logic> logic);
std::shared_ptr< llarp::Logic > logic);
/// get the current time on the event loop /// get the current time on the event loop
llarp_time_t llarp_time_t
@ -78,11 +77,9 @@ struct llarp_udp_io
/// called every event loop tick after reads /// called every event loop tick after reads
void (*tick)(struct llarp_udp_io*); void (*tick)(struct llarp_udp_io*);
/// sockaddr * is the source address /// sockaddr * is the source address
void (*recvfrom)(struct llarp_udp_io *, const struct sockaddr *, void (*recvfrom)(struct llarp_udp_io*, const struct sockaddr*, ManagedBuffer);
ManagedBuffer);
/// set by parent /// set by parent
int (*sendto)(struct llarp_udp_io *, const struct sockaddr *, const byte_t *, int (*sendto)(struct llarp_udp_io*, const struct sockaddr*, const byte_t*, size_t);
size_t);
}; };
/// get all packets recvieved last tick /// get all packets recvieved last tick
@ -92,13 +89,11 @@ llarp_ev_udp_recvmany(struct llarp_udp_io *udp, struct llarp_pkt_list *pkts);
/// add UDP handler /// add UDP handler
int int
llarp_ev_add_udp(struct llarp_ev_loop *ev, struct llarp_udp_io *udp, llarp_ev_add_udp(struct llarp_ev_loop* ev, struct llarp_udp_io* udp, const struct sockaddr* src);
const struct sockaddr *src);
/// send a UDP packet /// send a UDP packet
int int
llarp_ev_udp_sendto(struct llarp_udp_io *udp, const struct sockaddr *to, llarp_ev_udp_sendto(struct llarp_udp_io* udp, const struct sockaddr* to, const llarp_buffer_t& pkt);
const llarp_buffer_t &pkt);
/// close UDP handler /// close UDP handler
int int
@ -160,8 +155,7 @@ struct llarp_tcp_connecter
/// async try connecting to a remote connection 1 time /// async try connecting to a remote connection 1 time
void void
llarp_tcp_async_try_connect(struct llarp_ev_loop *l, llarp_tcp_async_try_connect(struct llarp_ev_loop* l, struct llarp_tcp_connecter* tcp);
struct llarp_tcp_connecter *tcp);
/// handles inbound connections /// handles inbound connections
struct llarp_tcp_acceptor struct llarp_tcp_acceptor
@ -186,8 +180,7 @@ struct llarp_tcp_acceptor
/// return false if failed to bind /// return false if failed to bind
/// return true on success /// return true on success
bool bool
llarp_tcp_serve(struct llarp_ev_loop *loop, struct llarp_tcp_acceptor *t, llarp_tcp_serve(struct llarp_ev_loop* loop, struct llarp_tcp_acceptor* t, const sockaddr* bindaddr);
const sockaddr *bindaddr);
/// close and stop accepting connections /// close and stop accepting connections
void void

@ -31,8 +31,7 @@ typedef struct sockaddr_un
} SOCKADDR_UN, *PSOCKADDR_UN; } SOCKADDR_UN, *PSOCKADDR_UN;
#else #else
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) \ #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || (__APPLE__ && __MACH__)
|| (__APPLE__ && __MACH__)
#include <sys/event.h> #include <sys/event.h>
#endif #endif
@ -137,15 +136,13 @@ namespace llarp
using LosslessWriteQueue_t = std::deque<WriteBuffer>; using LosslessWriteQueue_t = std::deque<WriteBuffer>;
intptr_t intptr_t fd; // Sockets only, fuck UNIX-style reactive IO with a rusty knife
fd; // Sockets only, fuck UNIX-style reactive IO with a rusty knife
int flags = 0; int flags = 0;
win32_ev_io(intptr_t f) : fd(f){}; win32_ev_io(intptr_t f) : fd(f){};
/// for tcp /// for tcp
win32_ev_io(intptr_t f, LosslessWriteQueue_t* q) win32_ev_io(intptr_t f, LosslessWriteQueue_t* q) : fd(f), m_BlockingWriteQueue(q)
: fd(f), m_BlockingWriteQueue(q)
{ {
} }
@ -154,8 +151,7 @@ namespace llarp
{ {
char ebuf[1024]; char ebuf[1024];
int err = WSAGetLastError(); int err = WSAGetLastError();
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, err, LANG_NEUTRAL, FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, err, LANG_NEUTRAL, ebuf, 1024, nullptr);
ebuf, 1024, nullptr);
llarp::LogError(ebuf); llarp::LogError(ebuf);
} }
@ -341,18 +337,20 @@ namespace llarp
}; };
}; };
using LossyWriteQueue_t = using LossyWriteQueue_t = llarp::util::CoDelQueue<
llarp::util::CoDelQueue< WriteBuffer, WriteBuffer::GetTime, WriteBuffer,
WriteBuffer::PutTime, WriteBuffer::Compare, WriteBuffer::GetTime,
WriteBuffer::GetNow, llarp::util::NullMutex, WriteBuffer::PutTime,
WriteBuffer::Compare,
WriteBuffer::GetNow,
llarp::util::NullMutex,
llarp::util::NullLock>; llarp::util::NullLock>;
using LosslessWriteQueue_t = std::deque<WriteBuffer>; using LosslessWriteQueue_t = std::deque<WriteBuffer>;
int fd; int fd;
int flags = 0; int flags = 0;
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) \ #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || (__APPLE__ && __MACH__)
|| (__APPLE__ && __MACH__)
struct kevent change; struct kevent change;
#endif #endif
@ -380,7 +378,8 @@ namespace llarp
read(byte_t* buf, size_t sz) = 0; read(byte_t* buf, size_t sz) = 0;
virtual int virtual int
sendto(__attribute__((unused)) const sockaddr* dst, sendto(
__attribute__((unused)) const sockaddr* dst,
__attribute__((unused)) const void* data, __attribute__((unused)) const void* data,
__attribute__((unused)) size_t sz) __attribute__((unused)) size_t sz)
{ {
@ -540,8 +539,7 @@ namespace llarp
} }
/// inbound /// inbound
tcp_conn(llarp_ev_loop* loop, int _fd) tcp_conn(llarp_ev_loop* loop, int _fd) : ev_io(_fd, new LosslessWriteQueue_t{}), _conn(nullptr)
: ev_io(_fd, new LosslessWriteQueue_t{}), _conn(nullptr)
{ {
tcp.impl = this; tcp.impl = this;
tcp.loop = loop; tcp.loop = loop;
@ -553,8 +551,7 @@ namespace llarp
} }
/// outbound /// outbound
tcp_conn(llarp_ev_loop* loop, int _fd, const sockaddr* addr, tcp_conn(llarp_ev_loop* loop, int _fd, const sockaddr* addr, llarp_tcp_connecter* conn)
llarp_tcp_connecter* conn)
: ev_io(_fd, new LosslessWriteQueue_t{}), _conn(conn) : ev_io(_fd, new LosslessWriteQueue_t{}), _conn(conn)
{ {
socklen_t slen = sizeof(sockaddr_in); socklen_t slen = sizeof(sockaddr_in);
@ -621,8 +618,7 @@ namespace llarp
#else #else
char ebuf[1024]; char ebuf[1024];
int err = WSAGetLastError(); int err = WSAGetLastError();
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, err, LANG_NEUTRAL, FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, err, LANG_NEUTRAL, ebuf, 1024, nullptr);
ebuf, 1024, nullptr);
llarp::LogError("tcp_conn error: ", ebuf); llarp::LogError("tcp_conn error: ", ebuf);
#endif #endif
if (_conn->error) if (_conn->error)
@ -645,8 +641,7 @@ namespace llarp
{ {
llarp_ev_loop* loop; llarp_ev_loop* loop;
llarp_tcp_acceptor* tcp; llarp_tcp_acceptor* tcp;
tcp_serv(llarp_ev_loop* l, int _fd, llarp_tcp_acceptor* t) tcp_serv(llarp_ev_loop* l, int _fd, llarp_tcp_acceptor* t) : ev_io(_fd), loop(l), tcp(t)
: ev_io(_fd), loop(l), tcp(t)
{ {
tcp->impl = this; tcp->impl = this;
} }
@ -669,8 +664,7 @@ namespace llarp
#ifdef _WIN32 #ifdef _WIN32
struct llarp_fd_promise struct llarp_fd_promise
{ {
void void Set(std::pair<int, int>)
Set(std::pair< int, int >)
{ {
} }
@ -742,8 +736,7 @@ struct llarp_ev_loop
tick(int ms) = 0; tick(int ms) = 0;
virtual uint32_t virtual uint32_t
call_after_delay(llarp_time_t delay_ms, call_after_delay(llarp_time_t delay_ms, std::function<void(void)> callback) = 0;
std::function< void(void) > callback) = 0;
virtual void virtual void
cancel_delayed_call(uint32_t call_id) = 0; cancel_delayed_call(uint32_t call_id) = 0;

@ -7,8 +7,7 @@
namespace libuv namespace libuv
{ {
#define LoopCall(h, ...) \ #define LoopCall(h, ...) LogicCall(static_cast<Loop*>((h)->loop->data)->m_Logic, __VA_ARGS__)
LogicCall(static_cast< Loop* >((h)->loop->data)->m_Logic, __VA_ARGS__)
struct glue struct glue
{ {
@ -106,8 +105,7 @@ namespace libuv
bool bool
ConnectAsync() ConnectAsync()
{ {
return uv_tcp_connect(&m_Connect, &m_Handle, m_Addr, &OnOutboundConnect) return uv_tcp_connect(&m_Connect, &m_Handle, m_Addr, &OnOutboundConnect) != -1;
!= -1;
} }
static void static void
@ -353,8 +351,7 @@ namespace libuv
{ {
uv_check_start(&m_Ticker, &OnTick); uv_check_start(&m_Ticker, &OnTick);
m_Accept->close = &ExplicitCloseAccept; m_Accept->close = &ExplicitCloseAccept;
return uv_tcp_bind(&m_Handle, m_Addr, 0) == 0 return uv_tcp_bind(&m_Handle, m_Addr, 0) == 0 && uv_listen(Stream(), 5, &OnAccept) == 0;
&& uv_listen(Stream(), 5, &OnAccept) == 0;
} }
}; };
@ -404,8 +401,7 @@ namespace libuv
llarp_pkt_list m_LastPackets; llarp_pkt_list m_LastPackets;
std::array<char, 1500> m_Buffer; std::array<char, 1500> m_Buffer;
udp_glue(uv_loop_t* loop, llarp_udp_io* udp, const sockaddr* src) udp_glue(uv_loop_t* loop, llarp_udp_io* udp, const sockaddr* src) : m_UDP(udp), m_Addr(*src)
: m_UDP(udp), m_Addr(*src)
{ {
m_Handle.data = this; m_Handle.data = this;
m_Ticker.data = this; m_Ticker.data = this;
@ -422,14 +418,13 @@ namespace libuv
} }
static void static void
OnRecv(uv_udp_t* handle, ssize_t nread, const uv_buf_t* buf, OnRecv(
const struct sockaddr* addr, unsigned) uv_udp_t* handle, ssize_t nread, const uv_buf_t* buf, const struct sockaddr* addr, unsigned)
{ {
udp_glue* glue = static_cast<udp_glue*>(handle->data); udp_glue* glue = static_cast<udp_glue*>(handle->data);
if (addr) if (addr)
glue->RecvFrom(nread, buf, addr); glue->RecvFrom(nread, buf, addr);
if(nread <= 0 || glue->m_UDP == nullptr if (nread <= 0 || glue->m_UDP == nullptr || glue->m_UDP->recvfrom != nullptr)
|| glue->m_UDP->recvfrom != nullptr)
delete[] buf->base; delete[] buf->base;
} }
@ -711,8 +706,7 @@ namespace libuv
llarp::LogError("failed to start up ", m_Tun->ifname); llarp::LogError("failed to start up ", m_Tun->ifname);
return false; return false;
} }
if(tuntap_set_ip(m_Device, m_Tun->ifaddr, m_Tun->ifaddr, m_Tun->netmask) if (tuntap_set_ip(m_Device, m_Tun->ifaddr, m_Tun->ifaddr, m_Tun->netmask) == -1)
== -1)
{ {
llarp::LogError("failed to set address on ", m_Tun->ifname); llarp::LogError("failed to set address on ", m_Tun->ifname);
return false; return false;
@ -724,8 +718,7 @@ namespace libuv
} }
if (m_Device->tun_fd == -1) if (m_Device->tun_fd == -1)
{ {
llarp::LogError("tun interface ", m_Tun->ifname, llarp::LogError("tun interface ", m_Tun->ifname, " has invalid fd: ", m_Device->tun_fd);
" has invalid fd: ", m_Device->tun_fd);
return false; return false;
} }
@ -741,11 +734,9 @@ namespace libuv
llarp::LogError("failed to start polling on ", m_Tun->ifname); llarp::LogError("failed to start polling on ", m_Tun->ifname);
return false; return false;
} }
if(uv_check_init(loop, &m_Ticker) != 0 if (uv_check_init(loop, &m_Ticker) != 0 || uv_check_start(&m_Ticker, &OnTick) != 0)
|| uv_check_start(&m_Ticker, &OnTick) != 0)
{ {
llarp::LogError("failed to set up tun interface timer for ", llarp::LogError("failed to set up tun interface timer for ", m_Tun->ifname);
m_Tun->ifname);
return false; return false;
} }
m_Tun->writepkt = &WritePkt; m_Tun->writepkt = &WritePkt;
@ -763,11 +754,7 @@ namespace libuv
loop->process_cancel_queue(); loop->process_cancel_queue();
} }
Loop::Loop() Loop::Loop() : llarp_ev_loop(), m_LogicCalls(1024), m_timerQueue(20), m_timerCancelQueue(20)
: llarp_ev_loop()
, m_LogicCalls(1024)
, m_timerQueue(20)
, m_timerCancelQueue(20)
{ {
} }
@ -789,7 +776,9 @@ namespace libuv
#endif #endif
m_LogicCaller.data = this; m_LogicCaller.data = this;
int err; int err;
if((err = uv_async_init(&m_Impl, &m_LogicCaller, if ((err = uv_async_init(
&m_Impl,
&m_LogicCaller,
[](uv_async_t* h) { [](uv_async_t* h) {
Loop* l = static_cast<Loop*>(h->data); Loop* l = static_cast<Loop*>(h->data);
while (not l->m_LogicCalls.empty()) while (not l->m_LogicCalls.empty())
@ -870,8 +859,7 @@ namespace libuv
{ {
// have to delete timer handle this way because libuv. // have to delete timer handle this way because libuv.
uv_timer_stop(timer); uv_timer_stop(timer);
uv_close((uv_handle_t*)timer, uv_close((uv_handle_t*)timer, [](uv_handle_t* handle) { delete (uv_timer_t*)handle; });
[](uv_handle_t* handle) { delete(uv_timer_t*)handle; });
} }
static void static void
@ -886,8 +874,7 @@ namespace libuv
} }
uint32_t uint32_t
Loop::call_after_delay(llarp_time_t delay_ms, Loop::call_after_delay(llarp_time_t delay_ms, std::function<void(void)> callback)
std::function< void(void) > callback)
{ {
#ifdef TESTNET_SPEED #ifdef TESTNET_SPEED
delay_ms *= TESTNET_SPEED; delay_ms *= TESTNET_SPEED;

@ -49,8 +49,7 @@ namespace libuv
tick(int ms) override; tick(int ms) override;
uint32_t uint32_t
call_after_delay(llarp_time_t delay_ms, call_after_delay(llarp_time_t delay_ms, std::function<void(void)> callback) override;
std::function< void(void) > callback) override;
void void
cancel_delayed_call(uint32_t job_id) override; cancel_delayed_call(uint32_t job_id) override;

@ -53,8 +53,7 @@ win32_tun_io::setup()
{ {
char ebuf[1024]; char ebuf[1024];
int err = GetLastError(); int err = GetLastError();
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, err, LANG_NEUTRAL, ebuf, FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, err, LANG_NEUTRAL, ebuf, 1024, nullptr);
1024, nullptr);
llarp::LogWarn("failed to put interface up: ", ebuf); llarp::LogWarn("failed to put interface up: ", ebuf);
return false; return false;
} }
@ -83,8 +82,7 @@ win32_tun_io::add_ev(llarp_ev_loop* loop)
unsigned long numCPU = sys_info.dwNumberOfProcessors; unsigned long numCPU = sys_info.dwNumberOfProcessors;
// let the system handle 2x the number of CPUs or hardware // let the system handle 2x the number of CPUs or hardware
// threads // threads
tun_event_queue = CreateIoCompletionPort(tunif->tun_fd, nullptr, tun_event_queue = CreateIoCompletionPort(tunif->tun_fd, nullptr, (ULONG_PTR)this, numCPU * 2);
(ULONG_PTR)this, numCPU * 2);
begin_tun_loop(numCPU * 2, loop); begin_tun_loop(numCPU * 2, loop);
} }
else else
@ -143,8 +141,7 @@ tun_ev_loop(void* u)
while (true) while (true)
{ {
alert = GetQueuedCompletionStatus(tun_event_queue, &size, &listener, &ovl, alert = GetQueuedCompletionStatus(tun_event_queue, &size, &listener, &ovl, EV_TICK_INTERVAL);
EV_TICK_INTERVAL);
if (!alert) if (!alert)
{ {

@ -15,8 +15,7 @@
// io packet for TUN read/write // io packet for TUN read/write
struct asio_evt_pkt struct asio_evt_pkt
{ {
OVERLAPPED pkt = { OVERLAPPED pkt = {0, 0, 0, 0, nullptr}; // must be first, since this is part of the IO call
0, 0, 0, 0, nullptr}; // must be first, since this is part of the IO call
bool write = false; // true, or false if read pkt bool write = false; // true, or false if read pkt
size_t sz; // should match the queued data size, if not try again? size_t sz; // should match the queued data size, if not try again?
void* buf; // must remain valid until we get notification; this is _supposed_ void* buf; // must remain valid until we get notification; this is _supposed_

@ -19,8 +19,7 @@ llarp_ev_pkt_pipe::StartPipe()
return false; return false;
#else #else
int _fds[2]; int _fds[2];
if(pipe(_fds) == -1 if (pipe(_fds) == -1 && fcntl(_fds[0], F_SETFL, fcntl(_fds[0], F_GETFL) | O_NONBLOCK))
&& fcntl(_fds[0], F_SETFL, fcntl(_fds[0], F_GETFL) | O_NONBLOCK))
{ {
return false; return false;
} }

@ -84,8 +84,7 @@ namespace llarp
} }
bool bool
Context::ObtainNewExit(const PubKey& pk, const PathID_t& path, Context::ObtainNewExit(const PubKey& pk, const PathID_t& path, bool permitInternet)
bool permitInternet)
{ {
auto itr = m_Exits.begin(); auto itr = m_Exits.begin();
while (itr != m_Exits.end()) while (itr != m_Exits.end())

@ -35,25 +35,20 @@ namespace llarp
AddExitEndpoint(const std::string& name, const Config_t& config); AddExitEndpoint(const std::string& name, const Config_t& config);
bool bool
ObtainNewExit(const PubKey &remote, const PathID_t &path, ObtainNewExit(const PubKey& remote, const PathID_t& path, bool permitInternet);
bool permitInternet);
exit::Endpoint* exit::Endpoint*
FindEndpointForPath(const PathID_t& path) const; FindEndpointForPath(const PathID_t& path) const;
/// calculate (pk, tx, rx) for all exit traffic /// calculate (pk, tx, rx) for all exit traffic
using TrafficStats = using TrafficStats = std::unordered_map<PubKey, std::pair<uint64_t, uint64_t>, PubKey::Hash>;
std::unordered_map< PubKey, std::pair< uint64_t, uint64_t >,
PubKey::Hash >;
void void
CalculateExitTraffic(TrafficStats& stats); CalculateExitTraffic(TrafficStats& stats);
private: private:
AbstractRouter* m_Router; AbstractRouter* m_Router;
std::unordered_map< std::string, std::unordered_map<std::string, std::shared_ptr<handlers::ExitEndpoint>> m_Exits;
std::shared_ptr< handlers::ExitEndpoint > >
m_Exits;
std::list<std::shared_ptr<handlers::ExitEndpoint>> m_Closed; std::list<std::shared_ptr<handlers::ExitEndpoint>> m_Closed;
}; };
} // namespace exit } // namespace exit

@ -8,9 +8,12 @@ namespace llarp
{ {
namespace exit namespace exit
{ {
Endpoint::Endpoint(const llarp::PubKey& remoteIdent, Endpoint::Endpoint(
const llarp::PathID_t& beginPath, bool rewriteIP, const llarp::PubKey& remoteIdent,
huint128_t ip, llarp::handlers::ExitEndpoint* parent) const llarp::PathID_t& beginPath,
bool rewriteIP,
huint128_t ip,
llarp::handlers::ExitEndpoint* parent)
: createdAt(parent->Now()) : createdAt(parent->Now())
, m_Parent(parent) , m_Parent(parent)
, m_remoteSignKey(remoteIdent) , m_remoteSignKey(remoteIdent)
@ -129,8 +132,7 @@ namespace llarp
dst = net::IPPacket::TruncateV6(m_Parent->GetIfAddr()); dst = net::IPPacket::TruncateV6(m_Parent->GetIfAddr());
else else
dst = pkt.dstv4(); dst = pkt.dstv4();
pkt.UpdateIPv4Address(xhtonl(net::IPPacket::TruncateV6(m_IP)), pkt.UpdateIPv4Address(xhtonl(net::IPPacket::TruncateV6(m_IP)), xhtonl(dst));
xhtonl(dst));
} }
else else
{ {
@ -157,8 +159,8 @@ namespace llarp
if (pkt.IsV6()) if (pkt.IsV6())
pkt.UpdateIPv6Address(src, m_IP); pkt.UpdateIPv6Address(src, m_IP);
else else
pkt.UpdateIPv4Address(xhtonl(net::IPPacket::TruncateV6(src)), pkt.UpdateIPv4Address(
xhtonl(net::IPPacket::TruncateV6(m_IP))); xhtonl(net::IPPacket::TruncateV6(src)), xhtonl(net::IPPacket::TruncateV6(m_IP)));
const auto _pktbuf = pkt.Buffer(); const auto _pktbuf = pkt.Buffer();
const llarp_buffer_t& pktbuf = _pktbuf.underlying; const llarp_buffer_t& pktbuf = _pktbuf.underlying;
@ -220,8 +222,7 @@ namespace llarp
Endpoint::GetCurrentPath() const Endpoint::GetCurrentPath() const
{ {
auto router = m_Parent->GetRouter(); auto router = m_Parent->GetRouter();
return router->pathContext().GetByUpstream(router->pubkey(), return router->pathContext().GetByUpstream(router->pubkey(), m_CurrentPath);
m_CurrentPath);
} }
} // namespace exit } // namespace exit
} // namespace llarp } // namespace llarp

@ -23,8 +23,11 @@ namespace llarp
{ {
static constexpr size_t MaxUpstreamQueueSize = 256; static constexpr size_t MaxUpstreamQueueSize = 256;
Endpoint(const llarp::PubKey& remoteIdent, Endpoint(
const llarp::PathID_t& beginPath, bool rewriteIP, huint128_t ip, const llarp::PubKey& remoteIdent,
const llarp::PathID_t& beginPath,
bool rewriteIP,
huint128_t ip,
llarp::handlers::ExitEndpoint* parent); llarp::handlers::ExitEndpoint* parent);
~Endpoint(); ~Endpoint();
@ -113,16 +116,14 @@ namespace llarp
uint64_t m_TxRate, m_RxRate; uint64_t m_TxRate, m_RxRate;
llarp_time_t m_LastActive; llarp_time_t m_LastActive;
bool m_RewriteSource; bool m_RewriteSource;
using InboundTrafficQueue_t = using InboundTrafficQueue_t = std::deque<llarp::routing::TransferTrafficMessage>;
std::deque< llarp::routing::TransferTrafficMessage >;
using TieredQueue = std::map<uint8_t, InboundTrafficQueue_t>; using TieredQueue = std::map<uint8_t, InboundTrafficQueue_t>;
// maps number of fragments the message will fit in to the queue for it // maps number of fragments the message will fit in to the queue for it
TieredQueue m_DownstreamQueues; TieredQueue m_DownstreamQueues;
struct UpstreamBuffer struct UpstreamBuffer
{ {
UpstreamBuffer(const llarp::net::IPPacket& p, uint64_t c) UpstreamBuffer(const llarp::net::IPPacket& p, uint64_t c) : pkt(p), counter(c)
: pkt(p), counter(c)
{ {
} }

@ -93,8 +93,7 @@ namespace llarp
} }
bool bool
ObtainExitMessage::HandleMessage(IMessageHandler* h, ObtainExitMessage::HandleMessage(IMessageHandler* h, AbstractRouter* r) const
AbstractRouter* r) const
{ {
return h->HandleObtainExitMessage(*this, r); return h->HandleObtainExitMessage(*this, r);
} }
@ -242,8 +241,7 @@ namespace llarp
} }
bool bool
RejectExitMessage::HandleMessage(IMessageHandler* h, RejectExitMessage::HandleMessage(IMessageHandler* h, AbstractRouter* r) const
AbstractRouter* r) const
{ {
return h->HandleRejectExitMessage(*this, r); return h->HandleRejectExitMessage(*this, r);
} }
@ -313,8 +311,7 @@ namespace llarp
} }
bool bool
UpdateExitMessage::HandleMessage(IMessageHandler* h, UpdateExitMessage::HandleMessage(IMessageHandler* h, AbstractRouter* r) const
AbstractRouter* r) const
{ {
return h->HandleUpdateExitMessage(*this, r); return h->HandleUpdateExitMessage(*this, r);
} }
@ -336,8 +333,7 @@ namespace llarp
} }
bool bool
UpdateExitVerifyMessage::DecodeKey(const llarp_buffer_t& k, UpdateExitVerifyMessage::DecodeKey(const llarp_buffer_t& k, llarp_buffer_t* buf)
llarp_buffer_t* buf)
{ {
bool read = false; bool read = false;
if (!BEncodeMaybeReadDictInt("S", S, read, k, buf)) if (!BEncodeMaybeReadDictInt("S", S, read, k, buf))
@ -350,8 +346,7 @@ namespace llarp
} }
bool bool
UpdateExitVerifyMessage::HandleMessage(IMessageHandler* h, UpdateExitVerifyMessage::HandleMessage(IMessageHandler* h, AbstractRouter* r) const
AbstractRouter* r) const
{ {
return h->HandleUpdateExitVerifyMessage(*this, r); return h->HandleUpdateExitVerifyMessage(*this, r);
} }

@ -15,7 +15,10 @@ namespace llarp
BaseSession::BaseSession( BaseSession::BaseSession(
const llarp::RouterID& routerId, const llarp::RouterID& routerId,
std::function<bool(const llarp_buffer_t&)> writepkt, std::function<bool(const llarp_buffer_t&)> writepkt,
AbstractRouter* r, size_t numpaths, size_t hoplen, bool bundleRC) AbstractRouter* r,
size_t numpaths,
size_t hoplen,
bool bundleRC)
: llarp::path::Builder(r, numpaths, hoplen) : llarp::path::Builder(r, numpaths, hoplen)
, m_ExitRouter(routerId) , m_ExitRouter(routerId)
, m_WritePacket(std::move(writepkt)) , m_WritePacket(std::move(writepkt))
@ -68,8 +71,11 @@ namespace llarp
} }
bool bool
BaseSession::SelectHop(llarp_nodedb* db, const std::set< RouterID >& prev, BaseSession::SelectHop(
RouterContact& cur, size_t hop, llarp_nodedb* db,
const std::set<RouterID>& prev,
RouterContact& cur,
size_t hop,
llarp::path::PathRole roles) llarp::path::PathRole roles)
{ {
std::set<RouterID> exclude = prev; std::set<RouterID> exclude = prev;
@ -158,8 +164,7 @@ namespace llarp
BaseSession::ResetInternalState() BaseSession::ResetInternalState()
{ {
auto sendExitClose = [&](const llarp::path::Path_ptr p) { auto sendExitClose = [&](const llarp::path::Path_ptr p) {
const static auto roles = const static auto roles = llarp::path::ePathRoleExit | llarp::path::ePathRoleSVC;
llarp::path::ePathRoleExit | llarp::path::ePathRoleSVC;
if (p->SupportsAnyRoles(roles)) if (p->SupportsAnyRoles(roles))
{ {
llarp::LogInfo(p->Name(), " closing exit path"); llarp::LogInfo(p->Name(), " closing exit path");
@ -195,8 +200,7 @@ namespace llarp
} }
bool bool
BaseSession::HandleTraffic(llarp::path::Path_ptr, const llarp_buffer_t& buf, BaseSession::HandleTraffic(llarp::path::Path_ptr, const llarp_buffer_t& buf, uint64_t counter)
uint64_t counter)
{ {
if (m_WritePacket) if (m_WritePacket)
{ {
@ -211,11 +215,9 @@ namespace llarp
} }
bool bool
BaseSession::HandleTrafficDrop(llarp::path::Path_ptr p, BaseSession::HandleTrafficDrop(llarp::path::Path_ptr p, const PathID_t& path, uint64_t s)
const PathID_t& path, uint64_t s)
{ {
llarp::LogError("dropped traffic on exit ", m_ExitRouter, " S=", s, llarp::LogError("dropped traffic on exit ", m_ExitRouter, " S=", s, " P=", path);
" P=", path);
p->EnterState(path::ePathIgnore, m_router->Now()); p->EnterState(path::ePathIgnore, m_router->Now());
return true; return true;
} }
@ -308,8 +310,7 @@ namespace llarp
if (r->nodedb()->Get(m_ExitRouter, rc)) if (r->nodedb()->Get(m_ExitRouter, rc))
r->TryConnectAsync(rc, 5); r->TryConnectAsync(rc, 5);
else else
r->LookupRouter(m_ExitRouter, r->LookupRouter(m_ExitRouter, [r](const std::vector<RouterContact>& results) {
[r](const std::vector< RouterContact >& results) {
if (results.size()) if (results.size())
r->TryConnectAsync(results[0], 5); r->TryConnectAsync(results[0], 5);
}); });
@ -334,8 +335,11 @@ namespace llarp
SNodeSession::SNodeSession( SNodeSession::SNodeSession(
const llarp::RouterID& snodeRouter, const llarp::RouterID& snodeRouter,
std::function<bool(const llarp_buffer_t&)> writepkt, std::function<bool(const llarp_buffer_t&)> writepkt,
AbstractRouter* r, size_t numpaths, size_t hoplen, AbstractRouter* r,
bool useRouterSNodeKey, bool bundleRC) size_t numpaths,
size_t hoplen,
bool useRouterSNodeKey,
bool bundleRC)
: BaseSession(snodeRouter, writepkt, r, numpaths, hoplen, bundleRC) : BaseSession(snodeRouter, writepkt, r, numpaths, hoplen, bundleRC)
{ {
if (useRouterSNodeKey) if (useRouterSNodeKey)

@ -27,9 +27,12 @@ namespace llarp
{ {
static constexpr size_t MaxUpstreamQueueLength = 256; static constexpr size_t MaxUpstreamQueueLength = 256;
BaseSession(const llarp::RouterID& exitRouter, BaseSession(
const llarp::RouterID& exitRouter,
std::function<bool(const llarp_buffer_t&)> writepkt, std::function<bool(const llarp_buffer_t&)> writepkt,
AbstractRouter* r, size_t numpaths, size_t hoplen, AbstractRouter* r,
size_t numpaths,
size_t hoplen,
bool bundleRC); bool bundleRC);
~BaseSession() override; ~BaseSession() override;
@ -64,8 +67,11 @@ namespace llarp
CheckPathDead(path::Path_ptr p, llarp_time_t dlt); CheckPathDead(path::Path_ptr p, llarp_time_t dlt);
bool bool
SelectHop(llarp_nodedb* db, const std::set< RouterID >& prev, SelectHop(
RouterContact& cur, size_t hop, llarp_nodedb* db,
const std::set<RouterID>& prev,
RouterContact& cur,
size_t hop,
llarp::path::PathRole roles) override; llarp::path::PathRole roles) override;
bool bool
@ -122,21 +128,18 @@ namespace llarp
PopulateRequest(llarp::routing::ObtainExitMessage& msg) const = 0; PopulateRequest(llarp::routing::ObtainExitMessage& msg) const = 0;
bool bool
HandleTrafficDrop(llarp::path::Path_ptr p, const llarp::PathID_t& path, HandleTrafficDrop(llarp::path::Path_ptr p, const llarp::PathID_t& path, uint64_t s);
uint64_t s);
bool bool
HandleGotExit(llarp::path::Path_ptr p, llarp_time_t b); HandleGotExit(llarp::path::Path_ptr p, llarp_time_t b);
bool bool
HandleTraffic(llarp::path::Path_ptr p, const llarp_buffer_t& buf, HandleTraffic(llarp::path::Path_ptr p, const llarp_buffer_t& buf, uint64_t seqno);
uint64_t seqno);
private: private:
std::set<RouterID> m_SnodeBlacklist; std::set<RouterID> m_SnodeBlacklist;
using UpstreamTrafficQueue_t = using UpstreamTrafficQueue_t = std::deque<llarp::routing::TransferTrafficMessage>;
std::deque< llarp::routing::TransferTrafficMessage >;
using TieredQueue_t = std::map<uint8_t, UpstreamTrafficQueue_t>; using TieredQueue_t = std::map<uint8_t, UpstreamTrafficQueue_t>;
TieredQueue_t m_Upstream; TieredQueue_t m_Upstream;
@ -152,8 +155,7 @@ namespace llarp
}; };
using DownstreamTrafficQueue_t = using DownstreamTrafficQueue_t =
std::priority_queue< DownstreamPkt, std::vector< DownstreamPkt >, std::priority_queue<DownstreamPkt, std::vector<DownstreamPkt>, DownstreamPktSorter>;
DownstreamPktSorter >;
DownstreamTrafficQueue_t m_Downstream; DownstreamTrafficQueue_t m_Downstream;
uint64_t m_Counter; uint64_t m_Counter;
@ -168,9 +170,12 @@ namespace llarp
struct ExitSession final : public BaseSession struct ExitSession final : public BaseSession
{ {
ExitSession(const llarp::RouterID& snodeRouter, ExitSession(
const llarp::RouterID& snodeRouter,
std::function<bool(const llarp_buffer_t&)> writepkt, std::function<bool(const llarp_buffer_t&)> writepkt,
AbstractRouter* r, size_t numpaths, size_t hoplen, AbstractRouter* r,
size_t numpaths,
size_t hoplen,
bool bundleRC) bool bundleRC)
: BaseSession(snodeRouter, writepkt, r, numpaths, hoplen, bundleRC) : BaseSession(snodeRouter, writepkt, r, numpaths, hoplen, bundleRC)
{ {
@ -193,10 +198,14 @@ namespace llarp
struct SNodeSession final : public BaseSession struct SNodeSession final : public BaseSession
{ {
SNodeSession(const llarp::RouterID& snodeRouter, SNodeSession(
const llarp::RouterID& snodeRouter,
std::function<bool(const llarp_buffer_t&)> writepkt, std::function<bool(const llarp_buffer_t&)> writepkt,
AbstractRouter* r, size_t numpaths, size_t hoplen, AbstractRouter* r,
bool useRouterSNodeKey, bool bundleRC); size_t numpaths,
size_t hoplen,
bool useRouterSNodeKey,
bool bundleRC);
~SNodeSession() override = default; ~SNodeSession() override = default;

@ -37,8 +37,18 @@ namespace llarp
, m_Resolver(std::make_shared<dns::Proxy>( , m_Resolver(std::make_shared<dns::Proxy>(
r->netloop(), r->logic(), r->netloop(), r->logic(), this)) r->netloop(), r->logic(), r->netloop(), r->logic(), this))
, m_Name(name) , m_Name(name)
, m_Tun{{0}, 0, 0, {0}, nullptr, nullptr, , m_Tun{{0},
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr} 0,
0,
{0},
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr}
, m_LocalResolverAddr("127.0.0.1", 53) , m_LocalResolverAddr("127.0.0.1", 53)
, m_InetToNetwork(name + "_exit_rx", r->netloop(), r->netloop()) , m_InetToNetwork(name + "_exit_rx", r->netloop(), r->netloop())
@ -54,8 +64,7 @@ namespace llarp
util::StatusObject util::StatusObject
ExitEndpoint::ExtractStatus() const ExitEndpoint::ExtractStatus() const
{ {
util::StatusObject obj{{"permitExit", m_PermitExit}, util::StatusObject obj{{"permitExit", m_PermitExit}, {"ip", m_IfAddr.ToString()}};
{"ip", m_IfAddr.ToString()}};
util::StatusObject exitsObj{}; util::StatusObject exitsObj{};
for (const auto& item : m_ActiveExits) for (const auto& item : m_ActiveExits)
{ {
@ -84,8 +93,7 @@ namespace llarp
return false; return false;
return m_OurRange.Contains(ip); return m_OurRange.Contains(ip);
} }
if(msg.questions[0].qtype == dns::qTypeA if (msg.questions[0].qtype == dns::qTypeA || msg.questions[0].qtype == dns::qTypeCNAME
|| msg.questions[0].qtype == dns::qTypeCNAME
|| msg.questions[0].qtype == dns::qTypeAAAA) || msg.questions[0].qtype == dns::qTypeAAAA)
{ {
if (msg.questions[0].IsName("localhost.loki")) if (msg.questions[0].IsName("localhost.loki"))
@ -97,8 +105,7 @@ namespace llarp
} }
bool bool
ExitEndpoint::HandleHookedDNSMessage( ExitEndpoint::HandleHookedDNSMessage(dns::Message msg, std::function<void(dns::Message)> reply)
dns::Message msg, std::function< void(dns::Message) > reply)
{ {
if (msg.questions[0].qtype == dns::qTypePTR) if (msg.questions[0].qtype == dns::qTypePTR)
{ {
@ -113,8 +120,7 @@ namespace llarp
else else
{ {
auto itr = m_IPToKey.find(ip); auto itr = m_IPToKey.find(ip);
if(itr != m_IPToKey.end() if (itr != m_IPToKey.end() && m_SNodeKeys.find(itr->second) != m_SNodeKeys.end())
&& m_SNodeKeys.find(itr->second) != m_SNodeKeys.end())
{ {
RouterID them = itr->second; RouterID them = itr->second;
msg.AddAReply(them.ToString()); msg.AddAReply(them.ToString());
@ -141,8 +147,7 @@ namespace llarp
else else
msg.AddNXReply(); msg.AddNXReply();
} }
else if(msg.questions[0].qtype == dns::qTypeA else if (msg.questions[0].qtype == dns::qTypeA || msg.questions[0].qtype == dns::qTypeAAAA)
|| msg.questions[0].qtype == dns::qTypeAAAA)
{ {
const bool isV6 = msg.questions[0].qtype == dns::qTypeAAAA; const bool isV6 = msg.questions[0].qtype == dns::qTypeAAAA;
const bool isV4 = msg.questions[0].qtype == dns::qTypeA; const bool isV4 = msg.questions[0].qtype == dns::qTypeA;
@ -179,8 +184,7 @@ namespace llarp
else if (m_SNodeKeys.find(pubKey) == m_SNodeKeys.end()) else if (m_SNodeKeys.find(pubKey) == m_SNodeKeys.end())
{ {
// we do not have it mapped, async obtain it // we do not have it mapped, async obtain it
ObtainSNodeSession( ObtainSNodeSession(r, [&](std::shared_ptr<exit::BaseSession> session) {
r, [&](std::shared_ptr< exit::BaseSession > session) {
if (session && session->IsReady()) if (session && session->IsReady())
{ {
msg.AddINReply(m_KeyToIP[pubKey], isV6); msg.AddINReply(m_KeyToIP[pubKey], isV6);
@ -214,8 +218,7 @@ namespace llarp
} }
void void
ExitEndpoint::ObtainSNodeSession(const RouterID &router, ExitEndpoint::ObtainSNodeSession(const RouterID& router, exit::SessionReadyFunc obtainCb)
exit::SessionReadyFunc obtainCb)
{ {
ObtainServiceNodeIP(router); ObtainServiceNodeIP(router);
m_SNodeSessions[router]->AddReadyHook(obtainCb); m_SNodeSessions[router]->AddReadyHook(obtainCb);
@ -253,8 +256,7 @@ namespace llarp
if (itr == m_IPToKey.end()) if (itr == m_IPToKey.end())
{ {
// drop // drop
LogWarn(Name(), " dropping packet, has no session at ", LogWarn(Name(), " dropping packet, has no session at ", pkt.dstv6());
pkt.dstv6());
return; return;
} }
pk = itr->second; pk = itr->second;
@ -275,7 +277,10 @@ namespace llarp
auto tryFlushingTraffic = [&](exit::Endpoint* const ep) -> bool { auto tryFlushingTraffic = [&](exit::Endpoint* const ep) -> bool {
if (!ep->QueueInboundTraffic(ManagedBuffer{pkt.Buffer()})) if (!ep->QueueInboundTraffic(ManagedBuffer{pkt.Buffer()}))
{ {
LogWarn(Name(), " dropped inbound traffic for session ", pk, LogWarn(
Name(),
" dropped inbound traffic for session ",
pk,
" as we are overloaded (probably)"); " as we are overloaded (probably)");
// continue iteration // continue iteration
return true; return true;
@ -286,7 +291,10 @@ namespace llarp
if (!VisitEndpointsFor(pk, tryFlushingTraffic)) if (!VisitEndpointsFor(pk, tryFlushingTraffic))
{ {
// we may have all dead sessions, wtf now? // we may have all dead sessions, wtf now?
LogWarn(Name(), " dropped inbound traffic for session ", pk, LogWarn(
Name(),
" dropped inbound traffic for session ",
pk,
" as we have no working endpoints"); " as we have no working endpoints");
} }
}); });
@ -308,8 +316,7 @@ namespace llarp
// TODO: move flush upstream to router event loop // TODO: move flush upstream to router event loop
if (!itr->second->FlushUpstream()) if (!itr->second->FlushUpstream())
{ {
LogWarn("failed to flush snode traffic to ", itr->first, LogWarn("failed to flush snode traffic to ", itr->first, " via outbound session");
" via outbound session");
} }
itr->second->FlushDownstream(); itr->second->FlushDownstream();
++itr; ++itr;
@ -336,8 +343,7 @@ namespace llarp
llarp::LogWarn("Could not create tunnel for exit endpoint"); llarp::LogWarn("Could not create tunnel for exit endpoint");
return false; return false;
} }
llarp::LogInfo("Trying to start resolver ", llarp::LogInfo("Trying to start resolver ", m_LocalResolverAddr.ToString());
m_LocalResolverAddr.ToString());
return m_Resolver->Start(m_LocalResolverAddr, m_UpstreamResolvers); return m_Resolver->Start(m_LocalResolverAddr, m_UpstreamResolvers);
} }
return true; return true;
@ -467,9 +473,7 @@ namespace llarp
{ {
const llarp_buffer_t buffer(buf); const llarp_buffer_t buffer(buf);
m_InetToNetwork.EmplaceIf( m_InetToNetwork.EmplaceIf(
[b = ManagedBuffer(buffer)](Pkt_t &pkt) -> bool { [b = ManagedBuffer(buffer)](Pkt_t& pkt) -> bool { return pkt.Load(b); });
return pkt.Load(b);
});
} }
bool bool
@ -482,8 +486,8 @@ namespace llarp
if (m_UseV6) if (m_UseV6)
pkt.UpdateIPv6Address(from, m_IfAddr); pkt.UpdateIPv6Address(from, m_IfAddr);
else else
pkt.UpdateIPv4Address(xhtonl(net::IPPacket::TruncateV6(from)), pkt.UpdateIPv4Address(
xhtonl(net::IPPacket::TruncateV6(m_IfAddr))); xhtonl(net::IPPacket::TruncateV6(from)), xhtonl(net::IPPacket::TruncateV6(m_IfAddr)));
return llarp_ev_tun_async_write(&m_Tun, pkt.Buffer()); return llarp_ev_tun_async_write(&m_Tun, pkt.Buffer());
} }
@ -557,8 +561,7 @@ namespace llarp
dnsport = std::atoi(v.substr(pos + 1).c_str()); dnsport = std::atoi(v.substr(pos + 1).c_str());
} }
m_UpstreamResolvers.emplace_back(resolverAddr, dnsport); m_UpstreamResolvers.emplace_back(resolverAddr, dnsport);
LogInfo(Name(), " adding upstream dns set to ", resolverAddr, ":", LogInfo(Name(), " adding upstream dns set to ", resolverAddr, ":", dnsport);
dnsport);
} }
if (k == "ifaddr") if (k == "ifaddr")
{ {
@ -581,8 +584,16 @@ namespace llarp
m_IfAddr = m_OurRange.addr; m_IfAddr = m_OurRange.addr;
m_NextAddr = m_IfAddr; m_NextAddr = m_IfAddr;
m_HigestAddr = m_OurRange.HighestAddr(); m_HigestAddr = m_OurRange.HighestAddr();
LogInfo(Name(), " set ifaddr range to ", m_Tun.ifaddr, "/", LogInfo(
m_Tun.netmask, " lo=", m_IfAddr, " hi=", m_HigestAddr); Name(),
" set ifaddr range to ",
m_Tun.ifaddr,
"/",
m_Tun.netmask,
" lo=",
m_IfAddr,
" hi=",
m_HigestAddr);
m_UseV6 = false; m_UseV6 = false;
} }
if (k == "ifname") if (k == "ifname")
@ -625,9 +636,12 @@ namespace llarp
{ {
auto session = std::make_shared<exit::SNodeSession>( auto session = std::make_shared<exit::SNodeSession>(
other, other,
std::bind(&ExitEndpoint::QueueSNodePacket, this, std::bind(&ExitEndpoint::QueueSNodePacket, this, std::placeholders::_1, ip),
std::placeholders::_1, ip), GetRouter(),
GetRouter(), 2, 1, true, false); 2,
1,
true,
false);
// this is a new service node make an outbound session to them // this is a new service node make an outbound session to them
m_SNodeSessions.emplace(other, session); m_SNodeSessions.emplace(other, session);
} }
@ -635,22 +649,19 @@ namespace llarp
} }
bool bool
ExitEndpoint::AllocateNewExit(const PubKey pk, const PathID_t &path, ExitEndpoint::AllocateNewExit(const PubKey pk, const PathID_t& path, bool wantInternet)
bool wantInternet)
{ {
if (wantInternet && !m_PermitExit) if (wantInternet && !m_PermitExit)
return false; return false;
auto ip = GetIPForIdent(pk); auto ip = GetIPForIdent(pk);
if(GetRouter()->pathContext().TransitHopPreviousIsRouter(path, if (GetRouter()->pathContext().TransitHopPreviousIsRouter(path, pk.as_array()))
pk.as_array()))
{ {
// we think this path belongs to a service node // we think this path belongs to a service node
// mark it as such so we don't make an outbound session to them // mark it as such so we don't make an outbound session to them
m_SNodeKeys.emplace(pk.as_array()); m_SNodeKeys.emplace(pk.as_array());
} }
m_ActiveExits.emplace(pk, m_ActiveExits.emplace(
std::make_unique< exit::Endpoint >( pk, std::make_unique<exit::Endpoint>(pk, path, !wantInternet, ip, this));
pk, path, !wantInternet, ip, this));
m_Paths[path] = pk; m_Paths[path] = pk;
@ -729,9 +740,8 @@ namespace llarp
m_ChosenExits[itr->first] = itr->second.get(); m_ChosenExits[itr->first] = itr->second.get();
} }
} }
else if(!itr->second->LooksDead( else if (!itr->second->LooksDead(now)) // set chosen exit if not dead for key that
now)) // set chosen exit if not dead for key that doesn't // doesn't have one yet
// have one yet
m_ChosenExits[itr->first] = itr->second.get(); m_ChosenExits[itr->first] = itr->second.get();
// tick which clears the tx rx counters // tick which clears the tx rx counters
itr->second->Tick(now); itr->second->Tick(now);

@ -26,8 +26,7 @@ namespace llarp
Name() const; Name() const;
bool bool
VisitEndpointsFor(const PubKey& pk, VisitEndpointsFor(const PubKey& pk, std::function<bool(exit::Endpoint* const)> visit);
std::function< bool(exit::Endpoint* const) > visit);
util::StatusObject util::StatusObject
ExtractStatus() const; ExtractStatus() const;
@ -39,12 +38,10 @@ namespace llarp
ShouldHookDNSMessage(const dns::Message& msg) const override; ShouldHookDNSMessage(const dns::Message& msg) const override;
bool bool
HandleHookedDNSMessage(dns::Message msg, HandleHookedDNSMessage(dns::Message msg, std::function<void(dns::Message)>) override;
std::function< void(dns::Message) >) override;
bool bool
AllocateNewExit(const PubKey pk, const PathID_t& path, AllocateNewExit(const PubKey pk, const PathID_t& path, bool permitInternet);
bool permitInternet);
exit::Endpoint* exit::Endpoint*
FindEndpointByPath(const PathID_t& path); FindEndpointByPath(const PathID_t& path);
@ -122,8 +119,7 @@ namespace llarp
/// async obtain snode session and call callback when it's ready to send /// async obtain snode session and call callback when it's ready to send
void void
ObtainSNodeSession(const RouterID& router, ObtainSNodeSession(const RouterID& router, exit::SessionReadyFunc obtainCb);
exit::SessionReadyFunc obtainCb);
bool bool
QueueSNodePacket(const llarp_buffer_t& buf, huint128_t from); QueueSNodePacket(const llarp_buffer_t& buf, huint128_t from);
@ -143,9 +139,7 @@ namespace llarp
std::unordered_map<PubKey, exit::Endpoint*, PubKey::Hash> m_ChosenExits; std::unordered_map<PubKey, exit::Endpoint*, PubKey::Hash> m_ChosenExits;
std::unordered_multimap< PubKey, std::unique_ptr< exit::Endpoint >, std::unordered_multimap<PubKey, std::unique_ptr<exit::Endpoint>, PubKey::Hash> m_ActiveExits;
PubKey::Hash >
m_ActiveExits;
using KeyMap_t = std::unordered_map<PubKey, huint128_t, PubKey::Hash>; using KeyMap_t = std::unordered_map<PubKey, huint128_t, PubKey::Hash>;
@ -156,8 +150,7 @@ namespace llarp
SNodes_t m_SNodeKeys; SNodes_t m_SNodeKeys;
using SNodeSessions_t = using SNodeSessions_t =
std::unordered_map< RouterID, std::shared_ptr< exit::SNodeSession >, std::unordered_map<RouterID, std::shared_ptr<exit::SNodeSession>, RouterID::Hash>;
RouterID::Hash >;
/// snode sessions we are talking to directly /// snode sessions we are talking to directly
SNodeSessions_t m_SNodeSessions; SNodeSessions_t m_SNodeSessions;
@ -177,9 +170,13 @@ namespace llarp
std::vector<Addr> m_UpstreamResolvers; std::vector<Addr> m_UpstreamResolvers;
using Pkt_t = net::IPPacket; using Pkt_t = net::IPPacket;
using PacketQueue_t = using PacketQueue_t = util::CoDelQueue<
util::CoDelQueue< Pkt_t, Pkt_t::GetTime, Pkt_t::PutTime, Pkt_t,
Pkt_t::CompareOrder, Pkt_t::GetNow, util::NullMutex, Pkt_t::GetTime,
Pkt_t::PutTime,
Pkt_t::CompareOrder,
Pkt_t::GetNow,
util::NullMutex,
util::NullLock>; util::NullLock>;
/// internet to llarp packet queue /// internet to llarp packet queue

@ -7,19 +7,17 @@ namespace llarp
{ {
namespace handlers namespace handlers
{ {
struct NullEndpoint final struct NullEndpoint final : public llarp::service::Endpoint,
: public llarp::service::Endpoint,
public std::enable_shared_from_this<NullEndpoint> public std::enable_shared_from_this<NullEndpoint>
{ {
NullEndpoint(const std::string &name, AbstractRouter *r, NullEndpoint(const std::string& name, AbstractRouter* r, llarp::service::Context* parent)
llarp::service::Context *parent)
: llarp::service::Endpoint(name, r, parent) : llarp::service::Endpoint(name, r, parent)
{ {
} }
virtual bool virtual bool
HandleInboundPacket(const service::ConvoTag, const llarp_buffer_t &, HandleInboundPacket(
service::ProtocolType) override const service::ConvoTag, const llarp_buffer_t&, service::ProtocolType) override
{ {
return true; return true;
} }

@ -49,13 +49,11 @@ namespace llarp
} }
} }
TunEndpoint::TunEndpoint(const std::string &nickname, AbstractRouter *r, TunEndpoint::TunEndpoint(
service::Context *parent, bool lazyVPN) const std::string& nickname, AbstractRouter* r, service::Context* parent, bool lazyVPN)
: service::Endpoint(nickname, r, parent) : service::Endpoint(nickname, r, parent)
, m_UserToNetworkPktQueue(nickname + "_sendq", r->netloop(), , m_UserToNetworkPktQueue(nickname + "_sendq", r->netloop(), r->netloop())
r->netloop()) , m_NetworkToUserPktQueue(nickname + "_recvq", r->netloop(), r->netloop())
, m_NetworkToUserPktQueue(nickname + "_recvq", r->netloop(),
r->netloop())
, m_Resolver(std::make_shared<dns::Proxy>( , m_Resolver(std::make_shared<dns::Proxy>(
r->netloop(), r->logic(), r->netloop(), r->logic(), this)) r->netloop(), r->logic(), r->netloop(), r->logic(), this))
{ {
@ -123,8 +121,7 @@ namespace llarp
} }
else else
{ {
LogError(Name(), " config option reachable = '", v, LogError(Name(), " config option reachable = '", v, "' does not make sense");
"' does not make sense");
return false; return false;
} }
} }
@ -140,8 +137,7 @@ namespace llarp
LogInfo(Name(), " booyeah network isolation succeeded"); LogInfo(Name(), " booyeah network isolation succeeded");
return true; return true;
#else #else
LogError(Name(), LogError(Name(), " network isolation is not supported on your platform");
" network isolation is not supported on your platform");
return false; return false;
#endif #endif
} }
@ -157,15 +153,14 @@ namespace llarp
RouterContact rc; RouterContact rc;
if (!m_router->nodedb()->Get(connect, rc)) if (!m_router->nodedb()->Get(connect, rc))
{ {
LogError(Name(), " we don't have the RC for ", v, LogError(
" so we can't use it in strict-connect"); Name(), " we don't have the RC for ", v, " so we can't use it in strict-connect");
return false; return false;
} }
for (const auto& ai : rc.addrs) for (const auto& ai : rc.addrs)
{ {
m_StrictConnectAddrs.emplace_back(ai); m_StrictConnectAddrs.emplace_back(ai);
LogInfo(Name(), " added ", m_StrictConnectAddrs.back(), LogInfo(Name(), " added ", m_StrictConnectAddrs.back(), " to strict connect");
" to strict connect");
} }
return true; return true;
} }
@ -193,8 +188,7 @@ namespace llarp
} }
routerStr = str(TrimWhitespace(routerStr)); routerStr = str(TrimWhitespace(routerStr));
if (!(exitRouter.FromString(routerStr) if (!(exitRouter.FromString(routerStr)
|| HexDecode(routerStr.c_str(), exitRouter.begin(), || HexDecode(routerStr.c_str(), exitRouter.begin(), exitRouter.size())))
exitRouter.size())))
{ {
llarp::LogError(Name(), " bad exit router key: ", routerStr); llarp::LogError(Name(), " bad exit router key: ", routerStr);
return false; return false;
@ -202,10 +196,12 @@ namespace llarp
auto exit = std::make_shared<llarp::exit::ExitSession>( auto exit = std::make_shared<llarp::exit::ExitSession>(
exitRouter, exitRouter,
util::memFn(&TunEndpoint::QueueInboundPacketForExit, this), util::memFn(&TunEndpoint::QueueInboundPacketForExit, this),
m_router, numPaths, numHops, ShouldBundleRC()); m_router,
numPaths,
numHops,
ShouldBundleRC());
m_ExitMap.Insert(exitRange, exit); m_ExitMap.Insert(exitRange, exit);
llarp::LogInfo(Name(), " using exit at ", exitRouter, " for ", llarp::LogInfo(Name(), " using exit at ", exitRouter, " for ", exitRange);
exitRange);
} }
if (k == "local-dns") if (k == "local-dns")
{ {
@ -233,15 +229,16 @@ namespace llarp
dnsport = std::atoi(v.substr(pos + 1).c_str()); dnsport = std::atoi(v.substr(pos + 1).c_str());
} }
m_UpstreamResolvers.emplace_back(resolverAddr, dnsport); m_UpstreamResolvers.emplace_back(resolverAddr, dnsport);
llarp::LogInfo(Name(), " adding upstream DNS server ", resolverAddr, llarp::LogInfo(Name(), " adding upstream DNS server ", resolverAddr, ":", dnsport);
":", dnsport);
} }
if (k == "mapaddr") if (k == "mapaddr")
{ {
auto pos = v.find(":"); auto pos = v.find(":");
if (pos == std::string::npos) if (pos == std::string::npos)
{ {
llarp::LogError("Cannot map address ", v, llarp::LogError(
"Cannot map address ",
v,
" invalid format, missing colon (:), expects " " invalid format, missing colon (:), expects "
"address.loki:ip.address.goes.here"); "address.loki:ip.address.goes.here");
return false; return false;
@ -265,8 +262,7 @@ namespace llarp
} }
else else
{ {
llarp::LogError(Name(), "failed to map ", ip_str, llarp::LogError(Name(), "failed to map ", ip_str, " failed to parse IP");
" failed to parse IP");
return false; return false;
} }
return MapAddress(addr, ipv6, false); return MapAddress(addr, ipv6, false);
@ -315,8 +311,7 @@ namespace llarp
tunif->netmask = 32; tunif->netmask = 32;
addr = v; addr = v;
} }
llarp::LogInfo(Name() + " set ifaddr to ", addr, " with netmask ", llarp::LogInfo(Name() + " set ifaddr to ", addr, " with netmask ", tunif->netmask);
tunif->netmask);
strncpy(tunif->ifaddr, addr.c_str(), sizeof(tunif->ifaddr) - 1); strncpy(tunif->ifaddr, addr.c_str(), sizeof(tunif->ifaddr) - 1);
return true; return true;
} }
@ -341,8 +336,7 @@ namespace llarp
{ {
static const auto func = [](auto self) { static const auto func = [](auto self) {
self->FlushSend(); self->FlushSend();
self->m_ExitMap.ForEachValue( self->m_ExitMap.ForEachValue([](const auto& exit) { exit->FlushUpstream(); });
[](const auto &exit) { exit->FlushUpstream(); });
self->Pump(self->Now()); self->Pump(self->Now());
}; };
if (NetworkIsIsolated()) if (NetworkIsIsolated())
@ -404,20 +398,16 @@ namespace llarp
} }
bool bool
TunEndpoint::HandleHookedDNSMessage( TunEndpoint::HandleHookedDNSMessage(dns::Message msg, std::function<void(dns::Message)> reply)
dns::Message msg, std::function< void(dns::Message) > reply)
{ {
auto ReplyToSNodeDNSWhenReady = [self = this, reply = reply]( auto ReplyToSNodeDNSWhenReady = [self = this, reply = reply](
RouterID snode, auto msg, RouterID snode, auto msg, bool isV6) -> bool {
bool isV6) -> bool { return self->EnsurePathToSNode(snode, [=](const RouterID&, exit::BaseSession_ptr s) {
return self->EnsurePathToSNode(
snode, [=](const RouterID &, exit::BaseSession_ptr s) {
self->SendDNSReply(snode, s, msg, reply, true, isV6); self->SendDNSReply(snode, s, msg, reply, true, isV6);
}); });
}; };
auto ReplyToLokiDNSWhenReady = [self = this, reply = reply]( auto ReplyToLokiDNSWhenReady = [self = this, reply = reply](
service::Address addr, auto msg, service::Address addr, auto msg, bool isV6) -> bool {
bool isV6) -> bool {
using service::Address; using service::Address;
using service::OutboundContext; using service::OutboundContext;
if (self->HasAddress(addr)) if (self->HasAddress(addr))
@ -447,8 +437,7 @@ namespace llarp
RouterID addr; RouterID addr;
if (not addr.FromString(qname)) if (not addr.FromString(qname))
return false; return false;
auto replyMsg = auto replyMsg = std::make_shared<dns::Message>(clear_dns_message(msg));
std::make_shared< dns::Message >(clear_dns_message(msg));
return ReplyToSNodeDNSWhenReady(addr, std::move(replyMsg), false); return ReplyToSNodeDNSWhenReady(addr, std::move(replyMsg), false);
} }
else if (answer.HasCNameForTLD(".loki")) else if (answer.HasCNameForTLD(".loki"))
@ -460,8 +449,7 @@ namespace llarp
service::Address addr; service::Address addr;
if (not addr.FromString(qname)) if (not addr.FromString(qname))
return false; return false;
auto replyMsg = auto replyMsg = std::make_shared<dns::Message>(clear_dns_message(msg));
std::make_shared< dns::Message >(clear_dns_message(msg));
return ReplyToLokiDNSWhenReady(addr, replyMsg, false); return ReplyToLokiDNSWhenReady(addr, replyMsg, false);
} }
} }
@ -499,8 +487,7 @@ namespace llarp
{ {
size_t counter = 0; size_t counter = 0;
context->ForEachService( context->ForEachService(
[&](const std::string &, [&](const std::string&, const std::shared_ptr<service::Endpoint>& service) -> bool {
const std::shared_ptr< service::Endpoint > &service) -> bool {
const service::Address addr = service->GetIdentity().pub.Addr(); const service::Address addr = service->GetIdentity().pub.Addr();
msg.AddCNAMEReply(addr.ToString(), 1); msg.AddCNAMEReply(addr.ToString(), 1);
++counter; ++counter;
@ -513,8 +500,7 @@ namespace llarp
msg.AddNXReply(); msg.AddNXReply();
reply(msg); reply(msg);
} }
else if(msg.questions[0].qtype == dns::qTypeA else if (msg.questions[0].qtype == dns::qTypeA || msg.questions[0].qtype == dns::qTypeAAAA)
|| msg.questions[0].qtype == dns::qTypeAAAA)
{ {
const bool isV6 = msg.questions[0].qtype == dns::qTypeAAAA; const bool isV6 = msg.questions[0].qtype == dns::qTypeAAAA;
const bool isV4 = msg.questions[0].qtype == dns::qTypeA; const bool isV4 = msg.questions[0].qtype == dns::qTypeA;
@ -530,8 +516,7 @@ namespace llarp
if (Router()->GetRandomGoodRouter(random)) if (Router()->GetRandomGoodRouter(random))
{ {
msg.AddCNAMEReply(random.ToString(), 1); msg.AddCNAMEReply(random.ToString(), 1);
return ReplyToSNodeDNSWhenReady( return ReplyToSNodeDNSWhenReady(random, std::make_shared<dns::Message>(msg), isV6);
random, std::make_shared< dns::Message >(msg), isV6);
} }
else else
msg.AddNXReply(); msg.AddNXReply();
@ -540,8 +525,7 @@ namespace llarp
{ {
size_t counter = 0; size_t counter = 0;
context->ForEachService( context->ForEachService(
[&](const std::string &, [&](const std::string&, const std::shared_ptr<service::Endpoint>& service) -> bool {
const std::shared_ptr< service::Endpoint > &service) -> bool {
if (!service->HasIfAddr()) if (!service->HasIfAddr())
return true; return true;
huint128_t ip = service->GetIfAddr(); huint128_t ip = service->GetIfAddr();
@ -563,8 +547,7 @@ namespace llarp
} }
else else
{ {
return ReplyToLokiDNSWhenReady( return ReplyToLokiDNSWhenReady(addr, std::make_shared<dns::Message>(msg), isV6);
addr, std::make_shared< dns::Message >(msg), isV6);
} }
} }
else if (addr.FromString(qname, ".snode")) else if (addr.FromString(qname, ".snode"))
@ -624,8 +607,7 @@ namespace llarp
TunEndpoint::ResetInternalState() TunEndpoint::ResetInternalState()
{ {
service::Endpoint::ResetInternalState(); service::Endpoint::ResetInternalState();
m_ExitMap.ForEachValue( m_ExitMap.ForEachValue([](const auto& exit) { exit->ResetInternalState(); });
[](const auto &exit) { exit->ResetInternalState(); });
} }
bool bool
@ -667,14 +649,13 @@ namespace llarp
} }
bool bool
TunEndpoint::MapAddress(const service::Address &addr, huint128_t ip, TunEndpoint::MapAddress(const service::Address& addr, huint128_t ip, bool SNode)
bool SNode)
{ {
auto itr = m_IPToAddr.find(ip); auto itr = m_IPToAddr.find(ip);
if (itr != m_IPToAddr.end()) if (itr != m_IPToAddr.end())
{ {
llarp::LogWarn(ip, " already mapped to ", llarp::LogWarn(
service::Address(itr->second.as_array()).ToString()); ip, " already mapped to ", service::Address(itr->second.as_array()).ToString());
return false; return false;
} }
llarp::LogInfo(Name() + " map ", addr.ToString(), " to ", ip); llarp::LogInfo(Name() + " map ", addr.ToString(), " to ", ip);
@ -783,9 +764,8 @@ namespace llarp
{ {
if (!llarp_ev_add_tun(loop.get(), tunif.get())) if (!llarp_ev_add_tun(loop.get(), tunif.get()))
{ {
llarp::LogError(Name(), llarp::LogError(
" failed to set up tun interface: ", tunif->ifaddr, Name(), " failed to set up tun interface: ", tunif->ifaddr, " on ", tunif->ifname);
" on ", tunif->ifname);
return false; return false;
} }
} }
@ -826,8 +806,7 @@ namespace llarp
m_OurRange.addr = m_OurIP; m_OurRange.addr = m_OurIP;
m_MaxIP = m_OurRange.HighestAddr(); m_MaxIP = m_OurRange.HighestAddr();
llarp::LogInfo(Name(), " set ", ifname, " to have address ", m_OurIP); llarp::LogInfo(Name(), " set ", ifname, " to have address ", m_OurIP);
llarp::LogInfo(Name(), " allocated up to ", m_MaxIP, " on range ", llarp::LogInfo(Name(), " allocated up to ", m_MaxIP, " on range ", m_OurRange);
m_OurRange);
const service::Address ourAddr = m_Identity.pub.Addr(); const service::Address ourAddr = m_Identity.pub.Addr();
@ -919,28 +898,32 @@ namespace llarp
if (pkt.IsV4() && !llarp::IsIPv4Bogon(pkt.dstv4())) if (pkt.IsV4() && !llarp::IsIPv4Bogon(pkt.dstv4()))
{ {
pkt.UpdateIPv4Address({0}, xhtonl(pkt.dstv4())); pkt.UpdateIPv4Address({0}, xhtonl(pkt.dstv4()));
exit->QueueUpstreamTraffic(std::move(pkt), exit->QueueUpstreamTraffic(std::move(pkt), llarp::routing::ExitPadSize);
llarp::routing::ExitPadSize);
} }
else if (pkt.IsV6()) else if (pkt.IsV6())
{ {
pkt.UpdateIPv6Address({0}, pkt.dstv6()); pkt.UpdateIPv6Address({0}, pkt.dstv6());
exit->QueueUpstreamTraffic(std::move(pkt), exit->QueueUpstreamTraffic(std::move(pkt), llarp::routing::ExitPadSize);
llarp::routing::ExitPadSize);
} }
} }
return; return;
} }
if (m_SNodes.at(itr->second)) if (m_SNodes.at(itr->second))
{ {
sendFunc = std::bind(&TunEndpoint::SendToSNodeOrQueue, this, sendFunc = std::bind(
itr->second.as_array(), std::placeholders::_1); &TunEndpoint::SendToSNodeOrQueue,
this,
itr->second.as_array(),
std::placeholders::_1);
} }
else else
{ {
sendFunc = std::bind(&TunEndpoint::SendToServiceOrQueue, this, sendFunc = std::bind(
&TunEndpoint::SendToServiceOrQueue,
this,
service::Address(itr->second.as_array()), service::Address(itr->second.as_array()),
std::placeholders::_1, pkt.ServiceProtocol()); std::placeholders::_1,
pkt.ServiceProtocol());
} }
// prepare packet for insertion into network // prepare packet for insertion into network
// this includes clearing IP addresses, recalculating checksums, etc // this includes clearing IP addresses, recalculating checksums, etc
@ -967,8 +950,7 @@ namespace llarp
// llarp::LogInfo("themIP ", themIP); // llarp::LogInfo("themIP ", themIP);
auto usIP = m_OurIP; auto usIP = m_OurIP;
ManagedBuffer buf(b); ManagedBuffer buf(b);
return m_NetworkToUserPktQueue.EmplaceIf( return m_NetworkToUserPktQueue.EmplaceIf([buf, themIP, usIP](net::IPPacket& pkt) -> bool {
[buf, themIP, usIP](net::IPPacket &pkt) -> bool {
// load // load
if (!pkt.Load(buf)) if (!pkt.Load(buf))
return false; return false;
@ -981,15 +963,14 @@ namespace llarp
if (pkt.IsV4()) if (pkt.IsV4())
{ {
auto hdr = pkt.Header(); auto hdr = pkt.Header();
if(pkt.sz < sizeof(*hdr) if (pkt.sz < sizeof(*hdr) || (hdr->saddr != 0 && *(byte_t*)&(hdr->saddr) == 0)
|| (hdr->saddr != 0 && *(byte_t *)&(hdr->saddr) == 0)
|| (hdr->daddr != 0 && *(byte_t*)&(hdr->daddr) == 0) || (hdr->daddr != 0 && *(byte_t*)&(hdr->daddr) == 0)
|| ((hdr->saddr == 0) != (hdr->daddr == 0))) || ((hdr->saddr == 0) != (hdr->daddr == 0)))
{ {
return false; return false;
} }
pkt.UpdateIPv4Address(xhtonl(net::IPPacket::TruncateV6(themIP)), pkt.UpdateIPv4Address(
xhtonl(net::IPPacket::TruncateV6(usIP))); xhtonl(net::IPPacket::TruncateV6(themIP)), xhtonl(net::IPPacket::TruncateV6(usIP)));
} }
else if (pkt.IsV6()) else if (pkt.IsV6())
{ {
@ -1026,8 +1007,7 @@ namespace llarp
do do
{ {
nextIP = ++m_NextIP; nextIP = ++m_NextIP;
} while(m_IPToAddr.find(nextIP) != m_IPToAddr.end() } while (m_IPToAddr.find(nextIP) != m_IPToAddr.end() && m_NextIP < m_MaxIP);
&& m_NextIP < m_MaxIP);
if (nextIP < m_MaxIP) if (nextIP < m_MaxIP)
{ {
m_AddrToIP[ident] = nextIP; m_AddrToIP[ident] = nextIP;

@ -20,8 +20,11 @@ namespace llarp
public dns::IQueryHandler, public dns::IQueryHandler,
public std::enable_shared_from_this<TunEndpoint> public std::enable_shared_from_this<TunEndpoint>
{ {
TunEndpoint(const std::string& nickname, AbstractRouter* r, TunEndpoint(
llarp::service::Context* parent, bool lazyVPN = false); const std::string& nickname,
AbstractRouter* r,
llarp::service::Context* parent,
bool lazyVPN = false);
~TunEndpoint() override; ~TunEndpoint() override;
path::PathSet_ptr path::PathSet_ptr
@ -50,8 +53,7 @@ namespace llarp
bool bool
HandleHookedDNSMessage( HandleHookedDNSMessage(
dns::Message query, dns::Message query, std::function<void(dns::Message)> sendreply) override;
std::function< void(dns::Message) > sendreply) override;
void void
TickTun(llarp_time_t now); TickTun(llarp_time_t now);
@ -81,9 +83,8 @@ namespace llarp
/// overrides Endpoint /// overrides Endpoint
bool bool
HandleInboundPacket(const service::ConvoTag tag, HandleInboundPacket(
const llarp_buffer_t& pkt, const service::ConvoTag tag, const llarp_buffer_t& pkt, service::ProtocolType t) override
service::ProtocolType t) override
{ {
if (t != service::eProtocolTrafficV4 && t != service::eProtocolTrafficV6) if (t != service::eProtocolTrafficV4 && t != service::eProtocolTrafficV6)
return false; return false;
@ -97,8 +98,7 @@ namespace llarp
/// handle inbound traffic /// handle inbound traffic
bool bool
HandleWriteIPPacket(const llarp_buffer_t& buf, HandleWriteIPPacket(const llarp_buffer_t& buf, std::function<huint128_t(void)> getFromIP);
std::function< huint128_t(void) > getFromIP);
/// queue outbound packet to the world /// queue outbound packet to the world
bool bool
@ -189,8 +189,11 @@ namespace llarp
llarp_time_t m_LastFlushAt = 0s; llarp_time_t m_LastFlushAt = 0s;
using PacketQueue_t = llarp::util::CoDelQueue< using PacketQueue_t = llarp::util::CoDelQueue<
net::IPPacket, net::IPPacket::GetTime, net::IPPacket::PutTime, net::IPPacket,
net::IPPacket::CompareOrder, net::IPPacket::GetNow >; net::IPPacket::GetTime,
net::IPPacket::PutTime,
net::IPPacket::CompareOrder,
net::IPPacket::GetNow>;
/// queue packet for send on net thread from user /// queue packet for send on net thread from user
std::vector<net::IPPacket> m_TunPkts; std::vector<net::IPPacket> m_TunPkts;
@ -217,14 +220,11 @@ namespace llarp
/// maps ip to key (host byte order) /// maps ip to key (host byte order)
std::unordered_map<huint128_t, AlignedBuffer<32>> m_IPToAddr; std::unordered_map<huint128_t, AlignedBuffer<32>> m_IPToAddr;
/// maps key to ip (host byte order) /// maps key to ip (host byte order)
std::unordered_map< AlignedBuffer< 32 >, huint128_t, std::unordered_map<AlignedBuffer<32>, huint128_t, AlignedBuffer<32>::Hash> m_AddrToIP;
AlignedBuffer< 32 >::Hash >
m_AddrToIP;
/// maps key to true if key is a service node, maps key to false if key is /// maps key to true if key is a service node, maps key to false if key is
/// a hidden service /// a hidden service
std::unordered_map< AlignedBuffer< 32 >, bool, AlignedBuffer< 32 >::Hash > std::unordered_map<AlignedBuffer<32>, bool, AlignedBuffer<32>::Hash> m_SNodes;
m_SNodes;
private: private:
llarp_vpn_io_impl* llarp_vpn_io_impl*
@ -239,16 +239,14 @@ namespace llarp
QueueInboundPacketForExit(const llarp_buffer_t& buf) QueueInboundPacketForExit(const llarp_buffer_t& buf)
{ {
ManagedBuffer copy{buf}; ManagedBuffer copy{buf};
return m_NetworkToUserPktQueue.EmplaceIf( return m_NetworkToUserPktQueue.EmplaceIf([&](llarp::net::IPPacket& pkt) -> bool {
[&](llarp::net::IPPacket& pkt) -> bool {
if (!pkt.Load(copy.underlying)) if (!pkt.Load(copy.underlying))
return false; return false;
if (SupportsV6()) if (SupportsV6())
{ {
if (pkt.IsV4()) if (pkt.IsV4())
{ {
pkt.UpdateIPv6Address(net::IPPacket::ExpandV4(pkt.srcv4()), pkt.UpdateIPv6Address(net::IPPacket::ExpandV4(pkt.srcv4()), m_OurIP);
m_OurIP);
} }
else else
{ {
@ -259,8 +257,7 @@ namespace llarp
{ {
if (pkt.IsV4()) if (pkt.IsV4())
pkt.UpdateIPv4Address( pkt.UpdateIPv4Address(
xhtonl(pkt.srcv4()), xhtonl(pkt.srcv4()), xhtonl(net::IPPacket::TruncateV6(m_OurIP)));
xhtonl(net::IPPacket::TruncateV6(m_OurIP)));
else else
return false; return false;
} }
@ -270,9 +267,12 @@ namespace llarp
template <typename Addr_t, typename Endpoint_t> template <typename Addr_t, typename Endpoint_t>
void void
SendDNSReply(Addr_t addr, Endpoint_t ctx, SendDNSReply(
Addr_t addr,
Endpoint_t ctx,
std::shared_ptr<dns::Message> query, std::shared_ptr<dns::Message> query,
std::function< void(dns::Message) > reply, bool snode, std::function<void(dns::Message)> reply,
bool snode,
bool sendIPv6) bool sendIPv6)
{ {
if (ctx) if (ctx)

@ -19,8 +19,7 @@ namespace llarp
namespace hooks namespace hooks
{ {
#if defined(ENABLE_SHELLHOOKS) #if defined(ENABLE_SHELLHOOKS)
struct ExecShellHookBackend struct ExecShellHookBackend : public IBackend,
: public IBackend,
public std::enable_shared_from_this<ExecShellHookBackend> public std::enable_shared_from_this<ExecShellHookBackend>
{ {
thread::ThreadPool m_ThreadPool; thread::ThreadPool m_ThreadPool;
@ -28,8 +27,7 @@ namespace llarp
std::vector<std::string> _args; std::vector<std::string> _args;
std::vector<char*> args; std::vector<char*> args;
ExecShellHookBackend(std::string script) ExecShellHookBackend(std::string script) : m_ThreadPool(1, 1000, "exechook")
: m_ThreadPool(1, 1000, "exechook")
{ {
do do
{ {
@ -79,8 +77,7 @@ namespace llarp
} }
void void
NotifyAsync( NotifyAsync(std::unordered_map<std::string, std::string> params) override;
std::unordered_map< std::string, std::string > params) override;
}; };
struct ExecShellHookJob struct ExecShellHookJob
@ -89,7 +86,8 @@ namespace llarp
std::vector<char*> _m_env; std::vector<char*> _m_env;
std::shared_ptr<ExecShellHookBackend> m_Parent; std::shared_ptr<ExecShellHookBackend> m_Parent;
ExecShellHookJob(std::shared_ptr< ExecShellHookBackend > b, ExecShellHookJob(
std::shared_ptr<ExecShellHookBackend> b,
const std::unordered_map<std::string, std::string> env) const std::unordered_map<std::string, std::string> env)
: m_Parent(b) : m_Parent(b)
{ {
@ -134,11 +132,9 @@ namespace llarp
}; };
void void
ExecShellHookBackend::NotifyAsync( ExecShellHookBackend::NotifyAsync(std::unordered_map<std::string, std::string> params)
std::unordered_map< std::string, std::string > params)
{ {
auto job = std::make_shared< ExecShellHookJob >(shared_from_this(), auto job = std::make_shared<ExecShellHookJob>(shared_from_this(), std::move(params));
std::move(params));
m_ThreadPool.addJob(std::bind(&ExecShellHookJob::Exec, job)); m_ThreadPool.addJob(std::bind(&ExecShellHookJob::Exec, job));
} }

@ -8,27 +8,35 @@ namespace llarp
namespace iwp namespace iwp
{ {
LinkLayer_ptr LinkLayer_ptr
NewInboundLink(std::shared_ptr< KeyManager > keyManager, GetRCFunc getrc, NewInboundLink(
LinkMessageHandler h, SignBufferFunc sign, std::shared_ptr<KeyManager> keyManager,
GetRCFunc getrc,
LinkMessageHandler h,
SignBufferFunc sign,
SessionEstablishedHandler est, SessionEstablishedHandler est,
SessionRenegotiateHandler reneg, TimeoutHandler timeout, SessionRenegotiateHandler reneg,
SessionClosedHandler closed, PumpDoneHandler pumpDone) TimeoutHandler timeout,
SessionClosedHandler closed,
PumpDoneHandler pumpDone)
{ {
return std::make_shared< LinkLayer >(keyManager, getrc, h, sign, est, return std::make_shared<LinkLayer>(
reneg, timeout, closed, pumpDone, keyManager, getrc, h, sign, est, reneg, timeout, closed, pumpDone, true);
true);
} }
LinkLayer_ptr LinkLayer_ptr
NewOutboundLink(std::shared_ptr< KeyManager > keyManager, GetRCFunc getrc, NewOutboundLink(
LinkMessageHandler h, SignBufferFunc sign, std::shared_ptr<KeyManager> keyManager,
GetRCFunc getrc,
LinkMessageHandler h,
SignBufferFunc sign,
SessionEstablishedHandler est, SessionEstablishedHandler est,
SessionRenegotiateHandler reneg, TimeoutHandler timeout, SessionRenegotiateHandler reneg,
SessionClosedHandler closed, PumpDoneHandler pumpDone) TimeoutHandler timeout,
SessionClosedHandler closed,
PumpDoneHandler pumpDone)
{ {
return std::make_shared< LinkLayer >(keyManager, getrc, h, sign, est, return std::make_shared<LinkLayer>(
reneg, timeout, closed, pumpDone, keyManager, getrc, h, sign, est, reneg, timeout, closed, pumpDone, false);
false);
} }
} // namespace iwp } // namespace iwp
} // namespace llarp } // namespace llarp

@ -11,17 +11,27 @@ namespace llarp
namespace iwp namespace iwp
{ {
LinkLayer_ptr LinkLayer_ptr
NewInboundLink(std::shared_ptr< KeyManager > keyManager, GetRCFunc getrc, NewInboundLink(
LinkMessageHandler h, SignBufferFunc sign, std::shared_ptr<KeyManager> keyManager,
GetRCFunc getrc,
LinkMessageHandler h,
SignBufferFunc sign,
SessionEstablishedHandler est, SessionEstablishedHandler est,
SessionRenegotiateHandler reneg, TimeoutHandler timeout, SessionRenegotiateHandler reneg,
SessionClosedHandler closed, PumpDoneHandler pumpDone); TimeoutHandler timeout,
SessionClosedHandler closed,
PumpDoneHandler pumpDone);
LinkLayer_ptr LinkLayer_ptr
NewOutboundLink(std::shared_ptr< KeyManager > keyManager, GetRCFunc getrc, NewOutboundLink(
LinkMessageHandler h, SignBufferFunc sign, std::shared_ptr<KeyManager> keyManager,
GetRCFunc getrc,
LinkMessageHandler h,
SignBufferFunc sign,
SessionEstablishedHandler est, SessionEstablishedHandler est,
SessionRenegotiateHandler reneg, TimeoutHandler timeout, SessionRenegotiateHandler reneg,
SessionClosedHandler closed, PumpDoneHandler pumpDone); TimeoutHandler timeout,
SessionClosedHandler closed,
PumpDoneHandler pumpDone);
} // namespace iwp } // namespace iwp
} // namespace llarp } // namespace llarp

@ -8,14 +8,18 @@ namespace llarp
{ {
namespace iwp namespace iwp
{ {
LinkLayer::LinkLayer(std::shared_ptr< KeyManager > keyManager, LinkLayer::LinkLayer(
GetRCFunc getrc, LinkMessageHandler h, std::shared_ptr<KeyManager> keyManager,
SignBufferFunc sign, SessionEstablishedHandler est, GetRCFunc getrc,
LinkMessageHandler h,
SignBufferFunc sign,
SessionEstablishedHandler est,
SessionRenegotiateHandler reneg, SessionRenegotiateHandler reneg,
TimeoutHandler timeout, SessionClosedHandler closed, TimeoutHandler timeout,
PumpDoneHandler pumpDone, bool allowInbound) SessionClosedHandler closed,
: ILinkLayer(keyManager, getrc, h, sign, est, reneg, timeout, closed, PumpDoneHandler pumpDone,
pumpDone) bool allowInbound)
: ILinkLayer(keyManager, getrc, h, sign, est, reneg, timeout, closed, pumpDone)
, permitInbound{allowInbound} , permitInbound{allowInbound}
{ {
} }
@ -69,8 +73,7 @@ namespace llarp
bool success = session->Recv_LL(std::move(pkt)); bool success = session->Recv_LL(std::move(pkt));
if (!success and isNewSession) if (!success and isNewSession)
{ {
LogWarn( LogWarn("Brand new session failed; removing from pending sessions list");
"Brand new session failed; removing from pending sessions list");
m_Pending.erase(m_Pending.find(from)); m_Pending.erase(m_Pending.find(from));
} }
} }
@ -92,8 +95,7 @@ namespace llarp
} }
std::shared_ptr<ILinkSession> std::shared_ptr<ILinkSession>
LinkLayer::NewOutboundSession(const RouterContact& rc, LinkLayer::NewOutboundSession(const RouterContact& rc, const AddressInfo& ai)
const AddressInfo& ai)
{ {
return std::make_shared<Session>(this, rc, ai); return std::make_shared<Session>(this, rc, ai);
} }

@ -17,17 +17,22 @@ namespace llarp
{ {
struct LinkLayer final : public ILinkLayer struct LinkLayer final : public ILinkLayer
{ {
LinkLayer(std::shared_ptr< KeyManager > keyManager, GetRCFunc getrc, LinkLayer(
LinkMessageHandler h, SignBufferFunc sign, std::shared_ptr<KeyManager> keyManager,
SessionEstablishedHandler est, SessionRenegotiateHandler reneg, GetRCFunc getrc,
TimeoutHandler timeout, SessionClosedHandler closed, LinkMessageHandler h,
PumpDoneHandler pumpDone, bool permitInbound); SignBufferFunc sign,
SessionEstablishedHandler est,
SessionRenegotiateHandler reneg,
TimeoutHandler timeout,
SessionClosedHandler closed,
PumpDoneHandler pumpDone,
bool permitInbound);
~LinkLayer() override; ~LinkLayer() override;
std::shared_ptr<ILinkSession> std::shared_ptr<ILinkSession>
NewOutboundSession(const RouterContact &rc, NewOutboundSession(const RouterContact& rc, const AddressInfo& ai) override;
const AddressInfo &ai) override;
const char* const char*
Name() const override; Name() const override;

@ -6,7 +6,8 @@ namespace llarp
{ {
namespace iwp namespace iwp
{ {
OutboundMessage::OutboundMessage(uint64_t msgid, OutboundMessage::OutboundMessage(
uint64_t msgid,
ILinkSession::Message_t msg, ILinkSession::Message_t msg,
llarp_time_t now, llarp_time_t now,
ILinkSession::CompletionHandler handler) ILinkSession::CompletionHandler handler)
@ -27,10 +28,9 @@ namespace llarp
auto xmit = CreatePacket(Command::eXMIT, 10 + 32 + extra, 0, 0); auto xmit = CreatePacket(Command::eXMIT, 10 + 32 + extra, 0, 0);
htobe16buf(xmit.data() + CommandOverhead + PacketOverhead, m_Data.size()); htobe16buf(xmit.data() + CommandOverhead + PacketOverhead, m_Data.size());
htobe64buf(xmit.data() + 2 + CommandOverhead + PacketOverhead, m_MsgID); htobe64buf(xmit.data() + 2 + CommandOverhead + PacketOverhead, m_MsgID);
std::copy_n(m_Digest.begin(), m_Digest.size(), std::copy_n(
xmit.data() + 10 + CommandOverhead + PacketOverhead); m_Digest.begin(), m_Digest.size(), xmit.data() + 10 + CommandOverhead + PacketOverhead);
std::copy_n(m_Data.data(), extra, std::copy_n(m_Data.data(), extra, xmit.data() + 10 + CommandOverhead + PacketOverhead + 32);
xmit.data() + 10 + CommandOverhead + PacketOverhead + 32);
return xmit; return xmit;
} }
@ -68,12 +68,13 @@ namespace llarp
{ {
if (not m_Acks[idx / FragmentSize]) if (not m_Acks[idx / FragmentSize])
{ {
const size_t fragsz = const size_t fragsz = idx + FragmentSize < datasz ? FragmentSize : datasz - idx;
idx + FragmentSize < datasz ? FragmentSize : datasz - idx;
auto frag = CreatePacket(Command::eDATA, fragsz + Overhead, 0, 0); auto frag = CreatePacket(Command::eDATA, fragsz + Overhead, 0, 0);
htobe16buf(frag.data() + 2 + PacketOverhead, idx); htobe16buf(frag.data() + 2 + PacketOverhead, idx);
htobe64buf(frag.data() + 4 + PacketOverhead, m_MsgID); htobe64buf(frag.data() + 4 + PacketOverhead, m_MsgID);
std::copy(m_Data.begin() + idx, m_Data.begin() + idx + fragsz, std::copy(
m_Data.begin() + idx,
m_Data.begin() + idx + fragsz,
frag.data() + PacketOverhead + Overhead + 2); frag.data() + PacketOverhead + Overhead + 2);
sendpkt(std::move(frag)); sendpkt(std::move(frag));
} }
@ -111,18 +112,13 @@ namespace llarp
m_Completed = nullptr; m_Completed = nullptr;
} }
InboundMessage::InboundMessage(uint64_t msgid, uint16_t sz, ShortHash h, InboundMessage::InboundMessage(uint64_t msgid, uint16_t sz, ShortHash h, llarp_time_t now)
llarp_time_t now) : m_Data(size_t{sz}), m_Digset{std::move(h)}, m_MsgID(msgid), m_LastActiveAt{now}
: m_Data(size_t{sz})
, m_Digset{std::move(h)}
, m_MsgID(msgid)
, m_LastActiveAt{now}
{ {
} }
void void
InboundMessage::HandleData(uint16_t idx, const llarp_buffer_t &buf, InboundMessage::HandleData(uint16_t idx, const llarp_buffer_t& buf, llarp_time_t now)
llarp_time_t now)
{ {
if (idx + buf.sz > m_Data.size()) if (idx + buf.sz > m_Data.size())
{ {
@ -176,8 +172,7 @@ namespace llarp
} }
void void
InboundMessage::SendACKS( InboundMessage::SendACKS(std::function<void(ILinkSession::Packet_t)> sendpkt, llarp_time_t now)
std::function< void(ILinkSession::Packet_t) > sendpkt, llarp_time_t now)
{ {
sendpkt(ACKS()); sendpkt(ACKS());
m_LastACKSent = now; m_LastACKSent = now;

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save