more hidden service stuff

pull/6/head^2
Jeff Becker 6 years ago
parent 97e11a28f6
commit 7fbc21207f

@ -243,6 +243,7 @@ set(LIB_SRC
llarp/service/context.cpp
llarp/service/endpoint.cpp
llarp/service/lookup.cpp
llarp/service/protocol.cpp
llarp/service/tag.cpp
llarp/service/info.cpp
${LIBTUNTAP_SRC}

@ -86,13 +86,12 @@ def main():
fp = os.path.join(d, 'daemon.ini')
with open(fp, 'w') as f:
config.write(f)
config = CP()
config['test-service'] = {
'tag': 'test',
'prefetch-tag': "test"
}
with open(hiddenservice, 'w') as f:
config.write(f)
f.write('''[test-service]
tag=test
prefetch-tag=test
prefetch-tag=nonexist
''')
with open(args.out, 'w') as f:
f.write('''[program:svc-node]

@ -159,6 +159,15 @@ namespace llarp
return true;
}
struct Hash
{
size_t
operator()(const AlignedBuffer< sz >& buf) const
{
return *buf.data_l();
}
};
protected:
union {
byte_t b[sz];

@ -4,6 +4,8 @@
#include <llarp/bencode.h>
#include <llarp/logger.hpp>
#include <set>
namespace llarp
{
inline bool
@ -131,6 +133,31 @@ namespace llarp
return true;
}
template < typename T >
bool
BEncodeReadSet(std::set< T >& result, llarp_buffer_t* buf)
{
if(*buf->cur != 'l') // ensure is a list
return false;
buf->cur++;
while(llarp_buffer_size_left(*buf) && *buf->cur != 'e')
{
T item;
if(!item.BDecode(buf))
return false;
result.insert(item);
/*
if(!result.insert(item).second)
return false;
*/
}
if(*buf->cur != 'e') // make sure we're at a list end
return false;
buf->cur++;
return true;
}
template < typename List_t >
bool
BEncodeWriteDictList(const char* k, List_t& list, llarp_buffer_t* buf)
@ -150,7 +177,7 @@ namespace llarp
virtual bool
BEncode(llarp_buffer_t* buf) const = 0;
bool
virtual bool
BDecode(llarp_buffer_t* buf)
{
dict_reader r;

@ -1,7 +1,7 @@
#ifndef LLARP_CODEL_QUEUE_HPP
#define LLARP_CODEL_QUEUE_HPP
#include <llarp/time.h>
#include "llarp/logger.hpp"
#include <llarp/logger.hpp>
#include <cmath>
#include <functional>

@ -70,7 +70,8 @@ namespace llarp
const IMessage* msg);
void
PropagateIntroSetTo(const service::IntroSet& introset, const Key_t& peer,
PropagateIntroSetTo(const Key_t& from, uint64_t fromTX,
const service::IntroSet& introset, const Key_t& peer,
uint64_t S);
void

@ -10,7 +10,7 @@ namespace llarp
/// acknologement to PublishIntroMessage or reply to FinIntroMessage
struct GotIntroMessage : public IMessage
{
std::list< llarp::service::IntroSet > I;
std::set< llarp::service::IntroSet > I;
uint64_t T = 0;
GotIntroMessage(const Key_t& from) : IMessage(from)

@ -9,6 +9,7 @@ namespace llarp
struct PublishIntroMessage : public IMessage
{
llarp::service::IntroSet I;
std::set< Key_t > E;
uint64_t R = 0;
uint64_t S = 0;
uint64_t txID = 0;
@ -18,8 +19,8 @@ namespace llarp
}
PublishIntroMessage(const llarp::service::IntroSet& i, uint64_t tx,
uint64_t s)
: IMessage({}), txID(tx)
uint64_t s, const std::set< Key_t >& exclude = {})
: IMessage({}), E(exclude), txID(tx)
{
I = i;
S = s;

@ -1,6 +1,7 @@
#pragma once
#include "codel.hpp"
#include <llarp/codel.hpp>
#include <llarp/crypto.hpp>
#include "frame_header.hpp"
#include "inbound_message.hpp"
#include "llarp/logger.hpp"
@ -42,7 +43,10 @@ struct frame_state
uint64_t rxids = 0;
uint64_t txids = 0;
llarp_time_t lastEvent = 0;
std::unordered_map< uint64_t, transit_message * > rx;
std::unordered_map< uint64_t, llarp::ShortHash > rxIDs;
std::unordered_map< llarp::ShortHash, transit_message *,
llarp::ShortHash::Hash >
rx;
std::unordered_map< uint64_t, transit_message * > tx;
typedef std::queue< sendbuf_t * > sendqueue_t;

@ -1,7 +1,7 @@
#pragma once
#include <atomic>
#include "codel.hpp"
#include <llarp/codel.hpp>
#include "frame_state.hpp"
#include "llarp/buffer.h"
#include "llarp/crypto.hpp"

@ -21,9 +21,6 @@ namespace llarp
bool
DecodeKey(llarp_buffer_t key, llarp_buffer_t* val);
bool
BDecode(llarp_buffer_t* buf);
bool
HandleMessage(IMessageHandler* h, llarp_router* r) const;
};

@ -83,7 +83,7 @@ namespace llarp
bool
GetCurrentIntroductions(
std::list< llarp::service::Introduction >& intros) const;
std::set< llarp::service::Introduction >& intros) const;
virtual bool
PublishIntroSet(llarp_router* r)

@ -67,6 +67,14 @@ namespace llarp
bool
CalculateAddress(byte_t* buf) const;
bool
BDecode(llarp_buffer_t* buf)
{
if(!IBEncodeMessage::BDecode(buf))
return false;
return CalculateAddress(m_CachedAddr);
}
bool
BEncode(llarp_buffer_t* buf) const;

@ -9,7 +9,7 @@
#include <llarp/service/Intro.hpp>
#include <llarp/service/tag.hpp>
#include <list>
#include <set>
namespace llarp
{
@ -20,7 +20,7 @@ namespace llarp
struct IntroSet : public llarp::IBEncodeMessage
{
ServiceInfo A;
std::list< Introduction > I;
std::set< Introduction > I;
Tag topic;
llarp::PoW* W = nullptr;
llarp::Signature Z;
@ -44,7 +44,7 @@ namespace llarp
bool
operator<(const IntroSet& other) const
{
return A < other.A || topic < other.topic;
return A < other.A;
}
friend std::ostream&

@ -1,8 +1,10 @@
#ifndef LLARP_SERVICE_ENDPOINT_HPP
#define LLARP_SERVICE_ENDPOINT_HPP
#include <llarp/codel.hpp>
#include <llarp/messages/hidden_service.hpp>
#include <llarp/pathbuilder.hpp>
#include <llarp/service/Identity.hpp>
#include <llarp/service/protocol.hpp>
namespace llarp
{
@ -25,6 +27,15 @@ namespace llarp
void
Tick(llarp_time_t now);
llarp_logic*
Logic();
llarp_crypto*
Crypto();
llarp_threadpool*
Worker();
bool
Start();
@ -52,6 +63,9 @@ namespace llarp
bool
ForgetPathToService(const Address& remote);
byte_t*
GetEncryptionSecretKey();
/// context needed to initiate an outbound hidden service session
struct OutboundContext : public llarp_pathbuilder_context
{
@ -61,12 +75,9 @@ namespace llarp
/// the remote hidden service's curren intro set
IntroSet currentIntroSet;
uint64_t sequenceNo = 0;
/// encrypt asynchronously and send to remote endpoint from us
/// returns false if we cannot send yet otherwise returns true
bool
AsyncEncryptAndSendTo(llarp_buffer_t D);
void
AsyncEncryptAndSendTo(llarp_buffer_t D, ProtocolType protocol);
/// issues a lookup to find the current intro set of the remote service
void
@ -76,7 +87,27 @@ namespace llarp
HandleGotIntroMessage(const llarp::dht::GotIntroMessage* msg);
private:
void
AsyncEncrypt(ProtocolMessage* msg,
std::function< void(ProtocolMessage*) > result);
void
AsyncGenIntro(ProtocolMessage* msg,
std::function< void(ProtocolMessage*) > result);
/// handle key exchange done
void
HandleIntroGen(ProtocolMessage* msg);
/// send an encrypted message
void
SendMessage(ProtocolMessage* msg);
uint64_t sequenceNo = 0;
llarp::SharedSecret sharedKey;
llarp::util::CoDelQueue< ProtocolMessage*, ProtocolMessage::GetTime,
ProtocolMessage::PutTime,
llarp::util::DummyMutex,
llarp::util::DummyLock >
m_SendQueue;
Endpoint* m_Parent;
};
@ -134,14 +165,15 @@ namespace llarp
struct CachedTagResult : public IServiceLookup
{
const static llarp_time_t TTL = 5000;
llarp_time_t lastModified = 0;
uint64_t pendingTX = 0;
const static llarp_time_t TTL = 10000;
llarp_time_t lastRequest = 0;
llarp_time_t lastModified;
uint64_t pendingTX = 0;
std::set< IntroSet > result;
Tag tag;
CachedTagResult(const Tag& t) : tag(t)
CachedTagResult(const Tag& t, llarp_time_t now)
: lastModified(now), tag(t)
{
}
@ -153,8 +185,9 @@ namespace llarp
bool
ShouldRefresh(llarp_time_t now) const
{
return result.size() == 0
|| (now - lastModified >= TTL && pendingTX == 0);
if(now <= lastRequest)
return false;
return (now - lastRequest) > TTL && pendingTX == 0;
}
llarp::routing::IMessage*

@ -0,0 +1,56 @@
#ifndef LLARP_SERVICE_PROTOCOL_HPP
#define LLARP_SERVICE_PROTOCOL_HPP
#include <llarp/time.h>
#include <llarp/bencode.hpp>
#include <llarp/crypto.hpp>
#include <vector>
namespace llarp
{
namespace service
{
enum ProtocolType
{
eProtocolText = 0,
eProtocolTraffic = 1
};
struct ProtocolMessage : public llarp::IBEncodeMessage
{
ProtocolMessage(ProtocolType t);
~ProtocolMessage();
ProtocolType proto;
llarp_time_t queued = 0;
std::vector< byte_t > payload;
llarp::KeyExchangeNonce N;
bool
DecodeKey(llarp_buffer_t key, llarp_buffer_t* val);
bool
BEncode(llarp_buffer_t* buf) const;
void
PutBuffer(llarp_buffer_t payload);
struct GetTime
{
llarp_time_t
operator()(const ProtocolMessage* msg) const
{
return msg->queued;
}
};
struct PutTime
{
void
operator()(ProtocolMessage* msg, llarp_time_t now) const
{
msg->queued = now;
}
};
};
} // namespace service
} // namespace llarp
#endif

@ -81,12 +81,20 @@ namespace llarp
};
void
Context::PropagateIntroSetTo(const service::IntroSet &introset,
Context::PropagateIntroSetTo(const Key_t &from, uint64_t txid,
const service::IntroSet &introset,
const Key_t &peer, uint64_t S)
{
llarp::LogInfo("Propagate Introset for ", introset.A, " to ", peer);
auto id = ++ids;
auto msg = new llarp::DHTImmeidateMessage(peer);
llarp::LogInfo("Propagate Introset for ", introset.A.Name(), " to ",
peer);
auto id = ++ids;
TXOwner ownerKey;
ownerKey.node = peer;
ownerKey.txid = id;
SearchJob job(from, txid, [](const std::set< service::IntroSet > &) {});
pendingTX[ownerKey] = job;
auto msg = new llarp::DHTImmeidateMessage(peer);
msg->msgs.push_back(new PublishIntroMessage(introset, id, S));
router->SendToOrQueue(peer, msg);
}

@ -10,12 +10,8 @@ namespace llarp
{
GotIntroMessage::GotIntroMessage(
const std::set< llarp::service::IntroSet > &results, uint64_t tx)
: IMessage({}), T(tx)
: IMessage({}), I(results), T(tx)
{
for(const auto &i : results)
{
I.push_back(i);
}
}
GotIntroMessage::~GotIntroMessage()
@ -86,7 +82,7 @@ namespace llarp
{
if(llarp_buffer_eq(key, "I"))
{
return BEncodeReadList(I, buf);
return BEncodeReadSet(I, buf);
}
bool read = false;
if(!BEncodeMaybeReadDictInt("T", T, read, key, buf))

@ -17,6 +17,10 @@ namespace llarp
PublishIntroMessage::DecodeKey(llarp_buffer_t key, llarp_buffer_t *val)
{
bool read = false;
if(llarp_buffer_eq(key, "E"))
{
return BEncodeReadSet(E, val);
}
if(!BEncodeMaybeReadDictEntry("I", I, read, key, val))
return false;
if(!BEncodeMaybeReadDictInt("R", R, read, key, val))
@ -65,10 +69,11 @@ namespace llarp
dht.services->PutNode(I);
replies.push_back(new GotIntroMessage({I}, txID));
Key_t peer;
std::set< Key_t > exclude = {dht.OurKey(), From};
std::set< Key_t > exclude = E;
exclude.insert(From);
if(S && dht.nodes->FindCloseExcluding(addr, peer, exclude))
{
dht.PropagateIntroSetTo(I, peer, S - 1);
dht.PropagateIntroSetTo(From, txID, I, peer, S - 1);
}
return true;
}
@ -80,6 +85,8 @@ namespace llarp
return false;
if(!BEncodeWriteDictMsgType(buf, "A", "I"))
return false;
if(!BEncodeWriteDictList("E", E, buf))
return false;
if(!BEncodeWriteDictEntry("I", I, buf))
return false;
if(!BEncodeWriteDictInt(buf, "R", R))

@ -5,6 +5,7 @@
#include "buffer.hpp"
#include "llarp/crypto.hpp"
#include "llarp/logger.hpp"
#include "mem.hpp"
#include "router.hpp"
llarp_router *
@ -26,10 +27,12 @@ frame_state::process_inbound_queue()
// TODO: is this right?
auto &front = q.top();
// the items are already sorted anyways so this doesn't really do much
nextMsgID = std::max(nextMsgID, front->msgid);
if(!Router()->HandleRecvLinkMessage(parent, front->Buffer()))
nextMsgID = std::max(nextMsgID, front->msgid);
auto buffer = front->Buffer();
if(!Router()->HandleRecvLinkMessage(parent, buffer))
{
llarp::LogWarn("failed to process inbound message ", front->msgid);
llarp::DumpBuffer< llarp_buffer_t, 128 >(buffer);
}
delete front;
q.pop();
@ -88,11 +91,13 @@ frame_state::got_xmit(frame_header hdr, size_t sz)
if(x.flags() & 0x01)
{
auto id = x.msgid();
auto itr = rx.find(id);
auto h = x.hash();
auto itr = rx.find(h);
if(itr == rx.end())
{
auto msg = new transit_message(x);
rx[id] = msg;
auto msg = new transit_message(x);
rx[h] = msg;
rxIDs[id] = h;
llarp::LogDebug("got message XMIT with ", (int)x.numfrags(),
" fragment"
"s");
@ -106,7 +111,7 @@ frame_state::got_xmit(frame_header hdr, size_t sz)
return true;
}
else
llarp::LogWarn("duplicate XMIT msgid=", x.msgid());
llarp::LogWarn("duplicate XMIT h=", h);
}
else
llarp::LogWarn("LSB not set on flags");
@ -137,8 +142,13 @@ frame_state::got_frag(frame_header hdr, size_t sz)
// TODO: implement little endian
memcpy(&msgid, hdr.data(), 8);
memcpy(&fragno, hdr.data() + 8, 1);
auto itr = rx.find(msgid);
auto idItr = rxIDs.find(msgid);
if(idItr == rxIDs.end())
{
llarp::LogWarn("no such RX fragment, msgid=", msgid);
return true;
}
auto itr = rx.find(idItr->second);
if(itr == rx.end())
{
llarp::LogWarn("no such RX fragment, msgid=", msgid);
@ -186,12 +196,12 @@ frame_state::inbound_frame_complete(uint64_t id)
{
bool success = false;
std::vector< byte_t > msg;
auto rxmsg = rx[id];
auto rxmsg = rx[rxIDs[id]];
llarp::ShortHash digest;
if(rxmsg->reassemble(msg))
{
auto router = Router();
llarp::ShortHash digest;
auto buf = llarp::Buffer< decltype(msg) >(msg);
auto buf = llarp::Buffer< decltype(msg) >(msg);
router->crypto.shorthash(digest, buf);
if(memcmp(digest, rxmsg->msginfo.hash(), 32))
{
@ -231,7 +241,8 @@ frame_state::inbound_frame_complete(uint64_t id)
}
delete rxmsg;
rx.erase(id);
rxIDs.erase(id);
rx.erase(digest);
if(!success)
llarp::LogWarn("Failed to process inbound message ", id);
@ -297,7 +308,7 @@ frame_state::process(byte_t *buf, size_t sz)
switch(hdr.msgtype())
{
case eALIV:
llarp::LogDebug("iwp_link::frame_state::process Got alive");
// llarp::LogDebug("iwp_link::frame_state::process Got alive");
if(rxflags & eSessionInvalidated)
{
txflags |= eSessionInvalidated;

@ -20,7 +20,6 @@ static void
handle_frame_encrypt(iwp_async_frame *frame)
{
llarp_link_session *self = static_cast< llarp_link_session * >(frame->user);
llarp::LogDebug("tx ", frame->sz);
if(llarp_ev_udp_sendto(self->udp, self->addr, frame->buf, frame->sz) == -1)
llarp::LogWarn("sendto failed");
}
@ -212,18 +211,18 @@ static void
handle_generated_session_start(iwp_async_session_start *start)
{
llarp_link_session *link = static_cast< llarp_link_session * >(start->user);
link->working = false;
if(llarp_ev_udp_sendto(link->udp, link->addr, start->buf, start->sz) == -1)
llarp::LogError("sendto failed");
link->EnterState(llarp_link_session::State::eSessionStartSent);
link->serv->remove_intro_from(link->addr);
link->working = false;
}
static void
handle_verify_intro(iwp_async_intro *intro)
{
llarp_link_session *self = static_cast< llarp_link_session * >(intro->user);
self->working = false;
if(!intro->buf)
{
self->serv->remove_intro_from(self->addr);
@ -490,23 +489,24 @@ 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);
self->working = false;
if(!s->buf)
{
// verify fail
// TODO: remove session?
llarp::LogWarn("session start verify failed from ", self->addr);
self->serv->RemoveSessionByAddr(self->addr);
return;
}
self->send_LIM();
self->working = false;
}
static void
handle_introack_generated(iwp_async_introack *i)
{
llarp_link_session *link = static_cast< llarp_link_session * >(i->user);
link->working = false;
if(i->buf && link->serv->has_intro_from(link->addr))
{
// track it with the server here
@ -514,6 +514,7 @@ handle_introack_generated(iwp_async_introack *i)
{
// duplicate session
llarp::LogWarn("duplicate session to ", link->addr);
link->working = false;
return;
}
link->frame.alive();
@ -527,6 +528,7 @@ handle_introack_generated(iwp_async_introack *i)
// failed to generate?
llarp::LogWarn("failed to generate introack");
}
link->working = false;
}
static void
@ -586,7 +588,6 @@ void
llarp_link_session::handle_frame_decrypt(iwp_async_frame *frame)
{
llarp_link_session *self = static_cast< llarp_link_session * >(frame->user);
llarp::LogDebug("rx ", frame->sz);
if(frame->success)
{
if(self->frame.process(frame->buf + 64, frame->sz - 64))
@ -701,7 +702,6 @@ llarp_link_session::intro_ack()
// call
introack.user = this;
introack.hook = &handle_introack_generated;
working = true;
iwp_call_async_gen_introack(iwp, &introack);
}
@ -738,11 +738,12 @@ llarp_link_session::recv(const void *buf, size_t sz)
case eLIMSent:
case eEstablished:
// session is started
/*
llarp::LogDebug("session recv - ",
state == eSessionStartSent ? "startsent" : "",
state == eLIMSent ? "limset" : "",
state == eEstablished ? "established" : "");
*/
decrypt_frame(buf, sz);
break;
default:

@ -2,7 +2,8 @@
#define LLARP_MEM_HPP
#include <llarp/buffer.h>
#include <llarp/mem.h>
#include <stdio.h>
#include <cctype>
#include <cstdio>
namespace llarp
{
@ -36,9 +37,9 @@ namespace llarp
}
else
{
printf("%c[0m", 27);
printf("%c[0;0m", 27);
}
if(buff.base[idx])
if(std::isprint(buff.base[idx]))
{
printf("%c", buff.base[idx]);
}

@ -90,7 +90,7 @@ namespace llarp
bool
PathSet::GetCurrentIntroductions(
std::list< llarp::service::Introduction >& intros) const
std::set< llarp::service::Introduction >& intros) const
{
intros.clear();
size_t count = 0;
@ -99,7 +99,7 @@ namespace llarp
{
if(itr->second->IsReady())
{
intros.push_back(itr->second->intro);
intros.insert(itr->second->intro);
++count;
}
++itr;

@ -22,7 +22,7 @@ namespace llarp
if(llarp_buffer_eq(key, "i"))
{
return BEncodeReadList(I, buf);
return BEncodeReadSet(I, buf);
}
if(!BEncodeMaybeReadDictEntry("n", topic, read, key, buf))

@ -1,6 +1,8 @@
#include <llarp/dht/messages/findintro.hpp>
#include <llarp/messages/dht.hpp>
#include <llarp/service/endpoint.hpp>
#include <llarp/service/protocol.hpp>
#include "buffer.hpp"
#include "router.hpp"
namespace llarp
@ -32,12 +34,39 @@ namespace llarp
return true;
}
struct PathAlignJob
{
Address remote;
PathAlignJob(const Address& addr) : remote(addr)
{
}
void
HandleResult(Endpoint::OutboundContext* context)
{
if(context)
{
byte_t tmp[128] = {0};
memcpy(tmp, "BEEP", 4);
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
context->AsyncEncryptAndSendTo(buf, eProtocolText);
}
else
{
llarp::LogWarn("PathAlignJob timed out");
delete this;
}
}
};
void
Endpoint::Tick(llarp_time_t now)
{
// publish descriptors
if(ShouldPublishDescriptors(now))
{
std::list< Introduction > I;
std::set< Introduction > I;
if(!GetCurrentIntroductions(I))
{
llarp::LogWarn("could not publish descriptors for endpoint ", Name(),
@ -60,12 +89,24 @@ namespace llarp
llarp::LogWarn("failed to publish intro set for endpoint ", Name());
}
}
// prefetch tags
for(const auto& tag : m_PrefetchTags)
{
auto itr = m_PrefetchedTags.find(tag);
if(itr == m_PrefetchedTags.end())
{
itr = m_PrefetchedTags.emplace(tag, tag).first;
itr = m_PrefetchedTags
.insert(std::make_pair(tag, CachedTagResult(tag, now)))
.first;
}
for(const auto& introset : itr->second.result)
{
PathAlignJob* j = new PathAlignJob(introset.A.Addr());
if(!EnsurePathToService(j->remote,
std::bind(&PathAlignJob::HandleResult, j,
std::placeholders::_1),
10000))
delete j;
}
itr->second.Expire(now);
if(itr->second.ShouldRefresh(now))
@ -107,13 +148,13 @@ namespace llarp
{
llarp::LogInfo("invalid introset signature for ", introset,
" on endpoint ", Name());
if(m_Identity.pub == introset.A)
if(m_Identity.pub == introset.A && m_CurrentPublishTX == msg->T)
{
IntroSetPublishFail();
}
return false;
}
if(m_Identity.pub == introset.A)
if(m_Identity.pub == introset.A && m_CurrentPublishTX == msg->T)
{
llarp::LogInfo(
"got introset publish confirmation for hidden service endpoint ",
@ -167,12 +208,16 @@ namespace llarp
Endpoint::CachedTagResult::HandleResponse(
const std::set< IntroSet >& introsets)
{
llarp::LogInfo("Tag result for ", tag.ToString(), " got ",
introsets.size(), " results");
lastModified = llarp_time_now_ms();
pendingTX = 0;
auto now = llarp_time_now_ms();
pendingTX = 0;
for(const auto& introset : introsets)
result.insert(introset);
if(result.insert(introset).second)
lastModified = now;
llarp::LogInfo("Tag result for ", tag.ToString(), " got ",
introsets.size(), " results from lookup, have ",
result.size(), " cached last modified at ", lastModified,
" is ", now - lastModified, "ms old");
return true;
}
@ -184,7 +229,9 @@ namespace llarp
{
if(itr->HasExpiredIntros(now))
{
itr = result.erase(itr);
llarp::LogInfo("Removing expired tag Entry ", itr->A.Name());
itr = result.erase(itr);
lastModified = now;
}
else
{
@ -198,6 +245,7 @@ namespace llarp
{
llarp::routing::DHTMessage* msg = new llarp::routing::DHTMessage();
msg->M.push_back(new llarp::dht::FindIntroMessage(tag, pendingTX));
lastRequest = llarp_time_now_ms();
return msg;
}
@ -247,8 +295,17 @@ namespace llarp
llarp::LogInfo(Name(), " IntroSet publish confirmed");
}
bool
Endpoint::EnsurePathToService(const Address& remote, PathEnsureHook hook,
llarp_time_t timeoutMS)
{
// TODO: implement me
return false;
}
Endpoint::OutboundContext::OutboundContext(Endpoint* parent)
: llarp_pathbuilder_context(parent->m_Router, parent->m_Router->dht, 2)
, m_SendQueue(parent->Name() + "::outbound_queue")
, m_Parent(parent)
{
}
@ -265,5 +322,105 @@ namespace llarp
return false;
}
void
Endpoint::OutboundContext::AsyncEncryptAndSendTo(llarp_buffer_t data,
ProtocolType protocol)
{
auto sendto =
std::bind(&OutboundContext::SendMessage, this, std::placeholders::_1);
ProtocolMessage* msg = new ProtocolMessage(protocol);
msg->PutBuffer(data);
if(sequenceNo)
{
AsyncEncrypt(msg, sendto);
}
else
{
AsyncGenIntro(msg, sendto);
}
}
struct AsyncKeyExchange
{
llarp_logic* logic;
llarp_crypto* crypto;
byte_t* sharedKey;
byte_t* remotePubkey;
byte_t* localSeckey;
byte_t* nonce;
ProtocolMessage* msg = nullptr;
std::function< void(ProtocolMessage*) > hook;
AsyncKeyExchange(llarp_logic* l, llarp_crypto* c, byte_t* key,
byte_t* remote, byte_t* localSecret, byte_t* n)
: logic(l)
, crypto(c)
, sharedKey(key)
, remotePubkey(remote)
, localSeckey(localSecret)
, nonce(n)
{
}
static void
Work(void* user)
{
AsyncKeyExchange* self = static_cast< AsyncKeyExchange* >(user);
self->crypto->dh_server(self->sharedKey, self->remotePubkey,
self->localSeckey, self->nonce);
}
};
void
Endpoint::OutboundContext::AsyncGenIntro(
ProtocolMessage* msg, std::function< void(ProtocolMessage*) > result)
{
msg->N.Randomize();
AsyncKeyExchange* ex = new AsyncKeyExchange(
m_Parent->Logic(), m_Parent->Crypto(), sharedKey,
currentIntroSet.A.enckey, m_Parent->GetEncryptionSecretKey(), msg->N);
llarp_threadpool_queue_job(m_Parent->Worker(),
{ex, &AsyncKeyExchange::Work});
}
void
Endpoint::OutboundContext::SendMessage(ProtocolMessage* msg)
{
// TODO: delete msg
// TODO: implement me
}
void
Endpoint::OutboundContext::AsyncEncrypt(
ProtocolMessage* msg, std::function< void(ProtocolMessage*) > result)
{
// TODO: implement me
}
llarp_logic*
Endpoint::Logic()
{
return m_Router->logic;
}
llarp_crypto*
Endpoint::Crypto()
{
return &m_Router->crypto;
}
llarp_threadpool*
Endpoint::Worker()
{
return m_Router->tp;
}
byte_t*
Endpoint::GetEncryptionSecretKey()
{
return m_Identity.enckey;
}
} // namespace service
} // namespace llarp

@ -0,0 +1,36 @@
#include <llarp/service/protocol.hpp>
namespace llarp
{
namespace service
{
ProtocolMessage::ProtocolMessage(ProtocolType t) : proto(t)
{
}
ProtocolMessage::~ProtocolMessage()
{
}
bool
ProtocolMessage::BEncode(llarp_buffer_t* buf) const
{
// TODO: implement me
return false;
}
bool
ProtocolMessage::DecodeKey(llarp_buffer_t key, llarp_buffer_t* val)
{
// TODO: implement me
return false;
}
void
ProtocolMessage::PutBuffer(llarp_buffer_t buf)
{
payload.resize(buf.sz);
memcpy(payload.data(), buf.base, buf.sz);
}
} // namespace service
} // namespace llarp

@ -3,7 +3,7 @@
namespace llarp
{
typedef std::chrono::steady_clock clock_t;
typedef std::chrono::system_clock clock_t;
template < typename Res, typename IntType >
static IntType

@ -36,7 +36,7 @@ TEST_F(HiddenServiceTest, TestGenerateIntroSet)
intro.expiresAt = 1000;
intro.router.Randomize();
intro.pathID.Randomize();
I.I.push_back(intro);
I.I.insert(intro);
}
ASSERT_TRUE(ident.SignIntroSet(I, Crypto()));
ASSERT_TRUE(I.VerifySignature(Crypto()));

Loading…
Cancel
Save