mirror of https://github.com/oxen-io/lokinet
more hidden service stuff
This commit is contained in:
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…
Reference in New Issue