dht and testnet fixes

pull/10/head^2
Jeff Becker 6 years ago
parent f68e3029b0
commit 86ec4dacc3

@ -98,6 +98,7 @@ prefetch-tag=test
f.write('''[program:svc-node]
directory = {}
command = {}
autorestart=true
redirect_stderr=true
#stdout_logfile=/dev/fd/1
stdout_logfile={}/svc-node-%(process_num)03d-log.txt
@ -108,6 +109,7 @@ numprocs = {}
f.write('''[program:client-node]
directory = {}
command = {}
autorestart=true
redirect_stderr=true
#stdout_logfile=/dev/fd/1
stdout_logfile={}/client-node-%(process_num)03d-log.txt

@ -5,6 +5,7 @@
#include <llarp/dht/key.hpp>
#include <map>
#include <set>
#include <vector>
namespace llarp
{
@ -17,6 +18,22 @@ namespace llarp
Bucket(const Key_t& us) : nodes(XorMetric(us)){};
bool
GetRandomNodeExcluding(Key_t& result,
const std::set< Key_t >& exclude) const
{
std::vector< Key_t > candidates;
for(const auto& item : nodes)
{
if(exclude.find(item.first) == exclude.end())
candidates.push_back(item.first);
}
if(candidates.size() == 0)
return false;
result = candidates[llarp_randint() % candidates.size()];
return true;
}
bool
FindClosest(const Key_t& target, Key_t& result) const
{

@ -49,7 +49,7 @@ namespace llarp
LookupTag(const service::Tag& tag, const Key_t& whoasked,
uint64_t whoaskedTX, const Key_t& askpeer,
const std::set< service::IntroSet >& include = {},
bool iterative = false);
uint64_t R = 0);
void
LookupRouterViaJob(llarp_router_lookup_job* job);

@ -124,7 +124,7 @@ namespace llarp
#ifndef _MSC_VER
if(inet_ntop(a.af(), ptr, tmp, sz))
#else
if(inet_ntop(a.af(), (void*)ptr, tmp,sz))
if(inet_ntop(a.af(), (void*)ptr, tmp, sz))
#endif
{
out << tmp;
@ -152,22 +152,22 @@ namespace llarp
switch(af())
{
case AF_INET:
dst = (void*)&((sockaddr_in*)other)->sin_addr.s_addr;
src = (void*)&_addr.sin6_addr.s6_addr[12];
ptr = &((sockaddr_in*)other)->sin_port;
dst = (void*)&((sockaddr_in*)other)->sin_addr.s_addr;
src = (void*)&_addr.sin6_addr.s6_addr[12];
ptr = &((sockaddr_in*)other)->sin_port;
slen = sizeof(in_addr);
break;
case AF_INET6:
dst = (void*)((sockaddr_in6*)other)->sin6_addr.s6_addr;
src = (void*)_addr.sin6_addr.s6_addr;
ptr = &((sockaddr_in6*)other)->sin6_port;
dst = (void*)((sockaddr_in6*)other)->sin6_addr.s6_addr;
src = (void*)_addr.sin6_addr.s6_addr;
ptr = &((sockaddr_in6*)other)->sin6_port;
slen = sizeof(in6_addr);
break;
default:
return;
}
memcpy(dst, src, slen);
*ptr = htons(port());
*ptr = htons(port());
other->sa_family = af();
}
@ -220,7 +220,7 @@ namespace llarp
isPrivate()
{
in_addr_t addr = this->addr4()->s_addr;
unsigned byte = ntohl(addr);
unsigned byte = ntohl(addr);
unsigned byte1 = byte >> 24 & 0xff;
unsigned byte2 = (0x00ff0000 & byte >> 16);
return (byte1 == 10 || (byte1 == 192 && byte2 == 168)
@ -240,7 +240,7 @@ namespace llarp
{
if(a.af() == AF_INET)
{
return a.port() + a.addr4()->s_addr;
return a.port() ^ a.addr4()->s_addr;
}
uint8_t empty[16] = {0};
return (a.af() + memcmp(a.addr6(), empty, 16)) ^ a.port();

@ -9,7 +9,7 @@ namespace llarp
{
namespace service
{
struct Endpoint : public llarp_pathbuilder_context
struct Endpoint : public llarp_pathbuilder_context, public ILookupHolder
{
/// minimum interval for publishing introsets
static const llarp_time_t INTROSET_PUBLISH_INTERVAL =
@ -74,6 +74,9 @@ namespace llarp
return &m_Identity;
}
void
PutLookup(IServiceLookup* lookup, uint64_t txid);
void
HandlePathBuilt(path::Path* path);
@ -117,6 +120,12 @@ namespace llarp
bool
HandleHiddenServiceFrame(const ProtocolFrame* frame);
void
PutLookup(IServiceLookup* lookup, uint64_t txid);
std::string
Name() const;
private:
void
AsyncEncrypt(llarp_buffer_t payload);
@ -131,6 +140,7 @@ namespace llarp
uint64_t sequenceNo = 0;
llarp::SharedSecret sharedKey;
Endpoint* m_Parent;
uint64_t m_UpdateIntrosetTX = 0;
};
// passed a sendto context when we have a path established otherwise
@ -196,13 +206,12 @@ namespace llarp
{
const static llarp_time_t TTL = 10000;
llarp_time_t lastRequest = 0;
llarp_time_t lastModified;
uint64_t pendingTX = 0;
llarp_time_t lastModified = 0;
std::set< IntroSet > result;
Tag tag;
CachedTagResult(const Tag& t, llarp_time_t now)
: lastModified(now), tag(t)
CachedTagResult(Endpoint* p, const Tag& t, uint64_t tx)
: IServiceLookup(p, tx), tag(t)
{
}
@ -216,7 +225,7 @@ namespace llarp
{
if(now <= lastRequest)
return false;
return (now - lastRequest) > TTL && pendingTX == 0;
return (now - lastRequest) > TTL;
}
llarp::routing::IMessage*

@ -16,11 +16,11 @@ namespace llarp
namespace service
{
struct ILookupHolder;
struct IServiceLookup
{
IServiceLookup() : m_created(llarp_time_now_ms())
{
}
IServiceLookup(ILookupHolder* parent, uint64_t tx);
virtual ~IServiceLookup(){};
@ -45,10 +45,19 @@ namespace llarp
bool
SendRequestViaPath(llarp::path::Path* p, llarp_router* r);
private:
ILookupHolder* parent;
uint64_t txid;
protected:
llarp_time_t m_created;
};
struct ILookupHolder
{
virtual void
PutLookup(IServiceLookup* l, uint64_t txid) = 0;
};
} // namespace service
} // namespace llarp

@ -256,6 +256,10 @@ namespace iwp
{
iwp_async_session_start *session =
static_cast< iwp_async_session_start * >(user);
// possible repeat job
if(session->buf == nullptr)
return;
auto crypto = session->iwp->crypto;
auto logic = session->iwp->logic;

@ -38,7 +38,10 @@ namespace llarp
while(itr != nodes.end())
{
if(itr->second.introset.IsExpired(now))
{
llarp::LogInfo("introset expired ", itr->second.introset.A.Addr());
itr = nodes.erase(itr);
}
else
++itr;
}
@ -54,9 +57,6 @@ namespace llarp
std::set< service::IntroSet > localIntroSets;
std::set< Key_t > asked;
service::Tag tag;
service::Address addr;
PathLookupJob(llarp_router *r, const PathID_t &localpath, uint64_t tx)
: txid(tx), pathID(localpath), m_router(r)
{
@ -80,6 +80,7 @@ namespace llarp
{
intros[--sz] = i;
}
llarp::LogInfo("found ", sz, " introsets for txid=", txid);
msg.M.push_back(new llarp::dht::GotIntroMessage(intros, txid));
path->SendRoutingMessage(&msg, m_router);
}
@ -134,7 +135,10 @@ namespace llarp
auto msg = new llarp::DHTImmeidateMessage(askpeer);
auto dhtmsg = new FindIntroMessage(tag, id);
dhtmsg->R = 5;
msg->msgs.push_back(dhtmsg);
llarp::LogInfo("asking ", askpeer, " for tag ", tag.ToString(), " with ",
j->localIntroSets.size(), " local tags txid=", txid);
router->SendToOrQueue(askpeer, msg);
}
@ -171,10 +175,11 @@ namespace llarp
// start at random middle point
auto start = llarp_randint() % nodes.size();
std::advance(itr, start);
auto end = itr;
auto end = itr;
std::string tagname = tag.ToString();
while(itr != nodes.end())
{
if(itr->second.introset.topic == tag)
if(itr->second.introset.topic.ToString() == tagname)
{
found.insert(itr->second.introset);
if(found.size() == max)
@ -185,7 +190,7 @@ namespace llarp
itr = nodes.begin();
while(itr != end)
{
if(itr->second.introset.topic == tag)
if(itr->second.introset.topic.ToString() == tagname)
{
found.insert(itr->second.introset);
if(found.size() == max)
@ -372,8 +377,7 @@ namespace llarp
void
Context::LookupTag(const llarp::service::Tag &tag, const Key_t &whoasked,
uint64_t txid, const Key_t &askpeer,
const std::set< service::IntroSet > &include,
bool iterative)
const std::set< service::IntroSet > &include, uint64_t R)
{
auto id = ++ids;
if(txid == 0)
@ -388,9 +392,9 @@ namespace llarp
std::bind(&IntroSetInformJob::OnResult, j, std::placeholders::_1));
pendingTX[ownerKey] = job;
auto msg = new llarp::DHTImmeidateMessage(askpeer);
auto dhtmsg = new FindIntroMessage(tag, id);
dhtmsg->iterative = iterative;
auto msg = new llarp::DHTImmeidateMessage(askpeer);
auto dhtmsg = new FindIntroMessage(tag, id);
dhtmsg->R = R;
msg->msgs.push_back(dhtmsg);
router->SendToOrQueue(askpeer, msg);
}

@ -101,6 +101,11 @@ namespace llarp
llarp_dht_context* ctx,
std::vector< llarp::dht::IMessage* >& replies) const
{
if(R > 5)
{
llarp::LogError("R value too big, ", R, "> 5");
return false;
}
auto& dht = ctx->impl;
Key_t peer;
std::set< Key_t > exclude = {dht.OurKey(), From};
@ -146,7 +151,7 @@ namespace llarp
if(relayed)
{
// tag lookup
if(dht.nodes->FindCloseExcluding(N.Key(), peer, exclude))
if(dht.nodes->GetRandomNodeExcluding(peer, exclude))
{
dht.LookupTagForPath(N, T, pathID, peer);
}
@ -158,7 +163,7 @@ namespace llarp
else
{
auto introsets = dht.FindRandomIntroSetsWithTag(N);
if(iterative)
if(iterative || R == 0)
{
std::vector< service::IntroSet > reply;
for(const auto& introset : introsets)
@ -171,9 +176,9 @@ namespace llarp
else
{
// tag lookup
if(dht.nodes->FindCloseExcluding(N.Key(), peer, exclude))
if(dht.nodes->GetRandomNodeExcluding(peer, exclude))
{
dht.LookupTag(N, From, T, peer, introsets, true);
dht.LookupTag(N, From, T, peer, introsets, R - 1);
}
}
}

@ -213,8 +213,8 @@ llarp_link::RemoveSession(llarp_link_session* s)
UnmapAddr(s->addr);
s->done();
m_sessions.erase(itr);
delete s;
}
delete s;
}
uint8_t*

@ -2,6 +2,7 @@
#define NOMINMAX
#endif
#include <llarp/iwp.h>
#include <algorithm>
#include <llarp/crypto.hpp>
#include <llarp/iwp/server.hpp>
#include <llarp/iwp/session.hpp>
@ -9,7 +10,6 @@
#include "buffer.hpp"
#include "link/encoder.hpp"
#include "llarp/ev.h" // for handle_frame_encrypt
#include <algorithm>
static void
handle_crypto_outbound(void *u)
@ -467,7 +467,6 @@ static void
handle_verify_session_start(iwp_async_session_start *s)
{
llarp_link_session *self = static_cast< llarp_link_session * >(s->user);
self->serv->remove_intro_from(self->addr);
if(!s->buf)
{
// verify fail
@ -476,6 +475,7 @@ handle_verify_session_start(iwp_async_session_start *s)
self->serv->RemoveSession(self);
return;
}
self->serv->remove_intro_from(self->addr);
self->send_LIM();
self->working = false;
}
@ -653,6 +653,11 @@ llarp_link_session::on_session_start(const void *buf, size_t sz)
llarp::LogDebug("session start too big");
return;
}
if(working)
{
llarp::LogError("duplicate session start from ", addr);
return;
}
// own the buffer
memcpy(workbuf, buf, sz);
// verify session start

@ -1,3 +1,4 @@
#include <llarp/dht/messages/findintro.hpp>
#include <llarp/messages/dht.hpp>
#include <llarp/service/endpoint.hpp>
@ -139,7 +140,8 @@ namespace llarp
if(itr == m_PrefetchedTags.end())
{
itr = m_PrefetchedTags
.insert(std::make_pair(tag, CachedTagResult(tag, now)))
.insert(std::make_pair(
tag, CachedTagResult(this, tag, GenTXID())))
.first;
}
for(const auto& introset : itr->second.result)
@ -161,8 +163,7 @@ namespace llarp
auto path = PickRandomEstablishedPath();
if(path)
{
itr->second.pendingTX = GenTXID();
m_PendingLookups[itr->second.pendingTX] = &itr->second;
itr->second.txid = GenTXID();
itr->second.SendRequestViaPath(path, m_Router);
}
}
@ -205,6 +206,12 @@ namespace llarp
return m_RemoteSessions.find(addr) != m_RemoteSessions.end();
}
void
Endpoint::PutLookup(IServiceLookup* lookup, uint64_t txid)
{
m_PendingLookups.insert(std::make_pair(txid, lookup));
}
bool
Endpoint::HandleGotIntroMessage(const llarp::dht::GotIntroMessage* msg)
{
@ -278,7 +285,7 @@ namespace llarp
{
auto now = llarp_time_now_ms();
pendingTX = 0;
txid = 0;
for(const auto& introset : introsets)
if(result.insert(introset).second)
lastModified = now;
@ -312,8 +319,9 @@ namespace llarp
Endpoint::CachedTagResult::BuildRequestMessage()
{
llarp::routing::DHTMessage* msg = new llarp::routing::DHTMessage();
msg->M.push_back(new llarp::dht::FindIntroMessage(tag, pendingTX));
msg->M.push_back(new llarp::dht::FindIntroMessage(tag, txid));
lastRequest = llarp_time_now_ms();
parent->PutLookup(this, txid);
return msg;
}
@ -326,7 +334,7 @@ namespace llarp
m_CurrentPublishTX = llarp_randint();
llarp::routing::DHTMessage msg;
msg.M.push_back(new llarp::dht::PublishIntroMessage(
m_IntroSet, m_CurrentPublishTX, 3));
m_IntroSet, m_CurrentPublishTX, 4));
if(path->SendRoutingMessage(&msg, r))
{
m_LastPublishAttempt = llarp_time_now_ms();
@ -334,7 +342,7 @@ namespace llarp
return true;
}
}
llarp::LogWarn(Name(), " publish introset failed");
llarp::LogWarn(Name(), " publish introset failed, no path");
return false;
}
@ -365,12 +373,11 @@ namespace llarp
struct HiddenServiceAddressLookup : public IServiceLookup
{
Endpoint* endpoint;
Address remote;
uint64_t txid;
HiddenServiceAddressLookup(Endpoint* parent, const Address& addr,
uint64_t tx)
: endpoint(parent), remote(addr), txid(tx)
Endpoint* endpoint;
HiddenServiceAddressLookup(Endpoint* p, const Address& addr, uint64_t tx)
: IServiceLookup(p, tx), remote(addr), endpoint(p)
{
llarp::LogInfo("New hidden service lookup for ", addr.ToString());
}
@ -447,6 +454,12 @@ namespace llarp
std::placeholders::_1));
}
void
Endpoint::OutboundContext::PutLookup(IServiceLookup* lookup, uint64_t txid)
{
m_Parent->PutLookup(lookup, txid);
}
bool
Endpoint::OutboundContext::HandleHiddenServiceFrame(
const ProtocolFrame* frame)
@ -486,7 +499,6 @@ namespace llarp
HiddenServiceAddressLookup* job =
new HiddenServiceAddressLookup(this, remote, GenTXID());
m_PendingLookups.insert(std::make_pair(job->txid, job));
return job->SendRequestViaPath(path, Router());
}
@ -523,20 +535,30 @@ namespace llarp
Endpoint::OutboundContext::HandleGotIntroMessage(
const llarp::dht::GotIntroMessage* msg)
{
if(msg->T != m_UpdateIntrosetTX)
{
llarp::LogError("unwarrented introset message txid=", msg->T);
return false;
}
auto crypto = m_Parent->Crypto();
if(msg->I.size() == 1)
{
// found intro set
auto itr = msg->I.begin();
if(itr->VerifySignature(crypto) && currentIntroSet.A == itr->A)
const auto& introset = msg->I[0];
if(introset.VerifySignature(crypto) && currentIntroSet.A == introset.A)
{
currentIntroSet = *itr;
// update
currentIntroSet = introset;
// reset tx
m_UpdateIntrosetTX = 0;
// shift to newest intro
// TODO: check timestamp on introset to make sure it's new enough
ShiftIntroduction();
return true;
}
else
{
llarp::LogError("Signature Error for intro set ", *itr);
llarp::LogError("Signature Error for intro set ", introset);
return false;
}
}
@ -639,7 +661,7 @@ namespace llarp
transfer.Y.Randomize();
transfer.P = selectedIntro.pathID;
llarp::LogInfo("sending frame via ", path->Upstream(), " to ",
path->Endpoint());
path->Endpoint(), " for ", Name());
path->SendRoutingMessage(&transfer, m_Parent->Router());
}
else
@ -648,17 +670,27 @@ namespace llarp
}
}
std::string
Endpoint::OutboundContext::Name() const
{
return "OBContext:" + m_Parent->Name() + "-"
+ currentIntroSet.A.Addr().ToString();
}
void
Endpoint::OutboundContext::UpdateIntroSet()
{
auto path = PickRandomEstablishedPath();
auto path = GetEstablishedPathClosestTo(currentIntroSet.A.Addr());
if(path)
{
uint64_t txid = llarp_randint();
routing::DHTMessage msg;
msg.M.push_back(
new llarp::dht::FindIntroMessage(currentIntroSet.A.Addr(), txid));
path->SendRoutingMessage(&msg, m_Parent->Router());
if(m_UpdateIntrosetTX == 0)
{
m_UpdateIntrosetTX = llarp_randint();
routing::DHTMessage msg;
msg.M.push_back(new llarp::dht::FindIntroMessage(
currentIntroSet.A.Addr(), m_UpdateIntrosetTX));
path->SendRoutingMessage(&msg, m_Parent->Router());
}
}
else
{

@ -1,9 +1,17 @@
#include <llarp/path.hpp>
#include <llarp/service/endpoint.hpp>
#include <llarp/service/lookup.hpp>
namespace llarp
{
namespace service
{
IServiceLookup::IServiceLookup(ILookupHolder *p, uint64_t tx)
: parent(p), txid(tx)
{
p->PutLookup(this, tx);
}
bool
IServiceLookup::SendRequestViaPath(llarp::path::Path *path, llarp_router *r)
{

Loading…
Cancel
Save