mirror of https://github.com/oxen-io/lokinet
parent
b122fc59f8
commit
5228a81bae
|
@ -3,7 +3,7 @@
|
|||
#include <signal.h>
|
||||
#include "logger.hpp"
|
||||
|
||||
#include <llarp/router_contact.h>
|
||||
#include <llarp/router_contact.hpp>
|
||||
#include <llarp/time.h>
|
||||
|
||||
#include <fstream>
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
#include <llarp/ev.h>
|
||||
#include <llarp/logic.h>
|
||||
#include <llarp/mem.h>
|
||||
#include <llarp/nodedb.h>
|
||||
#include <llarp/router.h>
|
||||
#include <llarp/version.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <llarp/threading.hpp>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <llarp/crypto.h>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
#ifndef LLARP_AI_HPP
|
||||
#define LLARP_AI_HPP
|
||||
#include <llarp/mem.h>
|
||||
#include <llarp/net.h>
|
||||
#include <stdbool.h>
|
||||
#include <llarp/crypto.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
* address_info.hpp
|
||||
*
|
||||
* utilities for handling addresses on the llarp network
|
||||
*/
|
||||
|
||||
/// address information model
|
||||
namespace llarp
|
||||
{
|
||||
struct AddressInfo
|
||||
{
|
||||
uint16_t rank;
|
||||
std::string dialect;
|
||||
llarp::PubKey pubkey;
|
||||
struct in6_addr ip;
|
||||
uint16_t port;
|
||||
|
||||
bool
|
||||
BEncode(llarp_buffer_t *buf) const;
|
||||
|
||||
bool
|
||||
BDecode(llarp_buffer_t *buf);
|
||||
};
|
||||
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
|
@ -38,6 +38,20 @@ namespace llarp
|
|||
return bencode_write_bytestring(buf, k, 1) && bencode_write_uint64(buf, i);
|
||||
}
|
||||
|
||||
template < typename List_t >
|
||||
bool
|
||||
BEncodeMaybeReadDictList(const char* k, List_t& item, bool& read,
|
||||
llarp_buffer_t key, llarp_buffer_t* buf)
|
||||
{
|
||||
if(llarp_buffer_eq(key, k))
|
||||
{
|
||||
if(!BEncodeReadList(item, buf))
|
||||
return false;
|
||||
read = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template < typename Item_t >
|
||||
bool
|
||||
BEncodeMaybeReadDictEntry(const char* k, Item_t& item, bool& read,
|
||||
|
@ -105,6 +119,43 @@ namespace llarp
|
|||
return bencode_end(buf);
|
||||
}
|
||||
|
||||
template < typename Array >
|
||||
bool
|
||||
BEncodeWriteDictArray(const char* k, const Array& array, llarp_buffer_t* buf)
|
||||
{
|
||||
if(!bencode_write_bytestring(buf, k, 1))
|
||||
return false;
|
||||
if(!bencode_start_list(buf))
|
||||
return false;
|
||||
|
||||
for(size_t idx = 0; idx < array.size(); ++idx)
|
||||
if(!array[idx].BEncode(buf))
|
||||
return false;
|
||||
return bencode_end(buf);
|
||||
}
|
||||
|
||||
template < typename Array >
|
||||
bool
|
||||
BEncodeReadArray(Array& array, llarp_buffer_t* buf)
|
||||
{
|
||||
if(*buf->cur != 'l') // ensure is a list
|
||||
return false;
|
||||
|
||||
buf->cur++;
|
||||
size_t idx = 0;
|
||||
while(llarp_buffer_size_left(*buf) && *buf->cur != 'e')
|
||||
{
|
||||
if(idx >= array.size())
|
||||
return false;
|
||||
if(!array[idx++].BDecode(buf))
|
||||
return false;
|
||||
}
|
||||
if(*buf->cur != 'e') // make sure we're at a list end
|
||||
return false;
|
||||
buf->cur++;
|
||||
return true;
|
||||
}
|
||||
|
||||
template < typename Iter >
|
||||
bool
|
||||
BEncodeWriteList(Iter itr, Iter end, llarp_buffer_t* buf)
|
||||
|
@ -212,4 +263,4 @@ namespace llarp
|
|||
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -24,39 +24,13 @@ llarp_dht_context_free(struct llarp_dht_context* dht);
|
|||
void
|
||||
llarp_dht_context_start(struct llarp_dht_context* ctx, const byte_t* key);
|
||||
|
||||
struct llarp_router_lookup_job;
|
||||
|
||||
typedef void (*llarp_router_lookup_handler)(struct llarp_router_lookup_job*);
|
||||
|
||||
struct llarp_router_lookup_job
|
||||
{
|
||||
/// can be anything but usually a class context for hook
|
||||
void* user;
|
||||
llarp_router_lookup_handler hook;
|
||||
struct llarp_dht_context* dht;
|
||||
byte_t target[PUBKEYSIZE];
|
||||
bool found;
|
||||
// make sure you initialize addr and exits
|
||||
struct llarp_rc result;
|
||||
bool iterative;
|
||||
};
|
||||
|
||||
/// start allowing dht participation on a context
|
||||
void
|
||||
llarp_dht_allow_transit(struct llarp_dht_context* ctx);
|
||||
|
||||
/// put router as a dht peer
|
||||
/// internal function do not use
|
||||
void
|
||||
__llarp_dht_put_peer(struct llarp_dht_context* ctx, struct llarp_rc* rc);
|
||||
|
||||
/// remove router from tracked dht peer list
|
||||
/// internal function do not use
|
||||
void
|
||||
__llarp_dht_remove_peer(struct llarp_dht_context* ctx, const byte_t* id);
|
||||
|
||||
void
|
||||
llarp_dht_lookup_router(struct llarp_dht_context* ctx,
|
||||
struct llarp_router_lookup_job* job);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -106,6 +106,9 @@ namespace llarp
|
|||
typedef std::function< void(const std::vector< service::IntroSet >&) >
|
||||
IntroSetLookupHandler;
|
||||
|
||||
typedef std::function< void(const std::vector< RouterContact >&) >
|
||||
RouterLookupHandler;
|
||||
|
||||
struct Context
|
||||
{
|
||||
Context();
|
||||
|
@ -130,7 +133,17 @@ namespace llarp
|
|||
void
|
||||
LookupRouterRecursive(const RouterID& target, const Key_t& whoasked,
|
||||
uint64_t whoaskedTX, const Key_t& askpeer,
|
||||
llarp_router_lookup_job* job = nullptr);
|
||||
RouterLookupHandler result = nullptr);
|
||||
|
||||
bool
|
||||
LookupRouter(const RouterID& target, RouterLookupHandler result)
|
||||
{
|
||||
Key_t askpeer;
|
||||
if(!nodes->FindClosest(target.data(), askpeer))
|
||||
return false;
|
||||
LookupRouterRecursive(target, OurKey(), 0, askpeer, result);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// on behalf of whoasked request introsets with tag from dht router with
|
||||
/// key askpeer with Recursion depth R
|
||||
|
@ -138,14 +151,16 @@ namespace llarp
|
|||
LookupTagRecursive(const service::Tag& tag, const Key_t& whoasked,
|
||||
uint64_t whoaskedTX, const Key_t& askpeer, uint64_t R);
|
||||
|
||||
void
|
||||
LookupRouterViaJob(llarp_router_lookup_job* job);
|
||||
|
||||
/// issue dht lookup for tag via askpeer and send reply to local path
|
||||
void
|
||||
LookupTagForPath(const service::Tag& tag, uint64_t txid,
|
||||
const llarp::PathID_t& path, const Key_t& askpeer);
|
||||
|
||||
/// issue dht lookup for router via askpeer and send reply to local path
|
||||
void
|
||||
LookupRouterForPath(const RouterID& target, uint64_t txid,
|
||||
const llarp::PathID_t& path, const Key_t& askpeer);
|
||||
|
||||
/// issue dht lookup for introset for addr via askpeer and send reply to
|
||||
/// local path
|
||||
void
|
||||
|
@ -193,10 +208,6 @@ namespace llarp
|
|||
const llarp::service::IntroSet*
|
||||
GetIntroSetByServiceAddress(const llarp::service::Address& addr) const;
|
||||
|
||||
/// queue lookup router via job
|
||||
void
|
||||
QueueRouterLookup(llarp_router_lookup_job* job);
|
||||
|
||||
static void
|
||||
handle_cleaner_timer(void* user, uint64_t orig, uint64_t left);
|
||||
|
||||
|
@ -207,9 +218,6 @@ namespace llarp
|
|||
void
|
||||
Explore();
|
||||
|
||||
static void
|
||||
queue_router_lookup(void* user);
|
||||
|
||||
llarp_router* router = nullptr;
|
||||
// for router contacts
|
||||
Bucket< RCNode >* nodes = nullptr;
|
||||
|
@ -340,7 +348,7 @@ namespace llarp
|
|||
TXHolder< service::Tag, service::IntroSet, service::Tag::Hash >
|
||||
pendingTagLookups;
|
||||
|
||||
TXHolder< RouterID, llarp_rc, RouterID::Hash > pendingRouterLookups;
|
||||
TXHolder< RouterID, RouterContact, RouterID::Hash > pendingRouterLookups;
|
||||
|
||||
TXHolder< RouterID, RouterID, RouterID::Hash > pendingExploreLookups;
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef LLARP_DHT_MESSAGES_GOT_ROUTER_HPP
|
||||
#define LLARP_DHT_MESSAGES_GOT_ROUTER_HPP
|
||||
#include <llarp/dht/message.hpp>
|
||||
#include <llarp/router_contact.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
|
@ -12,16 +13,11 @@ namespace llarp
|
|||
: IMessage(from), relayed(tunneled)
|
||||
{
|
||||
}
|
||||
GotRouterMessage(const Key_t& from, uint64_t id, const llarp_rc* result,
|
||||
GotRouterMessage(const Key_t& from, uint64_t id,
|
||||
const std::vector< RouterContact >& results,
|
||||
bool tunneled)
|
||||
: IMessage(from), txid(id), relayed(tunneled)
|
||||
: IMessage(from), R(results), txid(id), relayed(tunneled)
|
||||
{
|
||||
if(result)
|
||||
{
|
||||
R.emplace_back();
|
||||
llarp_rc_clear(&R.back());
|
||||
llarp_rc_copy(&R.back(), result);
|
||||
}
|
||||
}
|
||||
|
||||
GotRouterMessage(uint64_t id, const std::vector< RouterID >& near,
|
||||
|
@ -42,7 +38,7 @@ namespace llarp
|
|||
HandleMessage(llarp_dht_context* ctx,
|
||||
std::vector< IMessage* >& replies) const;
|
||||
|
||||
std::vector< llarp_rc > R;
|
||||
std::vector< RouterContact > R;
|
||||
std::vector< RouterID > N;
|
||||
uint64_t txid = 0;
|
||||
uint64_t version = 0;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef LLARP_DHT_NODE_HPP
|
||||
#define LLARP_DHT_NODE_HPP
|
||||
|
||||
#include <llarp/router_contact.h>
|
||||
#include <llarp/router_contact.hpp>
|
||||
#include <llarp/dht/key.hpp>
|
||||
#include <llarp/service/IntroSet.hpp>
|
||||
|
||||
|
@ -11,18 +11,19 @@ namespace llarp
|
|||
{
|
||||
struct RCNode
|
||||
{
|
||||
llarp_rc* rc;
|
||||
llarp::RouterContact rc;
|
||||
|
||||
Key_t ID;
|
||||
|
||||
RCNode() : rc(nullptr)
|
||||
RCNode()
|
||||
{
|
||||
ID.Zero();
|
||||
}
|
||||
|
||||
RCNode(llarp_rc* other) : rc(other)
|
||||
RCNode(const llarp::RouterContact& other)
|
||||
{
|
||||
ID = other->pubkey;
|
||||
rc = other;
|
||||
ID = other.pubkey.data();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -47,4 +48,4 @@ namespace llarp
|
|||
} // namespace dht
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -5,12 +5,15 @@
|
|||
#include <llarp/buffer.h>
|
||||
#include <sodium.h>
|
||||
#include <vector>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
/// encrypted buffer base type
|
||||
struct Encrypted
|
||||
{
|
||||
static const size_t MAX_SIZE = (1024 * 8);
|
||||
|
||||
Encrypted(Encrypted&&) = delete;
|
||||
Encrypted(const Encrypted& other);
|
||||
Encrypted();
|
||||
|
@ -31,15 +34,13 @@ namespace llarp
|
|||
}
|
||||
|
||||
Encrypted&
|
||||
operator=(llarp_buffer_t buf)
|
||||
operator=(const llarp_buffer_t& buf)
|
||||
{
|
||||
if(_data)
|
||||
delete[] _data;
|
||||
_data = nullptr;
|
||||
_sz = buf.sz;
|
||||
if(buf.sz > MAX_SIZE)
|
||||
return *this;
|
||||
_sz = buf.sz;
|
||||
if(_sz)
|
||||
{
|
||||
_data = new byte_t[_sz];
|
||||
memcpy(_data, buf.base, _sz);
|
||||
}
|
||||
UpdateBuffer();
|
||||
|
@ -69,10 +70,9 @@ namespace llarp
|
|||
return false;
|
||||
if(strbuf.sz == 0)
|
||||
return false;
|
||||
if(_data)
|
||||
delete[] _data;
|
||||
_sz = strbuf.sz;
|
||||
_data = new byte_t[_sz];
|
||||
if(strbuf.sz > MAX_SIZE)
|
||||
return false;
|
||||
_sz = strbuf.sz;
|
||||
memcpy(_data, strbuf.base, _sz);
|
||||
UpdateBuffer();
|
||||
return true;
|
||||
|
@ -116,10 +116,10 @@ namespace llarp
|
|||
m_Buffer.cur = data();
|
||||
m_Buffer.sz = size();
|
||||
}
|
||||
byte_t* _data = nullptr;
|
||||
size_t _sz = 0;
|
||||
byte_t _data[MAX_SIZE];
|
||||
size_t _sz = 0;
|
||||
llarp_buffer_t m_Buffer;
|
||||
};
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -33,10 +33,9 @@ namespace llarp
|
|||
EncryptedFrame&
|
||||
operator=(const EncryptedFrame& other)
|
||||
{
|
||||
if(_data)
|
||||
delete[] _data;
|
||||
_sz = other._sz;
|
||||
_data = new byte_t[_sz];
|
||||
if(other._sz > MAX_SIZE)
|
||||
throw std::logic_error("encrypted frame too big");
|
||||
_sz = other._sz;
|
||||
memcpy(_data, other._data, _sz);
|
||||
return *this;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
#ifndef LLARP_XI_HPP
|
||||
#define LLARP_XI_HPP
|
||||
#include <llarp/buffer.h>
|
||||
#include <llarp/crypto.hpp>
|
||||
#include <llarp/net.h>
|
||||
#include <iostream>
|
||||
#include <llarp/bits.hpp>
|
||||
|
||||
/**
|
||||
* exit_info.h
|
||||
*
|
||||
* utilities for handling exits on the llarp network
|
||||
*/
|
||||
|
||||
/// Exit info model
|
||||
namespace llarp
|
||||
{
|
||||
struct ExitInfo
|
||||
{
|
||||
struct in6_addr address;
|
||||
struct in6_addr netmask;
|
||||
PubKey pubkey;
|
||||
|
||||
bool
|
||||
BEncode(llarp_buffer_t *buf) const;
|
||||
|
||||
bool
|
||||
BDecode(llarp_buffer_t *buf);
|
||||
|
||||
friend std::ostream &
|
||||
operator<<(std::ostream &out, const ExitInfo &xi)
|
||||
{
|
||||
char tmp[128] = {0};
|
||||
if(inet_ntop(AF_INET6, &xi.address, tmp, sizeof(tmp)))
|
||||
out << std::string(tmp);
|
||||
else
|
||||
return out;
|
||||
out << std::string("/");
|
||||
return out << std::to_string(
|
||||
llarp::bits::count_array_bits(xi.netmask.s6_addr));
|
||||
}
|
||||
};
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "llarp/address_info.h"
|
||||
#include "llarp/address_info.hpp"
|
||||
|
||||
struct llarp_link;
|
||||
struct llarp_link_session;
|
||||
|
@ -9,13 +9,13 @@ struct llarp_link_establish_job
|
|||
{
|
||||
void *user;
|
||||
void (*result)(struct llarp_link_establish_job *);
|
||||
struct llarp_ai ai;
|
||||
llarp::AddressInfo ai;
|
||||
uint64_t timeout;
|
||||
uint16_t retries;
|
||||
|
||||
byte_t pubkey[PUBKEYSIZE];
|
||||
llarp::PubKey pubkey;
|
||||
/** set on success by try_establish */
|
||||
struct llarp_link *link;
|
||||
/** set on success by try_establish */
|
||||
struct llarp_link_session *session;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -86,7 +86,7 @@ struct frame_state
|
|||
clear();
|
||||
|
||||
bool
|
||||
inbound_frame_complete(uint64_t id);
|
||||
inbound_frame_complete(const std::unique_ptr< transit_message > &msg);
|
||||
|
||||
void
|
||||
push_ackfor(uint64_t id, uint32_t bitmask);
|
||||
|
|
|
@ -9,12 +9,26 @@
|
|||
struct InboundMessage
|
||||
{
|
||||
uint64_t msgid;
|
||||
std::vector< byte_t > msg;
|
||||
byte_t *_buf;
|
||||
size_t sz;
|
||||
llarp_time_t queued = 0;
|
||||
|
||||
InboundMessage(uint64_t id, const std::vector< byte_t > &m)
|
||||
: msgid(id), msg(m)
|
||||
InboundMessage(uint64_t id, const std::vector< byte_t > &m) : msgid(id)
|
||||
{
|
||||
sz = m.size();
|
||||
if(sz)
|
||||
{
|
||||
_buf = new byte_t[sz];
|
||||
memcpy(_buf, m.data(), sz);
|
||||
}
|
||||
else
|
||||
_buf = nullptr;
|
||||
}
|
||||
|
||||
~InboundMessage()
|
||||
{
|
||||
if(_buf)
|
||||
delete[] _buf;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -27,7 +41,7 @@ struct InboundMessage
|
|||
llarp_buffer_t
|
||||
Buffer() const
|
||||
{
|
||||
return llarp::ConstBuffer< decltype(msg) >(msg);
|
||||
return llarp::InitBuffer(_buf, sz);
|
||||
}
|
||||
|
||||
struct GetTime
|
||||
|
|
|
@ -7,25 +7,35 @@
|
|||
|
||||
struct sendbuf_t
|
||||
{
|
||||
sendbuf_t(size_t s) : sz(s)
|
||||
sendbuf_t()
|
||||
{
|
||||
_buf = new byte_t[s];
|
||||
_sz = 0;
|
||||
}
|
||||
|
||||
sendbuf_t(sendbuf_t &&other)
|
||||
{
|
||||
if(other._sz > sizeof(_buf))
|
||||
throw std::logic_error("sendbuf too big");
|
||||
memcpy(_buf, other._buf, other._sz);
|
||||
_sz = other._sz;
|
||||
other._sz = 0;
|
||||
}
|
||||
|
||||
sendbuf_t(size_t s)
|
||||
{
|
||||
if(s > sizeof(_buf))
|
||||
throw std::logic_error("sendbuf too big");
|
||||
_sz = s;
|
||||
}
|
||||
|
||||
~sendbuf_t()
|
||||
{
|
||||
if(_buf)
|
||||
delete[] _buf;
|
||||
}
|
||||
|
||||
size_t sz;
|
||||
|
||||
byte_t priority = 255;
|
||||
|
||||
size_t
|
||||
size() const
|
||||
{
|
||||
return sz;
|
||||
return _sz;
|
||||
}
|
||||
|
||||
byte_t *
|
||||
|
@ -39,7 +49,7 @@ struct sendbuf_t
|
|||
{
|
||||
llarp_buffer_t buf;
|
||||
buf.base = _buf;
|
||||
buf.sz = sz;
|
||||
buf.sz = _sz;
|
||||
buf.cur = buf.base;
|
||||
return buf;
|
||||
}
|
||||
|
@ -74,5 +84,6 @@ struct sendbuf_t
|
|||
llarp_time_t timestamp = 0;
|
||||
|
||||
private:
|
||||
byte_t *_buf = nullptr;
|
||||
size_t _sz;
|
||||
byte_t _buf[1500];
|
||||
};
|
||||
|
|
|
@ -139,7 +139,7 @@ struct llarp_link
|
|||
issue_cleanup_timer(uint64_t timeout);
|
||||
|
||||
void
|
||||
get_our_address(struct llarp_ai *addr);
|
||||
get_our_address(llarp::AddressInfo &addr);
|
||||
|
||||
static void
|
||||
after_recv(llarp_udp_io *udp);
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include "llarp/crypto.hpp"
|
||||
#include "llarp/crypto_async.h"
|
||||
#include "llarp/net.hpp"
|
||||
#include "llarp/router_contact.h"
|
||||
#include "llarp/router_contact.hpp"
|
||||
#include "llarp/time.h"
|
||||
#include "llarp/types.h"
|
||||
|
||||
|
@ -47,8 +47,9 @@ struct llarp_link_session
|
|||
|
||||
llarp_link *
|
||||
get_parent();
|
||||
llarp_rc *
|
||||
get_remote_router();
|
||||
|
||||
const llarp::RouterContact &
|
||||
get_remote_router() const;
|
||||
|
||||
bool
|
||||
CheckRCValid();
|
||||
|
@ -110,8 +111,8 @@ struct llarp_link_session
|
|||
|
||||
llarp_link *serv = nullptr;
|
||||
|
||||
llarp_rc *our_router = nullptr;
|
||||
llarp_rc remote_router;
|
||||
llarp::RouterContact *our_router = nullptr;
|
||||
llarp::RouterContact remote_router;
|
||||
|
||||
llarp::SecretKey eph_seckey;
|
||||
llarp::PubKey remote;
|
||||
|
|
|
@ -5,13 +5,17 @@ namespace llarp
|
|||
{
|
||||
struct LinkIntroMessage : public ILinkMessage
|
||||
{
|
||||
LinkIntroMessage(llarp_rc* rc) : ILinkMessage(), RC(rc)
|
||||
LinkIntroMessage(const RouterContact& rc) : ILinkMessage(), RC(rc)
|
||||
{
|
||||
hasRC = true;
|
||||
}
|
||||
|
||||
LinkIntroMessage();
|
||||
|
||||
~LinkIntroMessage();
|
||||
|
||||
llarp_rc* RC;
|
||||
bool hasRC = false;
|
||||
RouterContact RC;
|
||||
|
||||
bool
|
||||
DecodeKey(llarp_buffer_t key, llarp_buffer_t* buf);
|
||||
|
|
|
@ -45,7 +45,7 @@ namespace llarp
|
|||
|
||||
struct LR_CommitMessage : public ILinkMessage
|
||||
{
|
||||
std::vector< EncryptedFrame > frames;
|
||||
std::array< EncryptedFrame, 8 > frames;
|
||||
uint64_t version;
|
||||
|
||||
LR_CommitMessage() : ILinkMessage()
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#ifndef LLARP_NET_HPP
|
||||
#define LLARP_NET_HPP
|
||||
#include <llarp/address_info.h>
|
||||
#include <llarp/address_info.hpp>
|
||||
#include <llarp/net.h>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
|
@ -55,7 +55,7 @@ namespace llarp
|
|||
return (const in_addr*)&_addr.sin6_addr.s6_addr[12];
|
||||
}
|
||||
|
||||
Addr(const llarp_ai& other)
|
||||
Addr(const AddressInfo& other)
|
||||
{
|
||||
memcpy(addr6(), other.ip.s6_addr, 16);
|
||||
_addr.sin6_port = htons(other.port);
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
#ifndef LLARP_NODEDB_H
|
||||
#define LLARP_NODEDB_H
|
||||
#ifndef LLARP_NODEDB_HPP
|
||||
#define LLARP_NODEDB_HPP
|
||||
#include <llarp/common.h>
|
||||
#include <llarp/crypto.h>
|
||||
#include <llarp/router_contact.h>
|
||||
#include <llarp/router_contact.hpp>
|
||||
#include <llarp/router_id.hpp>
|
||||
|
||||
/**
|
||||
* nodedb.h
|
||||
* nodedb.hpp
|
||||
*
|
||||
* persistent storage API for router contacts
|
||||
*/
|
||||
|
@ -39,7 +40,7 @@ llarp_nodedb_store_dir(struct llarp_nodedb *n, const char *dir);
|
|||
struct llarp_nodedb_iter
|
||||
{
|
||||
void *user;
|
||||
struct llarp_rc *rc;
|
||||
llarp::RouterContact *rc;
|
||||
size_t index;
|
||||
bool (*visit)(struct llarp_nodedb_iter *);
|
||||
};
|
||||
|
@ -48,15 +49,6 @@ struct llarp_nodedb_iter
|
|||
int
|
||||
llarp_nodedb_iterate_all(struct llarp_nodedb *n, struct llarp_nodedb_iter i);
|
||||
|
||||
/// get a random rc that is loaded
|
||||
void
|
||||
llarp_nodedb_get_random_rc(struct llarp_nodedb *n, struct llarp_rc *result);
|
||||
|
||||
/// select a random rc at hop number N
|
||||
void
|
||||
llarp_nodedb_select_random_hop(struct llarp_nodedb *n, struct llarp_rc *prev,
|
||||
struct llarp_rc *result, size_t N);
|
||||
|
||||
/// return number of RC loaded
|
||||
size_t
|
||||
llarp_nodedb_num_loaded(struct llarp_nodedb *n);
|
||||
|
@ -68,11 +60,11 @@ llarp_nodedb_num_loaded(struct llarp_nodedb *n);
|
|||
returns true on success and false on error
|
||||
*/
|
||||
bool
|
||||
llarp_nodedb_put_rc(struct llarp_nodedb *n, struct llarp_rc *rc);
|
||||
llarp_nodedb_put_rc(struct llarp_nodedb *n, const llarp::RouterContact &rc);
|
||||
|
||||
/// return a pointer to an already loaded RC or nullptr if it's not there
|
||||
struct llarp_rc *
|
||||
llarp_nodedb_get_rc(struct llarp_nodedb *n, const byte_t *pk);
|
||||
bool
|
||||
llarp_nodedb_get_rc(struct llarp_nodedb *n, const llarp::RouterID &pk,
|
||||
llarp::RouterContact &result);
|
||||
|
||||
/// struct for async rc verification
|
||||
struct llarp_async_verify_rc;
|
||||
|
@ -94,7 +86,7 @@ struct llarp_async_verify_rc
|
|||
struct llarp_threadpool *diskworker;
|
||||
|
||||
/// router contact
|
||||
struct llarp_rc rc;
|
||||
llarp::RouterContact rc;
|
||||
/// result
|
||||
bool valid;
|
||||
/// hook
|
||||
|
@ -125,9 +117,9 @@ struct llarp_async_load_rc
|
|||
/// disk worker threadpool
|
||||
struct llarp_threadpool *diskworker;
|
||||
/// target pubkey
|
||||
byte_t pubkey[PUBKEYSIZE];
|
||||
llarp::PubKey pubkey;
|
||||
/// router contact result
|
||||
struct llarp_rc rc;
|
||||
llarp::RouterContact result;
|
||||
/// set to true if we loaded the rc
|
||||
bool loaded;
|
||||
/// hook function called in logic thread
|
||||
|
@ -138,4 +130,9 @@ struct llarp_async_load_rc
|
|||
void
|
||||
llarp_nodedb_async_load_rc(struct llarp_async_load_rc *job);
|
||||
|
||||
void
|
||||
llarp_nodedb_select_random_hop(struct llarp_nodedb *n,
|
||||
const llarp::RouterContact &prev,
|
||||
llarp::RouterContact &result, size_t N);
|
||||
|
||||
#endif
|
|
@ -1,28 +0,0 @@
|
|||
#ifndef LLARP_PATH_H
|
||||
#define LLARP_PATH_H
|
||||
|
||||
#include <llarp/router_contact.h>
|
||||
|
||||
#define MAXHOPS (8)
|
||||
#define DEFAULT_PATH_LIFETIME (10 * 60 * 1000)
|
||||
#define PATH_BUILD_TIMEOUT (10 * 1000)
|
||||
#define MESSAGE_PAD_SIZE (1024)
|
||||
|
||||
struct llarp_path_hop
|
||||
{
|
||||
struct llarp_rc router;
|
||||
byte_t nextHop[PUBKEYSIZE];
|
||||
byte_t sessionkey[SHAREDKEYSIZE];
|
||||
byte_t pathid[PATHIDSIZE];
|
||||
};
|
||||
|
||||
struct llarp_path_hops
|
||||
{
|
||||
struct llarp_path_hop hops[MAXHOPS];
|
||||
size_t numHops;
|
||||
};
|
||||
|
||||
void
|
||||
llarp_path_hops_free(struct llarp_path_hops* hops);
|
||||
|
||||
#endif
|
|
@ -1,6 +1,5 @@
|
|||
#ifndef LLARP_PATH_HPP
|
||||
#define LLARP_PATH_HPP
|
||||
#include <llarp/path.h>
|
||||
#include <llarp/router.h>
|
||||
#include <llarp/time.h>
|
||||
#include <llarp/aligned.hpp>
|
||||
|
@ -10,6 +9,7 @@
|
|||
#include <llarp/messages/relay_commit.hpp>
|
||||
#include <llarp/path_types.hpp>
|
||||
#include <llarp/pathset.hpp>
|
||||
#include <llarp/pathbuilder.hpp>
|
||||
#include <llarp/router_id.hpp>
|
||||
#include <llarp/routing/handler.hpp>
|
||||
#include <llarp/routing/message.hpp>
|
||||
|
@ -22,6 +22,11 @@
|
|||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#define MAXHOPS (8)
|
||||
#define DEFAULT_PATH_LIFETIME (10 * 60 * 1000)
|
||||
#define PATH_BUILD_TIMEOUT (10 * 1000)
|
||||
#define MESSAGE_PAD_SIZE (1024)
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace path
|
||||
|
@ -193,7 +198,7 @@ namespace llarp
|
|||
/// path id
|
||||
PathID_t txID, rxID;
|
||||
// router contact of router
|
||||
llarp_rc router;
|
||||
RouterContact rc;
|
||||
// temp public encryption key
|
||||
SecretKey commkey;
|
||||
/// shared secret at this hop
|
||||
|
@ -226,7 +231,7 @@ namespace llarp
|
|||
llarp_time_t buildStarted;
|
||||
PathStatus status;
|
||||
|
||||
Path(llarp_path_hops* path);
|
||||
Path(const std::vector< RouterContact >& routers);
|
||||
|
||||
void
|
||||
SetBuildResultHook(BuildResultHookFunc func);
|
||||
|
@ -338,7 +343,7 @@ namespace llarp
|
|||
|
||||
/// track a path builder with this context
|
||||
void
|
||||
AddPathBuilder(llarp_pathbuilder_context* set);
|
||||
AddPathBuilder(Builder* set);
|
||||
|
||||
void
|
||||
AllowTransit();
|
||||
|
@ -371,7 +376,7 @@ namespace llarp
|
|||
|
||||
bool
|
||||
ForwardLRCM(const RouterID& nextHop,
|
||||
std::deque< EncryptedFrame >& frames);
|
||||
const std::array< EncryptedFrame, 8 >& frames);
|
||||
|
||||
bool
|
||||
HopIsUs(const PubKey& k) const;
|
||||
|
@ -386,7 +391,7 @@ namespace llarp
|
|||
AddOwnPath(PathSet* set, Path* p);
|
||||
|
||||
void
|
||||
RemovePathBuilder(llarp_pathbuilder_context* ctx);
|
||||
RemovePathBuilder(Builder* ctx);
|
||||
|
||||
void
|
||||
RemovePathSet(PathSet* set);
|
||||
|
@ -423,7 +428,7 @@ namespace llarp
|
|||
SyncTransitMap_t m_TransitPaths;
|
||||
SyncTransitMap_t m_Paths;
|
||||
SyncOwnedPathsMap_t m_OurPaths;
|
||||
std::list< llarp_pathbuilder_context* > m_PathBuilders;
|
||||
std::list< Builder* > m_PathBuilders;
|
||||
bool m_AllowTransit;
|
||||
};
|
||||
} // namespace path
|
||||
|
|
|
@ -1,62 +0,0 @@
|
|||
#ifndef LLARP_PATHFINDER_H_
|
||||
#define LLARP_PATHFINDER_H_
|
||||
|
||||
#include <llarp/buffer.h>
|
||||
#include <llarp/path.h>
|
||||
|
||||
/**
|
||||
* path_base.h
|
||||
*
|
||||
* path api functions
|
||||
*/
|
||||
|
||||
/// forard declare
|
||||
struct llarp_router;
|
||||
struct llarp_dht_context;
|
||||
|
||||
// fwd declr
|
||||
struct llarp_pathbuilder_context;
|
||||
|
||||
/// alloc
|
||||
struct llarp_pathbuilder_context*
|
||||
llarp_pathbuilder_context_new(struct llarp_router* router,
|
||||
struct llarp_dht_context* dht, size_t numpaths,
|
||||
size_t defaultNumHops);
|
||||
/// dealloc
|
||||
void
|
||||
llarp_pathbuilder_context_free(struct llarp_pathbuilder_context* ctx);
|
||||
|
||||
// fwd declr
|
||||
struct llarp_pathbuild_job;
|
||||
|
||||
/// response callback
|
||||
typedef void (*llarp_pathbuilder_hook)(struct llarp_pathbuild_job*);
|
||||
// select hop function (user, nodedb, prevhop, result, hopnnumber) called in
|
||||
// logic thread
|
||||
typedef bool (*llarp_pathbuilder_select_hop_func)(void*, struct llarp_nodedb*,
|
||||
struct llarp_rc*,
|
||||
struct llarp_rc*, size_t);
|
||||
|
||||
// request struct
|
||||
struct llarp_pathbuild_job
|
||||
{
|
||||
// opaque pointer for user data
|
||||
void* user;
|
||||
// router context (set by llarp_pathbuilder_build_path)
|
||||
struct llarp_router* router;
|
||||
// context
|
||||
struct llarp_pathbuilder_context* context;
|
||||
// path hop selection
|
||||
llarp_pathbuilder_select_hop_func selectHop;
|
||||
// called when the path build started
|
||||
llarp_pathbuilder_hook pathBuildStarted;
|
||||
// path
|
||||
struct llarp_path_hops hops;
|
||||
};
|
||||
|
||||
/// request func
|
||||
// or find_path but thought pathfinder_find_path was a bit redundant
|
||||
void
|
||||
llarp_pathbuilder_build_path(struct llarp_pathbuild_job* job);
|
||||
|
||||
#endif
|
|
@ -1,37 +1,41 @@
|
|||
#ifndef LLARP_PATHBUILDER_HPP_
|
||||
#define LLARP_PATHBUILDER_HPP_
|
||||
#include <llarp/pathbuilder.h>
|
||||
#include <llarp/router.h>
|
||||
#include <llarp/path.hpp>
|
||||
|
||||
#include <llarp/pathset.hpp>
|
||||
|
||||
struct llarp_pathbuilder_context : public llarp::path::PathSet
|
||||
namespace llarp
|
||||
{
|
||||
struct llarp_router* router;
|
||||
struct llarp_dht_context* dht;
|
||||
llarp::SecretKey enckey;
|
||||
size_t numHops;
|
||||
/// construct
|
||||
llarp_pathbuilder_context(llarp_router* p_router,
|
||||
struct llarp_dht_context* p_dht, size_t numPaths,
|
||||
size_t numHops);
|
||||
namespace path
|
||||
{
|
||||
struct Builder : public PathSet
|
||||
{
|
||||
struct llarp_router* router;
|
||||
struct llarp_dht_context* dht;
|
||||
llarp::SecretKey enckey;
|
||||
size_t numHops;
|
||||
/// construct
|
||||
Builder(llarp_router* p_router, struct llarp_dht_context* p_dht,
|
||||
size_t numPaths, size_t numHops);
|
||||
|
||||
virtual ~llarp_pathbuilder_context();
|
||||
virtual ~Builder();
|
||||
|
||||
virtual bool
|
||||
SelectHop(llarp_nodedb* db, llarp_rc* prev, llarp_rc* cur, size_t hop);
|
||||
virtual bool
|
||||
SelectHop(llarp_nodedb* db, const RouterContact& prev, RouterContact& cur,
|
||||
size_t hop);
|
||||
|
||||
virtual bool
|
||||
ShouldBuildMore() const;
|
||||
virtual bool
|
||||
ShouldBuildMore() const;
|
||||
|
||||
void
|
||||
BuildOne();
|
||||
void
|
||||
BuildOne();
|
||||
|
||||
void
|
||||
ManualRebuild(size_t N);
|
||||
void
|
||||
ManualRebuild(size_t N);
|
||||
|
||||
virtual byte_t*
|
||||
GetTunnelEncryptionSecretKey();
|
||||
};
|
||||
virtual const byte_t*
|
||||
GetTunnelEncryptionSecretKey() const;
|
||||
};
|
||||
} // namespace path
|
||||
|
||||
} // namespace llarp
|
||||
#endif
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <llarp/routing/message.hpp>
|
||||
#include <llarp/service/IntroSet.hpp>
|
||||
#include <llarp/service/lookup.hpp>
|
||||
#include <llarp/dht/messages/all.hpp>
|
||||
#include <map>
|
||||
#include <tuple>
|
||||
|
||||
|
@ -114,17 +115,9 @@ namespace llarp
|
|||
}
|
||||
|
||||
virtual bool
|
||||
SelectHop(llarp_nodedb* db, llarp_rc* prev, llarp_rc* cur,
|
||||
SelectHop(llarp_nodedb* db, const RouterContact& prev, RouterContact& cur,
|
||||
size_t hop) = 0;
|
||||
|
||||
static bool
|
||||
SelectHopCallback(void* user, llarp_nodedb* db, llarp_rc* prev,
|
||||
llarp_rc* cur, size_t hopno)
|
||||
{
|
||||
PathSet* self = static_cast< PathSet* >(user);
|
||||
return self->SelectHop(db, prev, cur, hopno);
|
||||
}
|
||||
|
||||
private:
|
||||
typedef std::pair< RouterID, PathID_t > PathInfo_t;
|
||||
typedef std::map< PathInfo_t, Path* > PathMap_t;
|
||||
|
|
|
@ -3,11 +3,10 @@
|
|||
#include <llarp/config.h>
|
||||
#include <llarp/ev.h>
|
||||
#include <llarp/logic.h>
|
||||
#include <llarp/nodedb.h>
|
||||
#include <llarp/pathbuilder.h>
|
||||
#include <llarp/router_contact.h>
|
||||
#include <llarp/threadpool.h>
|
||||
#include <llarp/buffer.h>
|
||||
|
||||
struct llarp_nodedb;
|
||||
struct llarp_router;
|
||||
|
||||
bool
|
||||
|
@ -19,16 +18,6 @@ llarp_init_router(struct llarp_threadpool *worker,
|
|||
struct llarp_ev_loop *netloop, struct llarp_logic *logic);
|
||||
void
|
||||
llarp_free_router(struct llarp_router **router);
|
||||
|
||||
bool
|
||||
llarp_router_try_connect(struct llarp_router *router, struct llarp_rc *remote,
|
||||
uint16_t numretries);
|
||||
|
||||
/// override default path builder function (FFI)
|
||||
void
|
||||
llarp_router_override_path_selection(struct llarp_router *router,
|
||||
llarp_pathbuilder_select_hop_func func);
|
||||
|
||||
bool
|
||||
llarp_configure_router(struct llarp_router *router, struct llarp_config *conf);
|
||||
|
||||
|
|
|
@ -1,115 +0,0 @@
|
|||
#ifndef LLARP_RC_H
|
||||
#define LLARP_RC_H
|
||||
#include <llarp/address_info.h>
|
||||
#include <llarp/crypto.h>
|
||||
#include <llarp/exit_info.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <string>
|
||||
#endif
|
||||
|
||||
// forward declare
|
||||
struct llarp_alloc;
|
||||
struct llarp_rc;
|
||||
|
||||
#define MAX_RC_SIZE (1024)
|
||||
#define NICKLEN (32)
|
||||
|
||||
bool
|
||||
llarp_rc_bdecode(struct llarp_rc *rc, llarp_buffer_t *buf);
|
||||
bool
|
||||
llarp_rc_bencode(const struct llarp_rc *rc, llarp_buffer_t *buf);
|
||||
|
||||
struct llarp_rc
|
||||
{
|
||||
struct llarp_ai_list *addrs;
|
||||
// public encryption public key
|
||||
byte_t enckey[PUBKEYSIZE];
|
||||
// public signing public key
|
||||
byte_t pubkey[PUBKEYSIZE];
|
||||
struct llarp_xi_list *exits;
|
||||
byte_t signature[SIGSIZE];
|
||||
/// node nickname, yw kee
|
||||
byte_t nickname[NICKLEN];
|
||||
|
||||
uint64_t last_updated;
|
||||
|
||||
#ifdef __cplusplus
|
||||
bool
|
||||
BEncode(llarp_buffer_t *buf) const
|
||||
{
|
||||
return llarp_rc_bencode(this, buf);
|
||||
}
|
||||
|
||||
bool
|
||||
BDecode(llarp_buffer_t *buf)
|
||||
{
|
||||
return llarp_rc_bdecode(this, buf);
|
||||
}
|
||||
|
||||
bool
|
||||
HasNick() const
|
||||
{
|
||||
return nickname[0] != 0;
|
||||
}
|
||||
|
||||
std::string
|
||||
Nick() const
|
||||
{
|
||||
const char *nick = (const char *)nickname;
|
||||
return std::string(nick, strnlen(nick, sizeof(nickname)));
|
||||
}
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
void
|
||||
llarp_rc_free(struct llarp_rc *rc);
|
||||
|
||||
bool
|
||||
llarp_rc_new(struct llarp_rc *rc);
|
||||
|
||||
bool
|
||||
llarp_rc_verify_sig(struct llarp_crypto *crypto, struct llarp_rc *rc);
|
||||
|
||||
void
|
||||
llarp_rc_copy(struct llarp_rc *dst, const struct llarp_rc *src);
|
||||
|
||||
bool
|
||||
llarp_rc_is_public_router(const struct llarp_rc *const rc);
|
||||
|
||||
void
|
||||
llarp_rc_set_addrs(struct llarp_rc *rc, struct llarp_alloc *mem,
|
||||
struct llarp_ai_list *addr);
|
||||
|
||||
bool
|
||||
llarp_rc_set_nickname(struct llarp_rc *rc, const char *name);
|
||||
|
||||
void
|
||||
llarp_rc_set_pubenckey(struct llarp_rc *rc, const uint8_t *pubenckey);
|
||||
|
||||
void
|
||||
llarp_rc_set_pubsigkey(struct llarp_rc *rc, const uint8_t *pubkey);
|
||||
|
||||
/// combo
|
||||
void
|
||||
llarp_rc_set_pubkey(struct llarp_rc *rc, const uint8_t *pubenckey,
|
||||
const uint8_t *pubsigkey);
|
||||
|
||||
void
|
||||
llarp_rc_sign(struct llarp_crypto *crypto, const byte_t *seckey,
|
||||
struct llarp_rc *rc);
|
||||
|
||||
void
|
||||
llarp_rc_clear(struct llarp_rc *rc);
|
||||
|
||||
bool
|
||||
llarp_rc_addr_list_iter(struct llarp_ai_list_iter *iter, struct llarp_ai *ai);
|
||||
|
||||
bool
|
||||
llarp_rc_read(const char *fpath, struct llarp_rc *result);
|
||||
|
||||
bool
|
||||
llarp_rc_write(struct llarp_rc *rc, const char *our_rc_file);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,67 @@
|
|||
#ifndef LLARP_RC_HPP
|
||||
#define LLARP_RC_HPP
|
||||
#include <llarp/address_info.hpp>
|
||||
#include <llarp/crypto.h>
|
||||
#include <llarp/bencode.hpp>
|
||||
#include <llarp/exit_info.hpp>
|
||||
|
||||
#include <list>
|
||||
|
||||
#define MAX_RC_SIZE (1024)
|
||||
#define NICKLEN (32)
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
struct RouterContact : public IBEncodeMessage
|
||||
{
|
||||
// advertised addresses
|
||||
std::list< AddressInfo > addrs;
|
||||
// public encryption public key
|
||||
llarp::PubKey enckey;
|
||||
// public signing public key
|
||||
llarp::PubKey pubkey;
|
||||
// advertised exits
|
||||
std::list< ExitInfo > exits;
|
||||
// signature
|
||||
llarp::Signature signature;
|
||||
/// node nickname, yw kee
|
||||
llarp::AlignedBuffer< NICKLEN > nickname;
|
||||
|
||||
uint64_t last_updated;
|
||||
|
||||
bool
|
||||
BEncode(llarp_buffer_t *buf) const;
|
||||
|
||||
bool
|
||||
DecodeKey(llarp_buffer_t k, llarp_buffer_t *buf);
|
||||
|
||||
RouterContact &
|
||||
operator=(const RouterContact &other);
|
||||
|
||||
bool
|
||||
HasNick() const;
|
||||
|
||||
std::string
|
||||
Nick() const;
|
||||
|
||||
bool
|
||||
IsPublicRouter() const;
|
||||
|
||||
void
|
||||
SetNick(const std::string &nick);
|
||||
|
||||
bool
|
||||
VerifySignature(llarp_crypto *crypto) const;
|
||||
|
||||
bool
|
||||
Sign(llarp_crypto *crypto, const llarp::SecretKey &secret);
|
||||
|
||||
bool
|
||||
Read(const char *fname);
|
||||
|
||||
bool
|
||||
Write(const char *fname) const;
|
||||
};
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
|
@ -5,12 +5,13 @@
|
|||
#include <llarp/service/Identity.hpp>
|
||||
#include <llarp/service/handler.hpp>
|
||||
#include <llarp/service/protocol.hpp>
|
||||
#include <llarp/path.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace service
|
||||
{
|
||||
struct Endpoint : public llarp_pathbuilder_context,
|
||||
struct Endpoint : public path::Builder,
|
||||
public ILookupHolder,
|
||||
public IDataHandler
|
||||
{
|
||||
|
@ -145,7 +146,7 @@ namespace llarp
|
|||
typedef std::queue< PendingBuffer > PendingBufferQueue;
|
||||
|
||||
/// context needed to initiate an outbound hidden service session
|
||||
struct OutboundContext : public llarp_pathbuilder_context
|
||||
struct OutboundContext : public path::Builder
|
||||
{
|
||||
OutboundContext(const IntroSet& introSet, Endpoint* parent);
|
||||
~OutboundContext();
|
||||
|
@ -176,7 +177,8 @@ namespace llarp
|
|||
HandlePathBuilt(path::Path* path);
|
||||
|
||||
bool
|
||||
SelectHop(llarp_nodedb* db, llarp_rc* prev, llarp_rc* cur, size_t hop);
|
||||
SelectHop(llarp_nodedb* db, const RouterContact& prev,
|
||||
RouterContact& cur, size_t hop);
|
||||
|
||||
bool
|
||||
HandleHiddenServiceFrame(const ProtocolFrame* frame);
|
||||
|
|
|
@ -122,24 +122,6 @@ namespace llarp
|
|||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
Context::IterateDatabase(struct llarp_nodedb_iter i)
|
||||
{
|
||||
return llarp_nodedb_iterate_all(nodedb, i);
|
||||
}
|
||||
|
||||
bool
|
||||
Context::PutDatabase(struct llarp_rc *rc)
|
||||
{
|
||||
return llarp_nodedb_put_rc(nodedb, rc);
|
||||
}
|
||||
|
||||
struct llarp_rc *
|
||||
Context::GetDatabase(const byte_t *pk)
|
||||
{
|
||||
return llarp_nodedb_get_rc(nodedb, pk);
|
||||
}
|
||||
|
||||
int
|
||||
Context::Setup()
|
||||
{
|
||||
|
@ -371,25 +353,6 @@ extern "C"
|
|||
return ptr->ctx->GetDatabase(pk);
|
||||
}
|
||||
|
||||
struct llarp_rc *
|
||||
llarp_main_getLocalRC(struct llarp_main *ptr)
|
||||
{
|
||||
//
|
||||
/*
|
||||
llarp_config_iterator iter;
|
||||
iter.user = this;
|
||||
iter.visit = &iter_config;
|
||||
llarp_config_iter(ctx->config, &iter);
|
||||
*/
|
||||
llarp_rc *rc = new llarp_rc;
|
||||
llarp_rc_new(rc);
|
||||
llarp::LogInfo("Loading ", ptr->ctx->conatctFile);
|
||||
if(llarp_rc_read(ptr->ctx->conatctFile, rc))
|
||||
return rc;
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
llarp_main_checkOnline(void *u, uint64_t orig, uint64_t left)
|
||||
{
|
||||
|
@ -423,7 +386,6 @@ extern "C"
|
|||
request->first = true;
|
||||
llarp::LogInfo("llarp_main_queryDHT_online - We're online");
|
||||
llarp::LogInfo("llarp_main_queryDHT_online - Querying DHT");
|
||||
llarp_dht_lookup_router(request->ptr->ctx->router->dht, request->job);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include <llarp/crypto_async.h>
|
||||
#include <llarp/mem.h>
|
||||
#include <llarp/router_contact.h>
|
||||
#include <llarp/router_contact.hpp>
|
||||
#include <string.h>
|
||||
#include <llarp/crypto.hpp>
|
||||
#include <llarp/router_id.hpp>
|
||||
|
|
|
@ -19,15 +19,6 @@ llarp_dht_context_free(struct llarp_dht_context *ctx)
|
|||
delete ctx;
|
||||
}
|
||||
|
||||
void
|
||||
__llarp_dht_put_peer(struct llarp_dht_context *ctx, struct llarp_rc *rc)
|
||||
|
||||
{
|
||||
llarp::dht::RCNode n(rc);
|
||||
llarp::LogDebug("Adding ", n.ID, " to DHT");
|
||||
ctx->impl.nodes->PutNode(n);
|
||||
}
|
||||
|
||||
void
|
||||
__llarp_dht_remove_peer(struct llarp_dht_context *ctx, const byte_t *id)
|
||||
{
|
||||
|
@ -47,14 +38,3 @@ llarp_dht_context_start(struct llarp_dht_context *ctx, const byte_t *key)
|
|||
{
|
||||
ctx->impl.Init(key, ctx->parent, 20000);
|
||||
}
|
||||
|
||||
void
|
||||
llarp_dht_lookup_router(struct llarp_dht_context *ctx,
|
||||
struct llarp_router_lookup_job *job)
|
||||
{
|
||||
job->dht = ctx;
|
||||
job->found = false;
|
||||
llarp_rc_clear(&job->result);
|
||||
llarp_logic_queue_job(ctx->parent->logic,
|
||||
{job, &llarp::dht::Context::queue_router_lookup});
|
||||
}
|
||||
|
|
|
@ -70,7 +70,8 @@ namespace llarp
|
|||
llarp::LogInfo("got ", valuesFound.size(), " routers from exploration");
|
||||
for(const auto &pk : valuesFound)
|
||||
{
|
||||
if(llarp_nodedb_get_rc(parent->router->nodedb, pk) == nullptr)
|
||||
RouterContact rc;
|
||||
if(!llarp_nodedb_get_rc(parent->router->nodedb, pk, rc))
|
||||
{
|
||||
// try connecting to it we don't know it
|
||||
// this triggers a dht lookup
|
||||
|
@ -191,7 +192,7 @@ namespace llarp
|
|||
{
|
||||
// we are the target, give them our RC
|
||||
replies.push_back(
|
||||
new GotRouterMessage(requester, txid, &router->rc, false));
|
||||
new GotRouterMessage(requester, txid, {router->rc}, false));
|
||||
return;
|
||||
}
|
||||
Key_t next;
|
||||
|
@ -202,7 +203,7 @@ namespace llarp
|
|||
{
|
||||
// we know it
|
||||
replies.push_back(new GotRouterMessage(
|
||||
requester, txid, nodes->nodes[target].rc, false));
|
||||
requester, txid, {nodes->nodes[target].rc}, false));
|
||||
}
|
||||
else if(recursive) // are we doing a recursive lookup?
|
||||
{
|
||||
|
@ -216,22 +217,19 @@ namespace llarp
|
|||
{
|
||||
// no we are closer to the target so tell requester it's not there
|
||||
// so they switch to iterative lookup
|
||||
replies.push_back(
|
||||
new GotRouterMessage(requester, txid, nullptr, false));
|
||||
replies.push_back(new GotRouterMessage(requester, txid, {}, false));
|
||||
}
|
||||
}
|
||||
else // iterative lookup and we don't have it tell them we don't have
|
||||
// the target router
|
||||
{
|
||||
replies.push_back(
|
||||
new GotRouterMessage(requester, txid, nullptr, false));
|
||||
replies.push_back(new GotRouterMessage(requester, txid, {}, false));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// we don't know it and have no closer peers to ask
|
||||
replies.push_back(
|
||||
new GotRouterMessage(requester, txid, nullptr, false));
|
||||
replies.push_back(new GotRouterMessage(requester, txid, {}, false));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -600,15 +598,15 @@ namespace llarp
|
|||
return true;
|
||||
}
|
||||
|
||||
struct RecursiveRouterLookup : public TX< RouterID, llarp_rc >
|
||||
struct RecursiveRouterLookup : public TX< RouterID, RouterContact >
|
||||
{
|
||||
llarp_router_lookup_job *job;
|
||||
RouterLookupHandler resultHandler;
|
||||
RecursiveRouterLookup(const TXOwner &whoasked, const RouterID &target,
|
||||
Context *ctx, llarp_router_lookup_job *j)
|
||||
: TX< RouterID, llarp_rc >(whoasked, target, ctx)
|
||||
Context *ctx, RouterLookupHandler result)
|
||||
: TX< RouterID, RouterContact >(whoasked, target, ctx)
|
||||
, resultHandler(result)
|
||||
|
||||
{
|
||||
job = j;
|
||||
peersAsked.insert(ctx->OurKey());
|
||||
}
|
||||
|
||||
|
@ -641,32 +639,16 @@ namespace llarp
|
|||
void
|
||||
SendReply()
|
||||
{
|
||||
if(job)
|
||||
if(resultHandler)
|
||||
{
|
||||
job->found = false;
|
||||
if(valuesFound.size())
|
||||
{
|
||||
job->found =
|
||||
memcmp(valuesFound[0].pubkey, job->target, PUBKEYSIZE) == 0;
|
||||
if(job->found)
|
||||
llarp_rc_copy(&job->result, &valuesFound[0]);
|
||||
}
|
||||
if(job->hook)
|
||||
job->hook(job);
|
||||
else
|
||||
delete job;
|
||||
resultHandler(valuesFound);
|
||||
}
|
||||
else
|
||||
{
|
||||
llarp_rc *found = nullptr;
|
||||
if(valuesFound.size())
|
||||
found = &valuesFound[0];
|
||||
parent->DHTSendTo(
|
||||
whoasked.node,
|
||||
new GotRouterMessage({}, whoasked.txid, found, false));
|
||||
new GotRouterMessage({}, whoasked.txid, valuesFound, false));
|
||||
}
|
||||
for(auto rc : valuesFound)
|
||||
llarp_rc_free(&rc);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -674,38 +656,15 @@ namespace llarp
|
|||
Context::LookupRouterRecursive(const RouterID &target,
|
||||
const Key_t &whoasked, uint64_t txid,
|
||||
const Key_t &askpeer,
|
||||
llarp_router_lookup_job *job)
|
||||
RouterLookupHandler handler)
|
||||
{
|
||||
TXOwner asker(whoasked, txid);
|
||||
TXOwner peer(askpeer, ++ids);
|
||||
auto tx = pendingRouterLookups.NewTX(
|
||||
peer, target, new RecursiveRouterLookup(asker, target, this, job));
|
||||
peer, target,
|
||||
new RecursiveRouterLookup(asker, target, this, handler));
|
||||
tx->Start(peer);
|
||||
}
|
||||
|
||||
void
|
||||
Context::LookupRouterViaJob(llarp_router_lookup_job *job)
|
||||
{
|
||||
Key_t peer;
|
||||
|
||||
if(nodes->FindClosest(job->target, peer))
|
||||
LookupRouterRecursive(job->target, ourKey, 0, peer, job);
|
||||
else if(job->hook)
|
||||
{
|
||||
job->found = false;
|
||||
job->hook(job);
|
||||
}
|
||||
else
|
||||
delete job;
|
||||
}
|
||||
|
||||
void
|
||||
Context::queue_router_lookup(void *user)
|
||||
{
|
||||
struct llarp_router_lookup_job *job =
|
||||
static_cast< llarp_router_lookup_job * >(user);
|
||||
job->dht->impl.LookupRouterViaJob(job);
|
||||
}
|
||||
|
||||
} // namespace dht
|
||||
} // namespace llarp
|
||||
|
|
|
@ -9,60 +9,6 @@ namespace llarp
|
|||
{
|
||||
namespace dht
|
||||
{
|
||||
struct PathLookupInformer
|
||||
{
|
||||
llarp_router *router;
|
||||
PathID_t pathID;
|
||||
uint64_t txid;
|
||||
|
||||
PathLookupInformer(llarp_router *r, const PathID_t &id, uint64_t tx)
|
||||
: router(r), pathID(id), txid(tx)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
SendReply(llarp::routing::IMessage *msg)
|
||||
{
|
||||
auto path = router->paths.GetByUpstream(router->pubkey(), pathID);
|
||||
if(path == nullptr)
|
||||
{
|
||||
llarp::LogWarn("Path not found for relayed DHT message txid=", txid,
|
||||
" pathid=", pathID);
|
||||
return;
|
||||
}
|
||||
if(!path->SendRoutingMessage(msg, router))
|
||||
llarp::LogWarn("Failed to send reply for relayed DHT message txid=",
|
||||
txid, "pathid=", pathID);
|
||||
}
|
||||
|
||||
static void
|
||||
InformReply(llarp_router_lookup_job *job)
|
||||
{
|
||||
PathLookupInformer *self =
|
||||
static_cast< PathLookupInformer * >(job->user);
|
||||
llarp::routing::DHTMessage reply;
|
||||
if(job->found)
|
||||
{
|
||||
if(llarp_rc_verify_sig(&self->router->crypto, &job->result))
|
||||
{
|
||||
reply.M.push_back(new GotRouterMessage(job->target, self->txid,
|
||||
&job->result, false));
|
||||
}
|
||||
llarp_rc_free(&job->result);
|
||||
llarp_rc_clear(&job->result);
|
||||
}
|
||||
else
|
||||
{
|
||||
reply.M.push_back(
|
||||
new GotRouterMessage(job->target, self->txid, nullptr, false));
|
||||
}
|
||||
self->SendReply(&reply);
|
||||
// TODO: is this okay?
|
||||
delete self;
|
||||
delete job;
|
||||
}
|
||||
};
|
||||
|
||||
bool
|
||||
RelayedFindRouterMessage::HandleMessage(
|
||||
llarp_dht_context *ctx, std::vector< IMessage * > &replies) const
|
||||
|
@ -75,24 +21,16 @@ namespace llarp
|
|||
if(path)
|
||||
{
|
||||
replies.push_back(
|
||||
new GotRouterMessage(K.data(), txid, &dht.router->rc, false));
|
||||
new GotRouterMessage(K.data(), txid, {dht.router->rc}, false));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
llarp_router_lookup_job *job = new llarp_router_lookup_job;
|
||||
PathLookupInformer *informer =
|
||||
new PathLookupInformer(dht.router, pathID, txid);
|
||||
job->user = informer;
|
||||
job->hook = &PathLookupInformer::InformReply;
|
||||
job->found = false;
|
||||
llarp_rc_clear(&job->result);
|
||||
job->dht = ctx;
|
||||
memcpy(job->target, K, sizeof(job->target));
|
||||
|
||||
Key_t peer;
|
||||
Key_t k = K.data();
|
||||
if(dht.nodes->FindClosest(k, peer))
|
||||
dht.LookupRouterRecursive(K, dht.OurKey(), txid, peer, job);
|
||||
dht.LookupRouterForPath(K, txid, pathID, peer);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,9 +9,6 @@ namespace llarp
|
|||
{
|
||||
GotRouterMessage::~GotRouterMessage()
|
||||
{
|
||||
for(auto rc : R)
|
||||
llarp_rc_free(&rc);
|
||||
R.clear();
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -17,17 +17,17 @@ namespace llarp
|
|||
|
||||
Encrypted::Encrypted(const byte_t* buf, size_t sz) : _sz(sz)
|
||||
{
|
||||
_data = new byte_t[sz];
|
||||
if(sz > MAX_SIZE)
|
||||
throw std::logic_error("encrypted frame too big");
|
||||
if(buf)
|
||||
memcpy(data(), buf, sz);
|
||||
else
|
||||
llarp::Zero(data(), sz);
|
||||
UpdateBuffer();
|
||||
}
|
||||
|
||||
Encrypted::~Encrypted()
|
||||
{
|
||||
if(_data)
|
||||
delete[] _data;
|
||||
}
|
||||
|
||||
Encrypted::Encrypted(size_t sz) : Encrypted(nullptr, sz)
|
||||
|
|
|
@ -94,22 +94,30 @@ frame_state::got_xmit(frame_header hdr, size_t sz)
|
|||
auto itr = rx.find(h);
|
||||
if(itr == rx.end())
|
||||
{
|
||||
auto msg = rx.insert(std::make_pair(h,
|
||||
std::unique_ptr< transit_message >(
|
||||
new transit_message(x))))
|
||||
.first->second.get();
|
||||
rxIDs.insert(std::make_pair(id, h));
|
||||
llarp::LogDebug("got message XMIT with ", (int)x.numfrags(),
|
||||
" fragment"
|
||||
"s");
|
||||
// inserted, put last fragment
|
||||
msg->put_lastfrag(hdr.data() + sizeof(x.buffer), x.lastfrag());
|
||||
push_ackfor(id, 0);
|
||||
if(x.numfrags() == 0)
|
||||
if(x.numfrags() > 0)
|
||||
{
|
||||
return inbound_frame_complete(id);
|
||||
auto msg = rx.insert(std::make_pair(h,
|
||||
std::unique_ptr< transit_message >(
|
||||
new transit_message(x))))
|
||||
.first->second.get();
|
||||
rxIDs.insert(std::make_pair(id, h));
|
||||
llarp::LogDebug("got message XMIT with ", (int)x.numfrags(),
|
||||
" fragment"
|
||||
"s");
|
||||
// inserted, put last fragment
|
||||
msg->put_lastfrag(hdr.data() + sizeof(x.buffer), x.lastfrag());
|
||||
push_ackfor(id, 0);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// handle zero fragment message immediately
|
||||
std::unique_ptr< transit_message > msg =
|
||||
std::unique_ptr< transit_message >(new transit_message(x));
|
||||
msg->put_lastfrag(hdr.data() + sizeof(x.buffer), x.lastfrag());
|
||||
push_ackfor(id, 0);
|
||||
return inbound_frame_complete(msg);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
llarp::LogWarn("duplicate XMIT h=", llarp::ShortHash(h));
|
||||
|
@ -170,7 +178,10 @@ frame_state::got_frag(frame_header hdr, size_t sz)
|
|||
if(itr->second->completed())
|
||||
{
|
||||
push_ackfor(msgid, mask);
|
||||
return inbound_frame_complete(msgid);
|
||||
bool result = inbound_frame_complete(itr->second);
|
||||
rxIDs.erase(idItr);
|
||||
rx.erase(itr);
|
||||
return result;
|
||||
}
|
||||
else if(itr->second->should_send_ack(llarp_time_now_ms()))
|
||||
{
|
||||
|
@ -191,14 +202,15 @@ frame_state::push_ackfor(uint64_t id, uint32_t bitmask)
|
|||
}
|
||||
|
||||
bool
|
||||
frame_state::inbound_frame_complete(uint64_t id)
|
||||
frame_state::inbound_frame_complete(
|
||||
const std::unique_ptr< transit_message > &rxmsg)
|
||||
{
|
||||
bool success = false;
|
||||
std::vector< byte_t > msg;
|
||||
std::unique_ptr< transit_message > rxmsg = std::move(rx[rxIDs[id]]);
|
||||
rx.erase(rxIDs[id]);
|
||||
rxIDs.erase(id);
|
||||
llarp::ShortHash digest;
|
||||
|
||||
auto id = rxmsg->msginfo.msgid();
|
||||
|
||||
if(rxmsg->reassemble(msg))
|
||||
{
|
||||
auto router = Router();
|
||||
|
@ -334,8 +346,8 @@ frame_state::process(byte_t *buf, size_t sz)
|
|||
void
|
||||
frame_state::queue_tx(uint64_t id, transit_message *msg)
|
||||
{
|
||||
tx.insert(std::make_pair(id, std::unique_ptr< transit_message >(msg)));
|
||||
msg->generate_xmit(sendqueue, txflags);
|
||||
tx.insert(std::make_pair(id, std::unique_ptr< transit_message >(msg)));
|
||||
// msg->retransmit_frags(sendqueue, txflags);
|
||||
}
|
||||
|
||||
|
|
|
@ -111,8 +111,7 @@ llarp_link::TickSessions()
|
|||
{
|
||||
if(itr->second->Tick(now))
|
||||
{
|
||||
if(itr->second->get_remote_router())
|
||||
m_Connected.erase(itr->second->get_remote_router()->pubkey);
|
||||
m_Connected.erase(itr->second->get_remote_router().pubkey);
|
||||
itr = m_sessions.erase(itr);
|
||||
}
|
||||
else
|
||||
|
@ -289,13 +288,13 @@ llarp_link::issue_cleanup_timer(uint64_t timeout)
|
|||
}
|
||||
|
||||
void
|
||||
llarp_link::get_our_address(llarp_ai* addr)
|
||||
llarp_link::get_our_address(llarp::AddressInfo& addr)
|
||||
{
|
||||
addr->rank = 1;
|
||||
strncpy(addr->dialect, "IWP", sizeof(addr->dialect));
|
||||
memcpy(addr->enc_key, pubkey(), 32);
|
||||
memcpy(addr->ip.s6_addr, this->addr.addr6(), 16);
|
||||
addr->port = this->addr.port();
|
||||
addr.rank = 1;
|
||||
addr.dialect = "IWP";
|
||||
addr.pubkey = pubkey();
|
||||
addr.port = this->addr.port();
|
||||
memcpy(addr.ip.s6_addr, this->addr.addr6(), 16);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -411,7 +410,7 @@ llarp_link::try_establish(struct llarp_link_establish_job* job)
|
|||
visit_session(dst, [job](const std::unique_ptr< llarp_link_session >& s) {
|
||||
s->establish_job = job;
|
||||
s->frame.alive(); // mark it alive
|
||||
s->introduce(job->ai.enc_key);
|
||||
s->introduce(job->ai.pubkey);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -35,7 +35,6 @@ llarp_link_session::llarp_link_session(llarp_link *l, const byte_t *seckey,
|
|||
eph_seckey = seckey;
|
||||
else
|
||||
crypto->encryption_keygen(eph_seckey);
|
||||
llarp_rc_clear(&remote_router);
|
||||
crypto->randbytes(token, 32);
|
||||
frame.alive();
|
||||
working.store(false);
|
||||
|
@ -44,7 +43,6 @@ llarp_link_session::llarp_link_session(llarp_link *l, const byte_t *seckey,
|
|||
|
||||
llarp_link_session::~llarp_link_session()
|
||||
{
|
||||
llarp_rc_free(&remote_router);
|
||||
frame.clear();
|
||||
}
|
||||
|
||||
|
@ -72,6 +70,8 @@ llarp_link_session::sendto(llarp_buffer_t msg)
|
|||
bool
|
||||
llarp_link_session::timedout(llarp_time_t now, llarp_time_t timeout)
|
||||
{
|
||||
if(frame.lastEvent == 0)
|
||||
return false;
|
||||
if(now <= frame.lastEvent)
|
||||
return false;
|
||||
auto diff = now - frame.lastEvent;
|
||||
|
@ -127,10 +127,10 @@ llarp_link_session::session_established()
|
|||
llarp_logic_cancel_call(serv->logic, establish_job_id);
|
||||
}
|
||||
|
||||
llarp_rc *
|
||||
llarp_link_session::get_remote_router()
|
||||
const llarp::RouterContact &
|
||||
llarp_link_session::get_remote_router() const
|
||||
{
|
||||
return &remote_router;
|
||||
return remote_router;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -150,16 +150,16 @@ bool
|
|||
llarp_link_session::CheckRCValid()
|
||||
{
|
||||
// verify signatuire
|
||||
if(!llarp_rc_verify_sig(crypto, &remote_router))
|
||||
if(!remote_router.VerifySignature(crypto))
|
||||
return false;
|
||||
|
||||
auto &list = remote_router.addrs->list;
|
||||
if(list.size() == 0) // the remote node is a client node so accept it
|
||||
if(remote_router.addrs.size()
|
||||
== 0) // the remote node is a client node so accept it
|
||||
return true;
|
||||
// check if the RC owns a pubkey that we are using
|
||||
for(auto &ai : list)
|
||||
for(auto &ai : remote_router.addrs)
|
||||
{
|
||||
if(memcmp(ai.enc_key, remote, PUBKEYSIZE) == 0)
|
||||
if(ai.pubkey == remote)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -240,7 +240,6 @@ handle_verify_introack(iwp_async_introack *introack)
|
|||
{
|
||||
// invalid signature
|
||||
llarp::LogError("introack verify failed from ", link->addr);
|
||||
link->serv->remove_intro_from(link->addr);
|
||||
return;
|
||||
}
|
||||
// cancel resend
|
||||
|
@ -271,7 +270,8 @@ handle_establish_timeout(void *user, uint64_t orig, uint64_t left)
|
|||
// timer timeout
|
||||
job->session = nullptr;
|
||||
}
|
||||
job->result(job);
|
||||
if(!self->working)
|
||||
job->result(job);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -425,12 +425,10 @@ llarp_link_session::keepalive()
|
|||
void
|
||||
llarp_link_session::EncryptOutboundFrames()
|
||||
{
|
||||
llarp_link_session *self = this;
|
||||
outboundFrames.Process([self](iwp_async_frame *frame) {
|
||||
outboundFrames.Process([&](iwp_async_frame *frame) {
|
||||
if(iwp_encrypt_frame(frame))
|
||||
if(llarp_ev_udp_sendto(self->udp, self->addr, frame->buf, frame->sz)
|
||||
== -1)
|
||||
llarp::LogError("sendto ", self->addr, " failed");
|
||||
if(llarp_ev_udp_sendto(udp, addr, frame->buf, frame->sz) == -1)
|
||||
llarp::LogError("sendto ", addr, " failed");
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -753,6 +751,8 @@ llarp_link_session::encrypt_frame_async_send(const void *buf, size_t sz)
|
|||
{
|
||||
// 64 bytes frame overhead for nonce and hmac
|
||||
auto frame = alloc_frame(nullptr, sz + 64);
|
||||
if(frame == nullptr)
|
||||
return;
|
||||
memcpy(frame->buf + 64, buf, sz);
|
||||
// maybe add upto 128 random bytes to the packet
|
||||
auto padding = llarp_randint() % MAX_PAD;
|
||||
|
|
|
@ -5,7 +5,7 @@ namespace llarp
|
|||
/// encode Link Introduce Message onto a buffer
|
||||
/// if router is nullptr then the LIM's r member is omitted.
|
||||
bool
|
||||
EncodeLIM(llarp_buffer_t* buff, llarp_rc* router)
|
||||
EncodeLIM(llarp_buffer_t* buff, const llarp::RouterContact* router)
|
||||
{
|
||||
if(!bencode_start_dict(buff))
|
||||
return false;
|
||||
|
@ -21,7 +21,7 @@ namespace llarp
|
|||
{
|
||||
if(!bencode_write_bytestring(buff, "r", 1))
|
||||
return false;
|
||||
if(!llarp_rc_bencode(router, buff))
|
||||
if(!router->BEncode(buff))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,14 +3,14 @@
|
|||
|
||||
#include <llarp/bencode.h>
|
||||
#include <llarp/buffer.h>
|
||||
#include <llarp/router_contact.h>
|
||||
#include <llarp/router_contact.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
/// encode Link Introduce Message onto a buffer
|
||||
/// if router is nullptr then the LIM's r member is omitted.
|
||||
bool
|
||||
EncodeLIM(llarp_buffer_t* buff, llarp_rc* router);
|
||||
EncodeLIM(llarp_buffer_t* buff, const RouterContact* router);
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include <llarp/bencode.h>
|
||||
#include <llarp/router_contact.h>
|
||||
#include <llarp/router_contact.hpp>
|
||||
#include <llarp/messages/link_intro.hpp>
|
||||
#include "logger.hpp"
|
||||
#include "router.hpp"
|
||||
|
@ -15,13 +15,9 @@ namespace llarp
|
|||
{
|
||||
if(llarp_buffer_eq(key, "r"))
|
||||
{
|
||||
if(!llarp_rc_bdecode(RC, buf))
|
||||
{
|
||||
llarp::LogWarn("failed to decode RC");
|
||||
if(!RC.BDecode(buf))
|
||||
return false;
|
||||
}
|
||||
remote = (byte_t*)RC->pubkey;
|
||||
llarp::LogDebug("decoded RC from ", remote);
|
||||
hasRC = true;
|
||||
return true;
|
||||
}
|
||||
else if(llarp_buffer_eq(key, "v"))
|
||||
|
@ -55,12 +51,11 @@ namespace llarp
|
|||
if(!bencode_write_bytestring(buf, "i", 1))
|
||||
return false;
|
||||
|
||||
if(RC)
|
||||
if(hasRC)
|
||||
{
|
||||
if(!bencode_write_bytestring(buf, "r", 1))
|
||||
return false;
|
||||
if(!llarp_rc_bencode(RC, buf))
|
||||
return false;
|
||||
return RC.BEncode(buf);
|
||||
}
|
||||
|
||||
if(!bencode_write_version_entry(buf))
|
||||
|
@ -72,7 +67,7 @@ namespace llarp
|
|||
bool
|
||||
LinkIntroMessage::HandleMessage(llarp_router* router) const
|
||||
{
|
||||
router->async_verify_RC(RC, !llarp_rc_is_public_router(RC));
|
||||
router->async_verify_RC(RC, !RC.IsPublicRouter());
|
||||
return true;
|
||||
}
|
||||
} // namespace llarp
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include <llarp/router_contact.h>
|
||||
#include <llarp/router_contact.hpp>
|
||||
#include <llarp/messages.hpp>
|
||||
#include "buffer.hpp"
|
||||
#include "llarp/iwp/session.hpp"
|
||||
|
@ -88,8 +88,7 @@ namespace llarp
|
|||
RouterID
|
||||
InboundMessageParser::GetCurrentFrom()
|
||||
{
|
||||
auto rc = from->get_remote_router();
|
||||
return rc->pubkey;
|
||||
return from->get_remote_router().pubkey;
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
207
llarp/nodedb.cpp
207
llarp/nodedb.cpp
|
@ -1,6 +1,6 @@
|
|||
#include <llarp/crypto_async.h>
|
||||
#include <llarp/nodedb.h>
|
||||
#include <llarp/router_contact.h>
|
||||
#include <llarp/nodedb.hpp>
|
||||
#include <llarp/router_contact.hpp>
|
||||
|
||||
#include <fstream>
|
||||
#include <llarp/crypto.hpp>
|
||||
|
@ -22,87 +22,34 @@ struct llarp_nodedb
|
|||
|
||||
llarp_crypto *crypto;
|
||||
// std::map< llarp::pubkey, llarp_rc > entries;
|
||||
std::unordered_map< llarp::PubKey, llarp_rc, llarp::PubKey::Hash > entries;
|
||||
llarp::util::Mutex access;
|
||||
std::unordered_map< llarp::PubKey, llarp::RouterContact, llarp::PubKey::Hash >
|
||||
entries;
|
||||
fs::path nodePath;
|
||||
|
||||
void
|
||||
Clear()
|
||||
{
|
||||
auto itr = entries.begin();
|
||||
while(itr != entries.end())
|
||||
{
|
||||
llarp_rc_clear(&itr->second);
|
||||
itr = entries.erase(itr);
|
||||
}
|
||||
}
|
||||
|
||||
llarp_rc *
|
||||
getRC(const llarp::PubKey &pk)
|
||||
{
|
||||
return &entries.at(pk);
|
||||
llarp::util::Lock lock(access);
|
||||
entries.clear();
|
||||
}
|
||||
|
||||
bool
|
||||
Has(const llarp::PubKey &pk) const
|
||||
Get(const llarp::PubKey &pk, llarp::RouterContact &result)
|
||||
{
|
||||
return entries.find(pk) != entries.end();
|
||||
}
|
||||
|
||||
/*
|
||||
bool
|
||||
Has(const byte_t *pk)
|
||||
{
|
||||
llarp::PubKey test(pk);
|
||||
auto itr = this->entries.begin();
|
||||
while(itr != this->entries.end())
|
||||
{
|
||||
llarp::LogInfo("Has byte_t [", test.size(), "] vs [", itr->first.size(),
|
||||
"]"); if (memcmp(test.data(), itr->first.data(), 32) == 0) {
|
||||
llarp::LogInfo("Match");
|
||||
}
|
||||
itr++;
|
||||
}
|
||||
return entries.find(pk) != entries.end();
|
||||
}
|
||||
*/
|
||||
|
||||
bool
|
||||
pubKeyExists(llarp_rc *rc) const
|
||||
{
|
||||
// extract pk from rc
|
||||
llarp::PubKey pk = rc->pubkey;
|
||||
// return true if we found before end
|
||||
return entries.find(pk) != entries.end();
|
||||
}
|
||||
|
||||
bool
|
||||
check(llarp_rc *rc)
|
||||
{
|
||||
if(!pubKeyExists(rc))
|
||||
{
|
||||
// we don't have it
|
||||
llarp::util::Lock lock(access);
|
||||
auto itr = entries.find(pk);
|
||||
if(itr == entries.end())
|
||||
return false;
|
||||
}
|
||||
llarp::PubKey pk = rc->pubkey;
|
||||
result = itr->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: zero out any fields you don't want to compare
|
||||
// XXX: make a copy and then do modifications on the copy
|
||||
// touching external data in here is HARAM >:[
|
||||
|
||||
// serialize both and memcmp
|
||||
byte_t nodetmp[MAX_RC_SIZE];
|
||||
auto nodebuf = llarp::StackBuffer< decltype(nodetmp) >(nodetmp);
|
||||
if(llarp_rc_bencode(&entries[pk], &nodebuf))
|
||||
{
|
||||
byte_t paramtmp[MAX_RC_SIZE];
|
||||
auto parambuf = llarp::StackBuffer< decltype(paramtmp) >(paramtmp);
|
||||
if(llarp_rc_bencode(rc, ¶mbuf))
|
||||
{
|
||||
if(nodebuf.sz == parambuf.sz)
|
||||
return memcmp(¶mbuf, &nodebuf, parambuf.sz) == 0;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
bool
|
||||
Has(const llarp::PubKey &pk)
|
||||
{
|
||||
llarp::util::Lock lock(access);
|
||||
return entries.find(pk) != entries.end();
|
||||
}
|
||||
|
||||
std::string
|
||||
|
@ -119,40 +66,34 @@ struct llarp_nodedb
|
|||
return filepath.string();
|
||||
}
|
||||
|
||||
/// insert and write to disk
|
||||
bool
|
||||
setRC(llarp_rc *rc)
|
||||
Insert(const llarp::RouterContact &rc)
|
||||
{
|
||||
byte_t tmp[MAX_RC_SIZE];
|
||||
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
|
||||
|
||||
// extract pk from rc
|
||||
llarp::PubKey pk = rc->pubkey;
|
||||
|
||||
// set local db entry to have a copy we own
|
||||
llarp_rc entry;
|
||||
llarp::Zero(&entry, sizeof(entry));
|
||||
llarp_rc_copy(&entry, rc);
|
||||
entries.insert(std::make_pair(pk, entry));
|
||||
|
||||
if(llarp_rc_bencode(&entry, &buf))
|
||||
{
|
||||
buf.sz = buf.cur - buf.base;
|
||||
auto filepath = getRCFilePath(pk);
|
||||
llarp::LogDebug("saving RC.pubkey ", filepath);
|
||||
std::ofstream ofs(
|
||||
filepath,
|
||||
std::ofstream::out & std::ofstream::binary & std::ofstream::trunc);
|
||||
ofs.write((char *)buf.base, buf.sz);
|
||||
ofs.close();
|
||||
if(!ofs)
|
||||
{
|
||||
llarp::LogError("Failed to write: ", filepath);
|
||||
return false;
|
||||
}
|
||||
llarp::LogDebug("saved RC.pubkey: ", filepath);
|
||||
return true;
|
||||
llarp::util::Lock lock(access);
|
||||
entries.insert(std::make_pair(rc.pubkey, rc));
|
||||
}
|
||||
return false;
|
||||
if(!rc.BEncode(&buf))
|
||||
return false;
|
||||
|
||||
buf.sz = buf.cur - buf.base;
|
||||
auto filepath = getRCFilePath(rc.pubkey);
|
||||
llarp::LogDebug("saving RC.pubkey ", filepath);
|
||||
std::ofstream ofs(
|
||||
filepath,
|
||||
std::ofstream::out & std::ofstream::binary & std::ofstream::trunc);
|
||||
ofs.write((char *)buf.base, buf.sz);
|
||||
ofs.close();
|
||||
if(!ofs)
|
||||
{
|
||||
llarp::LogError("Failed to write: ", filepath);
|
||||
return false;
|
||||
}
|
||||
llarp::LogDebug("saved RC.pubkey: ", filepath);
|
||||
return true;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
|
@ -197,28 +138,30 @@ struct llarp_nodedb
|
|||
{
|
||||
if(fpath.extension() != RC_FILE_EXT)
|
||||
return false;
|
||||
llarp_rc rc;
|
||||
llarp_rc_clear(&rc);
|
||||
llarp::RouterContact rc;
|
||||
|
||||
if(!llarp_rc_read(fpath.string().c_str(), &rc))
|
||||
if(!rc.Read(fpath.string().c_str()))
|
||||
{
|
||||
llarp::LogError("Signature read failed", fpath);
|
||||
llarp::LogError("failed to read file ", fpath);
|
||||
return false;
|
||||
}
|
||||
if(!llarp_rc_verify_sig(crypto, &rc))
|
||||
if(!rc.VerifySignature(crypto))
|
||||
{
|
||||
llarp::LogError("Signature verify failed", fpath);
|
||||
return false;
|
||||
}
|
||||
llarp::PubKey pk(rc.pubkey);
|
||||
entries[pk] = rc;
|
||||
{
|
||||
llarp::util::Lock lock(access);
|
||||
entries.insert(std::make_pair(rc.pubkey, rc));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
iterate(struct llarp_nodedb_iter i)
|
||||
{
|
||||
i.index = 0;
|
||||
i.index = 0;
|
||||
llarp::util::Lock lock(access);
|
||||
auto itr = entries.begin();
|
||||
while(itr != entries.end())
|
||||
{
|
||||
|
@ -263,7 +206,7 @@ disk_threadworker_setRC(void *user)
|
|||
{
|
||||
llarp_async_verify_rc *verify_request =
|
||||
static_cast< llarp_async_verify_rc * >(user);
|
||||
verify_request->valid = verify_request->nodedb->setRC(&verify_request->rc);
|
||||
verify_request->valid = verify_request->nodedb->Insert(verify_request->rc);
|
||||
if(verify_request->logic)
|
||||
llarp_logic_queue_job(verify_request->logic,
|
||||
{verify_request, &logic_threadworker_callback});
|
||||
|
@ -276,9 +219,9 @@ crypto_threadworker_verifyrc(void *user)
|
|||
llarp_async_verify_rc *verify_request =
|
||||
static_cast< llarp_async_verify_rc * >(user);
|
||||
verify_request->valid =
|
||||
llarp_rc_verify_sig(verify_request->nodedb->crypto, &verify_request->rc);
|
||||
verify_request->rc.VerifySignature(verify_request->nodedb->crypto);
|
||||
// if it's valid we need to set it
|
||||
if(verify_request->valid && llarp_rc_is_public_router(&verify_request->rc))
|
||||
if(verify_request->valid && verify_request->rc.IsPublicRouter())
|
||||
{
|
||||
llarp::LogDebug("RC is valid, saving to disk");
|
||||
llarp_threadpool_queue_job(verify_request->diskworker,
|
||||
|
@ -310,8 +253,7 @@ nodedb_async_load_rc(void *user)
|
|||
job->loaded = job->nodedb->loadfile(fpath);
|
||||
if(job->loaded)
|
||||
{
|
||||
llarp_rc_clear(&job->rc);
|
||||
llarp_rc_copy(&job->rc, job->nodedb->getRC(job->pubkey));
|
||||
job->nodedb->Get(job->pubkey, job->result);
|
||||
}
|
||||
llarp_logic_queue_job(job->logic, {job, &nodedb_inform_load_rc});
|
||||
}
|
||||
|
@ -384,14 +326,6 @@ llarp_nodedb_load_dir(struct llarp_nodedb *n, const char *dir)
|
|||
return n->Load(dir);
|
||||
}
|
||||
|
||||
/// c api for nodedb::setRC
|
||||
/// maybe better to use llarp_nodedb_async_verify
|
||||
bool
|
||||
llarp_nodedb_put_rc(struct llarp_nodedb *n, struct llarp_rc *rc)
|
||||
{
|
||||
return n->setRC(rc);
|
||||
}
|
||||
|
||||
int
|
||||
llarp_nodedb_iterate_all(struct llarp_nodedb *n, struct llarp_nodedb_iter i)
|
||||
{
|
||||
|
@ -419,14 +353,12 @@ llarp_nodedb_async_load_rc(struct llarp_async_load_rc *job)
|
|||
}
|
||||
*/
|
||||
|
||||
struct llarp_rc *
|
||||
llarp_nodedb_get_rc(struct llarp_nodedb *n, const byte_t *pk)
|
||||
bool
|
||||
llarp_nodedb_get_rc(struct llarp_nodedb *n, const llarp::RouterID &pk,
|
||||
llarp::RouterContact &result)
|
||||
{
|
||||
// llarp::LogInfo("llarp_nodedb_get_rc [", pk, "]");
|
||||
if(n->Has(pk))
|
||||
return n->getRC(pk);
|
||||
else
|
||||
return nullptr;
|
||||
return n->Get(pk, result);
|
||||
}
|
||||
|
||||
size_t
|
||||
|
@ -436,14 +368,15 @@ llarp_nodedb_num_loaded(struct llarp_nodedb *n)
|
|||
}
|
||||
|
||||
void
|
||||
llarp_nodedb_select_random_hop(struct llarp_nodedb *n, struct llarp_rc *prev,
|
||||
struct llarp_rc *result, size_t N)
|
||||
llarp_nodedb_select_random_hop(struct llarp_nodedb *n,
|
||||
const llarp::RouterContact &prev,
|
||||
llarp::RouterContact &result, size_t N)
|
||||
{
|
||||
/// checking for "guard" status for N = 0 is done by caller inside of
|
||||
/// pathbuilder's scope
|
||||
auto sz = n->entries.size();
|
||||
|
||||
if(prev)
|
||||
if(N)
|
||||
{
|
||||
do
|
||||
{
|
||||
|
@ -451,13 +384,14 @@ llarp_nodedb_select_random_hop(struct llarp_nodedb *n, struct llarp_rc *prev,
|
|||
if(sz > 1)
|
||||
{
|
||||
auto idx = llarp_randint() % sz;
|
||||
std::advance(itr, idx);
|
||||
if(idx)
|
||||
std::advance(itr, idx - 1);
|
||||
}
|
||||
if(memcmp(prev->pubkey, itr->second.pubkey, PUBKEYSIZE) == 0)
|
||||
if(prev.pubkey == itr->second.pubkey)
|
||||
continue;
|
||||
if(itr->second.addrs && llarp_ai_list_size(itr->second.addrs))
|
||||
if(itr->second.addrs.size())
|
||||
{
|
||||
llarp_rc_copy(result, &itr->second);
|
||||
result = itr->second;
|
||||
return;
|
||||
}
|
||||
} while(true);
|
||||
|
@ -468,8 +402,9 @@ llarp_nodedb_select_random_hop(struct llarp_nodedb *n, struct llarp_rc *prev,
|
|||
if(sz > 1)
|
||||
{
|
||||
auto idx = llarp_randint() % sz;
|
||||
std::advance(itr, idx);
|
||||
if(idx)
|
||||
std::advance(itr, idx - 1);
|
||||
}
|
||||
llarp_rc_copy(result, &itr->second);
|
||||
result = itr->second;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,15 +62,11 @@ namespace llarp
|
|||
|
||||
bool
|
||||
PathContext::ForwardLRCM(const RouterID& nextHop,
|
||||
std::deque< EncryptedFrame >& frames)
|
||||
const std::array< EncryptedFrame, 8 >& frames)
|
||||
{
|
||||
llarp::LogDebug("fowarding LRCM to ", nextHop);
|
||||
LR_CommitMessage* msg = new LR_CommitMessage();
|
||||
while(frames.size())
|
||||
{
|
||||
msg->frames.push_back(frames.front());
|
||||
frames.pop_front();
|
||||
}
|
||||
msg->frames = frames;
|
||||
return m_Router->SendToOrQueue(nextHop, msg);
|
||||
}
|
||||
template < typename Map_t, typename Key_t, typename CheckValue_t,
|
||||
|
@ -290,7 +286,7 @@ namespace llarp
|
|||
}
|
||||
|
||||
void
|
||||
PathContext::AddPathBuilder(llarp_pathbuilder_context* ctx)
|
||||
PathContext::AddPathBuilder(Builder* ctx)
|
||||
{
|
||||
m_PathBuilders.push_back(ctx);
|
||||
}
|
||||
|
@ -311,7 +307,7 @@ namespace llarp
|
|||
}
|
||||
|
||||
void
|
||||
PathContext::RemovePathBuilder(llarp_pathbuilder_context* ctx)
|
||||
PathContext::RemovePathBuilder(Builder* ctx)
|
||||
{
|
||||
m_PathBuilders.remove(ctx);
|
||||
RemovePathSet(ctx);
|
||||
|
@ -319,31 +315,30 @@ namespace llarp
|
|||
|
||||
PathHopConfig::PathHopConfig()
|
||||
{
|
||||
llarp_rc_clear(&router);
|
||||
}
|
||||
|
||||
PathHopConfig::~PathHopConfig()
|
||||
{
|
||||
llarp_rc_free(&router);
|
||||
}
|
||||
|
||||
Path::Path(llarp_path_hops* h) : hops(h->numHops)
|
||||
Path::Path(const std::vector< RouterContact >& h) : hops(h.size())
|
||||
{
|
||||
for(size_t idx = 0; idx < h->numHops; ++idx)
|
||||
size_t hsz = h.size();
|
||||
for(size_t idx = 0; idx < hsz; ++idx)
|
||||
{
|
||||
llarp_rc_copy(&hops[idx].router, &h->hops[idx].router);
|
||||
hops[idx].rc = h[idx];
|
||||
hops[idx].txID.Randomize();
|
||||
hops[idx].rxID.Randomize();
|
||||
}
|
||||
|
||||
for(size_t idx = 0; idx < h->numHops - 1; ++idx)
|
||||
for(size_t idx = 0; idx < hsz - 1; ++idx)
|
||||
{
|
||||
hops[idx].txID = hops[idx + 1].rxID;
|
||||
}
|
||||
// initialize parts of the introduction
|
||||
intro.router = hops[h->numHops - 1].router.pubkey;
|
||||
intro.router = hops[hsz - 1].rc.pubkey;
|
||||
// TODO: or is it rxid ?
|
||||
intro.pathID = hops[h->numHops - 1].txID;
|
||||
intro.pathID = hops[hsz - 1].txID;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -355,7 +350,7 @@ namespace llarp
|
|||
RouterID
|
||||
Path::Endpoint() const
|
||||
{
|
||||
return hops[hops.size() - 1].router.pubkey;
|
||||
return hops[hops.size() - 1].rc.pubkey;
|
||||
}
|
||||
|
||||
const PathID_t&
|
||||
|
@ -379,7 +374,7 @@ namespace llarp
|
|||
RouterID
|
||||
Path::Upstream() const
|
||||
{
|
||||
return hops[0].router.pubkey;
|
||||
return hops[0].rc.pubkey;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include <llarp/nodedb.h>
|
||||
#include <llarp/nodedb.hpp>
|
||||
#include <llarp/path.hpp>
|
||||
|
||||
#include <llarp/pathbuilder.hpp>
|
||||
|
@ -44,7 +44,7 @@ namespace llarp
|
|||
ctx->crypto->encryption_keygen(hop.commkey);
|
||||
hop.nonce.Randomize();
|
||||
// do key exchange
|
||||
if(!ctx->crypto->dh_client(hop.shared, hop.router.enckey, hop.commkey,
|
||||
if(!ctx->crypto->dh_client(hop.shared, hop.rc.enckey, hop.commkey,
|
||||
hop.nonce))
|
||||
{
|
||||
llarp::LogError("Failed to generate shared key for path build");
|
||||
|
@ -59,11 +59,11 @@ namespace llarp
|
|||
|
||||
if(isFarthestHop)
|
||||
{
|
||||
hop.upstream = hop.router.pubkey;
|
||||
hop.upstream = hop.rc.pubkey;
|
||||
}
|
||||
else
|
||||
{
|
||||
hop.upstream = ctx->path->hops[ctx->idx].router.pubkey;
|
||||
hop.upstream = ctx->path->hops[ctx->idx].rc.pubkey;
|
||||
}
|
||||
|
||||
// build record
|
||||
|
@ -87,7 +87,7 @@ namespace llarp
|
|||
// use ephameral keypair for frame
|
||||
SecretKey framekey;
|
||||
ctx->crypto->encryption_keygen(framekey);
|
||||
if(!frame.EncryptInPlace(framekey, hop.router.enckey, ctx->crypto))
|
||||
if(!frame.EncryptInPlace(framekey, hop.rc.enckey, ctx->crypto))
|
||||
{
|
||||
llarp::LogError("Failed to encrypt LRCR");
|
||||
return;
|
||||
|
@ -123,16 +123,14 @@ namespace llarp
|
|||
|
||||
for(size_t idx = 0; idx < MAXHOPS; ++idx)
|
||||
{
|
||||
LRCM->frames.emplace_back();
|
||||
LRCM->frames.back().Randomize();
|
||||
LRCM->frames[idx].Randomize();
|
||||
}
|
||||
llarp_threadpool_queue_job(pool, {this, &GenerateNextKey});
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
pathbuilder_generated_keys(
|
||||
AsyncPathKeyExchangeContext< llarp_pathbuild_job >* ctx)
|
||||
pathbuilder_generated_keys(AsyncPathKeyExchangeContext< path::Builder >* ctx)
|
||||
{
|
||||
auto remote = ctx->path->Upstream();
|
||||
auto router = ctx->user->router;
|
||||
|
@ -148,131 +146,104 @@ namespace llarp
|
|||
router->PersistSessionUntil(remote, ctx->path->ExpireTime());
|
||||
// add own path
|
||||
router->paths.AddOwnPath(ctx->pathset, ctx->path);
|
||||
ctx->user->pathBuildStarted(ctx->user);
|
||||
}
|
||||
|
||||
void
|
||||
pathbuilder_start_build(void* user)
|
||||
namespace path
|
||||
{
|
||||
llarp_pathbuild_job* job = static_cast< llarp_pathbuild_job* >(user);
|
||||
// select hops
|
||||
size_t idx = 0;
|
||||
llarp_rc* prev = nullptr;
|
||||
while(idx < job->hops.numHops)
|
||||
Builder::Builder(llarp_router* p_router, struct llarp_dht_context* p_dht,
|
||||
size_t pathNum, size_t hops)
|
||||
: llarp::path::PathSet(pathNum)
|
||||
, router(p_router)
|
||||
, dht(p_dht)
|
||||
, numHops(hops)
|
||||
{
|
||||
llarp_rc* rc = &job->hops.hops[idx].router;
|
||||
llarp_rc_clear(rc);
|
||||
if(!job->selectHop(job->user, job->router->nodedb, prev, rc, idx))
|
||||
{
|
||||
/// TODO: handle this failure properly
|
||||
llarp::LogWarn("Failed to select hop ", idx);
|
||||
return;
|
||||
}
|
||||
prev = rc;
|
||||
++idx;
|
||||
p_router->paths.AddPathBuilder(this);
|
||||
p_router->crypto.encryption_keygen(enckey);
|
||||
}
|
||||
|
||||
// async generate keys
|
||||
AsyncPathKeyExchangeContext< llarp_pathbuild_job >* ctx =
|
||||
new AsyncPathKeyExchangeContext< llarp_pathbuild_job >(
|
||||
&job->router->crypto);
|
||||
ctx->pathset = job->context;
|
||||
auto path = new llarp::path::Path(&job->hops);
|
||||
path->SetBuildResultHook(std::bind(&llarp::path::PathSet::HandlePathBuilt,
|
||||
ctx->pathset, std::placeholders::_1));
|
||||
ctx->AsyncGenerateKeys(path, job->router->logic, job->router->tp, job,
|
||||
&pathbuilder_generated_keys);
|
||||
}
|
||||
Builder::~Builder()
|
||||
{
|
||||
router->paths.RemovePathBuilder(this);
|
||||
}
|
||||
|
||||
bool
|
||||
Builder::SelectHop(llarp_nodedb* db, const RouterContact& prev,
|
||||
RouterContact& cur, size_t hop)
|
||||
{
|
||||
if(hop == 0)
|
||||
{
|
||||
if(router->NumberOfConnectedRouters())
|
||||
return router->GetRandomConnectedRouter(cur);
|
||||
else
|
||||
{
|
||||
llarp_nodedb_select_random_hop(db, prev, cur, 0);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
llarp_nodedb_select_random_hop(db, prev, cur, hop);
|
||||
return true;
|
||||
}
|
||||
|
||||
const byte_t*
|
||||
Builder::GetTunnelEncryptionSecretKey() const
|
||||
{
|
||||
return enckey;
|
||||
}
|
||||
|
||||
bool
|
||||
Builder::ShouldBuildMore() const
|
||||
{
|
||||
return llarp::path::PathSet::ShouldBuildMore()
|
||||
|| router->NumberOfConnectedRouters() == 0;
|
||||
}
|
||||
|
||||
void
|
||||
Builder::BuildOne()
|
||||
{
|
||||
// select hops
|
||||
std::vector< RouterContact > hops(numHops);
|
||||
size_t idx = 0;
|
||||
RouterContact prev;
|
||||
while(idx < numHops)
|
||||
{
|
||||
if(idx == 0)
|
||||
{
|
||||
if(!SelectHop(router->nodedb, hops[0], hops[0], 0))
|
||||
{
|
||||
llarp::LogError("failed to select first hop");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!SelectHop(router->nodedb, hops[idx - 1], hops[idx], idx))
|
||||
{
|
||||
/// TODO: handle this failure properly
|
||||
llarp::LogWarn("Failed to select hop ", idx);
|
||||
return;
|
||||
}
|
||||
}
|
||||
++idx;
|
||||
}
|
||||
// async generate keys
|
||||
AsyncPathKeyExchangeContext< Builder >* ctx =
|
||||
new AsyncPathKeyExchangeContext< Builder >(&router->crypto);
|
||||
ctx->pathset = this;
|
||||
auto path = new llarp::path::Path(hops);
|
||||
path->SetBuildResultHook(std::bind(&llarp::path::PathSet::HandlePathBuilt,
|
||||
ctx->pathset, std::placeholders::_1));
|
||||
ctx->AsyncGenerateKeys(path, router->logic, router->tp, this,
|
||||
&pathbuilder_generated_keys);
|
||||
}
|
||||
|
||||
void
|
||||
Builder::ManualRebuild(size_t num)
|
||||
{
|
||||
llarp::LogDebug("manual rebuild ", num);
|
||||
while(num--)
|
||||
BuildOne();
|
||||
}
|
||||
|
||||
} // namespace path
|
||||
} // namespace llarp
|
||||
|
||||
llarp_pathbuilder_context::llarp_pathbuilder_context(
|
||||
llarp_router* p_router, struct llarp_dht_context* p_dht, size_t pathNum,
|
||||
size_t hops)
|
||||
: llarp::path::PathSet(pathNum), router(p_router), dht(p_dht), numHops(hops)
|
||||
{
|
||||
p_router->paths.AddPathBuilder(this);
|
||||
p_router->crypto.encryption_keygen(enckey);
|
||||
}
|
||||
|
||||
llarp_pathbuilder_context::~llarp_pathbuilder_context()
|
||||
{
|
||||
router->paths.RemovePathBuilder(this);
|
||||
}
|
||||
|
||||
bool
|
||||
llarp_pathbuilder_context::SelectHop(llarp_nodedb* db, llarp_rc* prev,
|
||||
llarp_rc* cur, size_t hop)
|
||||
{
|
||||
if(hop == 0)
|
||||
{
|
||||
return router->GetRandomConnectedRouter(cur);
|
||||
}
|
||||
else
|
||||
llarp_nodedb_select_random_hop(db, prev, cur, hop);
|
||||
return true;
|
||||
}
|
||||
|
||||
byte_t*
|
||||
llarp_pathbuilder_context::GetTunnelEncryptionSecretKey()
|
||||
{
|
||||
return enckey;
|
||||
}
|
||||
|
||||
bool
|
||||
llarp_pathbuilder_context::ShouldBuildMore() const
|
||||
{
|
||||
return llarp::path::PathSet::ShouldBuildMore()
|
||||
|| router->NumberOfConnectedRouters() == 0;
|
||||
}
|
||||
|
||||
void
|
||||
llarp_pathbuilder_context::BuildOne()
|
||||
{
|
||||
llarp_pathbuild_job* job = new llarp_pathbuild_job;
|
||||
job->context = this;
|
||||
job->selectHop = &PathSet::SelectHopCallback;
|
||||
job->hops.numHops = numHops;
|
||||
job->user = this;
|
||||
job->pathBuildStarted = [](llarp_pathbuild_job* j) { delete j; };
|
||||
llarp_pathbuilder_build_path(job);
|
||||
}
|
||||
|
||||
void
|
||||
llarp_pathbuilder_context::ManualRebuild(size_t num)
|
||||
{
|
||||
llarp::LogDebug("manual rebuild ", num);
|
||||
while(num--)
|
||||
BuildOne();
|
||||
}
|
||||
|
||||
struct llarp_pathbuilder_context*
|
||||
llarp_pathbuilder_context_new(struct llarp_router* router,
|
||||
struct llarp_dht_context* dht, size_t sz,
|
||||
size_t hops)
|
||||
{
|
||||
return new llarp_pathbuilder_context(router, dht, sz, hops);
|
||||
}
|
||||
|
||||
void
|
||||
llarp_pathbuilder_context_free(struct llarp_pathbuilder_context* ctx)
|
||||
{
|
||||
delete ctx;
|
||||
}
|
||||
|
||||
void
|
||||
llarp_pathbuilder_build_path(struct llarp_pathbuild_job* job)
|
||||
{
|
||||
if(!job->context)
|
||||
{
|
||||
llarp::LogError("failed to build path because no context is set in job");
|
||||
return;
|
||||
}
|
||||
if(job->selectHop == nullptr)
|
||||
{
|
||||
llarp::LogError("No callback provided for hop selection");
|
||||
return;
|
||||
}
|
||||
job->router = job->context->router;
|
||||
llarp_logic_queue_job(job->router->logic,
|
||||
{job, &llarp::pathbuilder_start_build});
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace llarp
|
|||
{
|
||||
if(llarp_buffer_eq(key, "c"))
|
||||
{
|
||||
return BEncodeReadList(frames, buf);
|
||||
return BEncodeReadArray(frames, buf);
|
||||
}
|
||||
bool read = false;
|
||||
if(!BEncodeMaybeReadVersion("v", version, LLARP_PROTO_VERSION, read, key,
|
||||
|
@ -35,7 +35,7 @@ namespace llarp
|
|||
if(!BEncodeWriteDictMsgType(buf, "a", "c"))
|
||||
return false;
|
||||
// frames
|
||||
if(!BEncodeWriteDictList("c", frames, buf))
|
||||
if(!BEncodeWriteDictArray("c", frames, buf))
|
||||
return false;
|
||||
// version
|
||||
if(!bencode_write_version_entry(buf))
|
||||
|
@ -165,7 +165,7 @@ namespace llarp
|
|||
typedef llarp::path::TransitHop Hop;
|
||||
typedef AsyncFrameDecrypter< LRCMFrameDecrypt > Decrypter;
|
||||
Decrypter* decrypter;
|
||||
std::deque< EncryptedFrame > frames;
|
||||
std::array< EncryptedFrame, 8 > frames;
|
||||
Context* context;
|
||||
// decrypted record
|
||||
LR_CommitRecord record;
|
||||
|
@ -174,10 +174,8 @@ namespace llarp
|
|||
|
||||
LRCMFrameDecrypt(Context* ctx, Decrypter* dec,
|
||||
const LR_CommitMessage* commit)
|
||||
: decrypter(dec), context(ctx), hop(new Hop())
|
||||
: decrypter(dec), frames(commit->frames), context(ctx), hop(new Hop())
|
||||
{
|
||||
for(const auto& f : commit->frames)
|
||||
frames.push_back(f);
|
||||
hop->info.downstream = commit->remote;
|
||||
}
|
||||
|
||||
|
@ -281,14 +279,21 @@ namespace llarp
|
|||
llarp::LogDebug("Accepted ", self->hop->info);
|
||||
self->context->PutTransitHop(self->hop);
|
||||
|
||||
size_t sz = self->frames.front().size();
|
||||
// we pop the front element it was ours
|
||||
self->frames.pop_front();
|
||||
size_t sz = self->frames[0].size();
|
||||
// shift
|
||||
std::array< EncryptedFrame, 8 > frames;
|
||||
frames[0] = self->frames[1];
|
||||
frames[1] = self->frames[2];
|
||||
frames[2] = self->frames[3];
|
||||
frames[3] = self->frames[4];
|
||||
frames[4] = self->frames[5];
|
||||
frames[5] = self->frames[6];
|
||||
frames[6] = self->frames[7];
|
||||
// put our response on the end
|
||||
self->frames.emplace_back(sz - EncryptedFrame::OverheadSize);
|
||||
frames[7] = EncryptedFrame(sz - EncryptedFrame::OverheadSize);
|
||||
// random junk for now
|
||||
self->frames.back().Randomize();
|
||||
|
||||
frames[7].Randomize();
|
||||
self->frames = std::move(frames);
|
||||
if(self->context->HopIsUs(info.upstream))
|
||||
{
|
||||
// we are the farthest hop
|
||||
|
@ -315,7 +320,7 @@ namespace llarp
|
|||
LRCMFrameDecrypt* frames = new LRCMFrameDecrypt(context, decrypter, this);
|
||||
|
||||
// decrypt frames async
|
||||
decrypter->AsyncDecrypt(context->Worker(), &frames->frames.front(), frames);
|
||||
decrypter->AsyncDecrypt(context->Worker(), &frames->frames[0], frames);
|
||||
return true;
|
||||
}
|
||||
} // namespace llarp
|
||||
|
|
392
llarp/router.cpp
392
llarp/router.cpp
|
@ -28,6 +28,47 @@ namespace llarp
|
|||
|
||||
} // namespace llarp
|
||||
|
||||
bool
|
||||
llarp_router_try_connect(struct llarp_router *router,
|
||||
const llarp::RouterContact &remote,
|
||||
uint16_t numretries)
|
||||
{
|
||||
// do we already have a pending job for this remote?
|
||||
if(router->HasPendingConnectJob(remote.pubkey))
|
||||
{
|
||||
llarp::LogDebug("We have pending connect jobs to ", remote.pubkey);
|
||||
return false;
|
||||
}
|
||||
// try first address only
|
||||
if(remote.addrs.size())
|
||||
|
||||
{
|
||||
auto link = router->outboundLink;
|
||||
auto itr = router->pendingEstablishJobs.insert(
|
||||
std::make_pair(remote.pubkey, llarp_link_establish_job()));
|
||||
auto job = &itr.first->second;
|
||||
job->ai = remote.addrs.front();
|
||||
job->pubkey = remote.pubkey;
|
||||
job->retries = numretries;
|
||||
job->timeout = 10000;
|
||||
job->result = &llarp_router::on_try_connect_result;
|
||||
// give router as user pointer
|
||||
job->user = router;
|
||||
job->link = link;
|
||||
// try establishing async
|
||||
llarp_logic_queue_job(router->logic,
|
||||
{job, [](void *u) {
|
||||
llarp_link_establish_job *j =
|
||||
static_cast< llarp_link_establish_job * >(u);
|
||||
j->link->try_establish(j);
|
||||
j->link = nullptr;
|
||||
}});
|
||||
return true;
|
||||
}
|
||||
llarp::LogWarn("couldn't get first address for ", remote.pubkey);
|
||||
return false;
|
||||
}
|
||||
|
||||
llarp_router::llarp_router()
|
||||
: ready(false)
|
||||
, paths(this)
|
||||
|
@ -39,13 +80,11 @@ llarp_router::llarp_router()
|
|||
// set rational defaults
|
||||
this->ip4addr.sin_family = AF_INET;
|
||||
this->ip4addr.sin_port = htons(1090);
|
||||
llarp_rc_clear(&rc);
|
||||
}
|
||||
|
||||
llarp_router::~llarp_router()
|
||||
{
|
||||
llarp_dht_context_free(dht);
|
||||
llarp_rc_free(&rc);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -104,8 +143,7 @@ llarp_router::SendToOrQueue(const llarp::RouterID &remote,
|
|||
outboundMessageQueue[remote].push(std::move(msg));
|
||||
|
||||
// we don't have an open session to that router right now
|
||||
auto rc = llarp_nodedb_get_rc(nodedb, remote);
|
||||
if(rc)
|
||||
if(llarp_nodedb_get_rc(nodedb, remote, rc))
|
||||
{
|
||||
// try connecting directly as the rc is loaded from disk
|
||||
llarp_router_try_connect(this, rc, 10);
|
||||
|
@ -113,55 +151,45 @@ llarp_router::SendToOrQueue(const llarp::RouterID &remote,
|
|||
}
|
||||
|
||||
// we don't have the RC locally so do a dht lookup
|
||||
llarp_router_lookup_job *lookup = new llarp_router_lookup_job();
|
||||
lookup->user = this;
|
||||
lookup->iterative = false;
|
||||
llarp_rc_clear(&lookup->result);
|
||||
memcpy(lookup->target, remote, PUBKEYSIZE);
|
||||
lookup->hook = &llarp_router::HandleDHTLookupForSendTo;
|
||||
lookup->user = this;
|
||||
llarp_dht_lookup_router(dht, lookup);
|
||||
|
||||
dht->impl.LookupRouter(remote,
|
||||
std::bind(&llarp_router::HandleDHTLookupForSendTo,
|
||||
this, remote, std::placeholders::_1));
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
llarp_router::HandleDHTLookupForSendTo(llarp_router_lookup_job *job)
|
||||
llarp_router::HandleDHTLookupForSendTo(
|
||||
llarp::RouterID remote, const std::vector< llarp::RouterContact > &results)
|
||||
{
|
||||
llarp_router *self = static_cast< llarp_router * >(job->user);
|
||||
if(job->found)
|
||||
if(results.size())
|
||||
{
|
||||
llarp_nodedb_put_rc(self->nodedb, &job->result);
|
||||
llarp_router_try_connect(self, &job->result, 10);
|
||||
llarp_rc_free(&job->result);
|
||||
llarp_nodedb_put_rc(nodedb, results[0]);
|
||||
llarp_router_try_connect(this, results[0], 10);
|
||||
}
|
||||
else
|
||||
{
|
||||
self->DiscardOutboundFor(job->target);
|
||||
DiscardOutboundFor(remote);
|
||||
}
|
||||
delete job;
|
||||
}
|
||||
|
||||
void
|
||||
llarp_router::try_connect(fs::path rcfile)
|
||||
{
|
||||
llarp_rc remote;
|
||||
llarp_rc_new(&remote);
|
||||
if(!llarp_rc_read(rcfile.string().c_str(), &remote))
|
||||
llarp::RouterContact remote;
|
||||
if(!remote.Read(rcfile.string().c_str()))
|
||||
{
|
||||
llarp::LogError("failure to decode or verify of remote RC");
|
||||
return;
|
||||
}
|
||||
if(llarp_rc_verify_sig(&crypto, &remote))
|
||||
if(remote.VerifySignature(&crypto))
|
||||
{
|
||||
llarp::LogDebug("verified signature");
|
||||
// store into filesystem
|
||||
// TODO: should this be async?
|
||||
if(!llarp_nodedb_put_rc(nodedb, &remote))
|
||||
if(!llarp_nodedb_put_rc(nodedb, remote))
|
||||
{
|
||||
llarp::LogWarn("failed to store");
|
||||
}
|
||||
if(!llarp_router_try_connect(this, &remote, 10))
|
||||
if(!llarp_router_try_connect(this, remote, 10))
|
||||
{
|
||||
// or error?
|
||||
llarp::LogWarn("session already made");
|
||||
|
@ -169,7 +197,6 @@ llarp_router::try_connect(fs::path rcfile)
|
|||
}
|
||||
else
|
||||
llarp::LogError("failed to verify signature of RC", rcfile);
|
||||
llarp_rc_free(&remote);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -185,7 +212,7 @@ bool
|
|||
llarp_router::EnsureEncryptionKey()
|
||||
{
|
||||
return llarp_findOrCreateEncryption(
|
||||
&crypto, encryption_keyfile.string().c_str(), &this->encryption);
|
||||
&crypto, encryption_keyfile.string().c_str(), encryption);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -204,7 +231,7 @@ bool
|
|||
llarp_router::SaveRC()
|
||||
{
|
||||
llarp::LogDebug("verify RC signature");
|
||||
if(!llarp_rc_verify_sig(&crypto, &rc))
|
||||
if(!rc.VerifySignature(&crypto))
|
||||
{
|
||||
llarp::LogError("RC has bad signature not saving");
|
||||
return false;
|
||||
|
@ -213,7 +240,7 @@ llarp_router::SaveRC()
|
|||
byte_t tmp[MAX_RC_SIZE];
|
||||
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
|
||||
|
||||
if(llarp_rc_bencode(&rc, &buf))
|
||||
if(rc.BEncode(&buf))
|
||||
{
|
||||
std::ofstream f(our_rc_file.string());
|
||||
|
||||
|
@ -272,9 +299,7 @@ llarp_router::on_verify_client_rc(llarp_async_verify_rc *job)
|
|||
{
|
||||
llarp::async_verify_context *ctx =
|
||||
static_cast< llarp::async_verify_context * >(job->user);
|
||||
llarp::PubKey pk = job->rc.pubkey;
|
||||
llarp_rc_free(&job->rc);
|
||||
ctx->router->pendingEstablishJobs.erase(pk);
|
||||
ctx->router->pendingEstablishJobs.erase(job->rc.pubkey);
|
||||
delete ctx;
|
||||
}
|
||||
|
||||
|
@ -295,7 +320,6 @@ llarp_router::on_verify_server_rc(llarp_async_verify_rc *job)
|
|||
if(session)
|
||||
session->close();
|
||||
}
|
||||
llarp_rc_free(&job->rc);
|
||||
router->pendingEstablishJobs.erase(pk);
|
||||
router->DiscardOutboundFor(pk);
|
||||
return;
|
||||
|
@ -305,16 +329,10 @@ llarp_router::on_verify_server_rc(llarp_async_verify_rc *job)
|
|||
llarp::LogDebug("rc verified and saved to nodedb");
|
||||
|
||||
// refresh valid routers RC value if it's there
|
||||
auto v = router->validRouters.find(pk);
|
||||
if(v != router->validRouters.end())
|
||||
{
|
||||
// free previous RC members
|
||||
llarp_rc_free(&v->second);
|
||||
}
|
||||
router->validRouters[pk] = job->rc;
|
||||
|
||||
// track valid router in dht
|
||||
__llarp_dht_put_peer(router->dht, &router->validRouters[pk]);
|
||||
router->dht->impl.nodes->PutNode(job->rc);
|
||||
|
||||
// this was an outbound establish job
|
||||
if(ctx->establish_job)
|
||||
|
@ -342,42 +360,31 @@ llarp_router::handle_router_ticker(void *user, uint64_t orig, uint64_t left)
|
|||
void
|
||||
llarp_router::TryEstablishTo(const llarp::RouterID &remote)
|
||||
{
|
||||
auto rc = llarp_nodedb_get_rc(nodedb, remote);
|
||||
if(rc)
|
||||
llarp::RouterContact rc;
|
||||
if(llarp_nodedb_get_rc(nodedb, remote, rc))
|
||||
{
|
||||
// try connecting
|
||||
// try connecting async
|
||||
llarp_router_try_connect(this, rc, 5);
|
||||
}
|
||||
else
|
||||
{
|
||||
// dht lookup as we don't know it
|
||||
llarp_router_lookup_job *lookup = new llarp_router_lookup_job;
|
||||
llarp_rc_clear(&lookup->result);
|
||||
memcpy(lookup->target, remote, PUBKEYSIZE);
|
||||
lookup->hook = &llarp_router::HandleDHTLookupForTryEstablishTo;
|
||||
lookup->iterative = false;
|
||||
lookup->user = this;
|
||||
llarp_dht_lookup_router(dht, lookup);
|
||||
dht->impl.LookupRouter(
|
||||
remote,
|
||||
std::bind(&llarp_router::HandleDHTLookupForTryEstablishTo, this,
|
||||
std::placeholders::_1));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
llarp_router::HandleDHTLookupForTryEstablishTo(llarp_router_lookup_job *job)
|
||||
llarp_router::HandleDHTLookupForTryEstablishTo(
|
||||
const std::vector< llarp::RouterContact > &results)
|
||||
{
|
||||
if(job->found)
|
||||
if(results.size())
|
||||
{
|
||||
llarp_router *self = static_cast< llarp_router * >(job->user);
|
||||
llarp_nodedb_put_rc(self->nodedb, &job->result);
|
||||
llarp_router_try_connect(self, &job->result, 5);
|
||||
llarp_rc_free(&job->result);
|
||||
llarp_nodedb_put_rc(nodedb, results[0]);
|
||||
llarp_router_try_connect(this, results[0], 5);
|
||||
}
|
||||
delete job;
|
||||
}
|
||||
|
||||
void
|
||||
llarp_router::HandleExploritoryPathBuildStarted(llarp_pathbuild_job *job)
|
||||
{
|
||||
delete job;
|
||||
}
|
||||
|
||||
size_t
|
||||
|
@ -487,9 +494,7 @@ llarp_router::SessionClosed(const llarp::RouterID &remote)
|
|||
auto itr = validRouters.find(remote);
|
||||
if(itr == validRouters.end())
|
||||
return;
|
||||
|
||||
__llarp_dht_remove_peer(dht, remote);
|
||||
llarp_rc_free(&itr->second);
|
||||
validRouters.erase(itr);
|
||||
}
|
||||
|
||||
|
@ -585,7 +590,7 @@ llarp_router::DiscardOutboundFor(const llarp::RouterID &remote)
|
|||
}
|
||||
|
||||
bool
|
||||
llarp_router::GetRandomConnectedRouter(llarp_rc *result) const
|
||||
llarp_router::GetRandomConnectedRouter(llarp::RouterContact &result) const
|
||||
{
|
||||
auto sz = validRouters.size();
|
||||
if(sz)
|
||||
|
@ -593,21 +598,25 @@ llarp_router::GetRandomConnectedRouter(llarp_rc *result) const
|
|||
auto itr = validRouters.begin();
|
||||
if(sz > 1)
|
||||
std::advance(itr, llarp_randint() % sz);
|
||||
llarp_rc_copy(result, &itr->second);
|
||||
result = itr->second;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
llarp_router::async_verify_RC(llarp_rc *rc, bool isExpectingClient,
|
||||
llarp_router::async_verify_RC(const llarp::RouterContact &rc,
|
||||
bool isExpectingClient,
|
||||
llarp_link_establish_job *establish_job)
|
||||
{
|
||||
llarp_async_verify_rc *job = new llarp_async_verify_rc();
|
||||
job->user = new llarp::async_verify_context{this, establish_job};
|
||||
job->rc = {};
|
||||
job->valid = false;
|
||||
job->hook = nullptr;
|
||||
llarp_async_verify_rc *job = new llarp_async_verify_rc();
|
||||
llarp::async_verify_context *ctx = new llarp::async_verify_context();
|
||||
ctx->router = this;
|
||||
ctx->establish_job = establish_job;
|
||||
job->user = ctx;
|
||||
job->rc = rc;
|
||||
job->valid = false;
|
||||
job->hook = nullptr;
|
||||
|
||||
job->nodedb = nodedb;
|
||||
job->logic = logic;
|
||||
|
@ -615,7 +624,6 @@ llarp_router::async_verify_RC(llarp_rc *rc, bool isExpectingClient,
|
|||
job->cryptoworker = tp;
|
||||
job->diskworker = disk;
|
||||
|
||||
llarp_rc_copy(&job->rc, rc);
|
||||
if(isExpectingClient)
|
||||
job->hook = &llarp_router::on_verify_client_rc;
|
||||
else
|
||||
|
@ -627,10 +635,6 @@ void
|
|||
llarp_router::Run()
|
||||
{
|
||||
// zero out router contact
|
||||
llarp::Zero(&rc, sizeof(llarp_rc));
|
||||
// fill our address list
|
||||
rc.addrs = llarp_ai_list_new();
|
||||
|
||||
sockaddr *dest = (sockaddr *)&this->ip4addr;
|
||||
llarp::Addr publicAddr(*dest);
|
||||
if(this->publicOverride)
|
||||
|
@ -644,8 +648,8 @@ llarp_router::Run()
|
|||
llarp::LogInfo("You have ", inboundLinks.size(), " inbound links");
|
||||
for(auto link : inboundLinks)
|
||||
{
|
||||
llarp_ai addr;
|
||||
link->get_our_address(&addr);
|
||||
llarp::AddressInfo addr;
|
||||
link->get_our_address(addr);
|
||||
llarp::Addr a(addr);
|
||||
if(this->publicOverride && a.sameAddr(publicAddr))
|
||||
{
|
||||
|
@ -654,7 +658,7 @@ llarp_router::Run()
|
|||
if(!a.isPrivate())
|
||||
{
|
||||
llarp::LogInfo("Loading Addr: ", a, " into our RC");
|
||||
llarp_ai_list_pushback(rc.addrs, &addr);
|
||||
rc.addrs.push_back(addr);
|
||||
}
|
||||
};
|
||||
if(this->publicOverride)
|
||||
|
@ -674,47 +678,27 @@ llarp_router::Run()
|
|||
return;
|
||||
}
|
||||
link = inboundLinks.front();
|
||||
/*
|
||||
// create a new link
|
||||
link = new llarp_link;
|
||||
llarp::Zero(link, sizeof(llarp_link));
|
||||
|
||||
llarp_iwp_args args = {
|
||||
.crypto = &this->crypto,
|
||||
.logic = this->logic,
|
||||
.cryptoworker = this->tp,
|
||||
.router = this,
|
||||
.keyfile = this->transport_keyfile.c_str(),
|
||||
};
|
||||
iwp_link_init(link, args);
|
||||
if(llarp_link_initialized(link))
|
||||
{
|
||||
|
||||
}
|
||||
*/
|
||||
}
|
||||
link->get_our_address(&this->addrInfo);
|
||||
link->get_our_address(this->addrInfo);
|
||||
// override ip and port
|
||||
this->addrInfo.ip = *publicAddr.addr6();
|
||||
this->addrInfo.port = publicAddr.port();
|
||||
llarp::LogInfo("Loaded our public ", publicAddr, " override into RC!");
|
||||
// we need the link to set the pubkey
|
||||
llarp_ai_list_pushback(rc.addrs, &this->addrInfo);
|
||||
rc.addrs.push_back(this->addrInfo);
|
||||
}
|
||||
// set public encryption key
|
||||
llarp_rc_set_pubenckey(&rc, llarp::seckey_topublic(encryption));
|
||||
|
||||
char ftmp[68] = {0};
|
||||
const char *hexKey = llarp::HexEncode< llarp::PubKey, decltype(ftmp) >(
|
||||
llarp::seckey_topublic(encryption), ftmp);
|
||||
llarp::LogInfo("Your Encryption pubkey ", hexKey);
|
||||
rc.enckey = llarp::seckey_topublic(encryption);
|
||||
llarp::LogInfo("Your Encryption pubkey ", rc.enckey);
|
||||
// set public signing key
|
||||
llarp_rc_set_pubsigkey(&rc, llarp::seckey_topublic(identity));
|
||||
hexKey = llarp::HexEncode< llarp::PubKey, decltype(ftmp) >(
|
||||
llarp::seckey_topublic(identity), ftmp);
|
||||
llarp::LogInfo("Your Identity pubkey ", hexKey);
|
||||
rc.pubkey = llarp::seckey_topublic(identity);
|
||||
llarp::LogInfo("Your Identity pubkey ", rc.pubkey);
|
||||
|
||||
llarp_rc_sign(&crypto, identity, &rc);
|
||||
if(!rc.Sign(&crypto, identity))
|
||||
{
|
||||
llarp::LogError("failed to sign rc");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!SaveRC())
|
||||
{
|
||||
|
@ -865,166 +849,6 @@ llarp_run_router(struct llarp_router *router, struct llarp_nodedb *nodedb)
|
|||
router->Run();
|
||||
}
|
||||
|
||||
bool
|
||||
llarp_router_try_connect(struct llarp_router *router, struct llarp_rc *remote,
|
||||
uint16_t numretries)
|
||||
{
|
||||
char ftmp[68] = {0};
|
||||
const char *hexname =
|
||||
llarp::HexEncode< llarp::PubKey, decltype(ftmp) >(remote->pubkey, ftmp);
|
||||
|
||||
// do we already have a pending job for this remote?
|
||||
if(router->HasPendingConnectJob(remote->pubkey))
|
||||
{
|
||||
llarp::LogDebug("We have pending connect jobs to ", hexname);
|
||||
return false;
|
||||
}
|
||||
// try first address only
|
||||
llarp_ai addr;
|
||||
if(llarp_ai_list_index(remote->addrs, 0, &addr))
|
||||
{
|
||||
auto link = router->outboundLink;
|
||||
auto itr = router->pendingEstablishJobs.insert(
|
||||
std::make_pair(remote->pubkey, llarp_link_establish_job()));
|
||||
auto job = &itr.first->second;
|
||||
llarp_ai_copy(&job->ai, &addr);
|
||||
memcpy(job->pubkey, remote->pubkey, PUBKEYSIZE);
|
||||
job->retries = numretries;
|
||||
job->timeout = 10000;
|
||||
job->result = &llarp_router::on_try_connect_result;
|
||||
// give router as user pointer
|
||||
job->user = router;
|
||||
// try establishing
|
||||
link->try_establish(job);
|
||||
return true;
|
||||
}
|
||||
llarp::LogWarn("couldn't get first address for ", hexname);
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
llarp_rc_clear(struct llarp_rc *rc)
|
||||
{
|
||||
// zero out router contact
|
||||
llarp::Zero(rc, sizeof(llarp_rc));
|
||||
}
|
||||
|
||||
void
|
||||
llarp_rc_set_pubenckey(struct llarp_rc *rc, const uint8_t *pubenckey)
|
||||
{
|
||||
// set public encryption key
|
||||
memcpy(rc->enckey, pubenckey, PUBKEYSIZE);
|
||||
}
|
||||
|
||||
void
|
||||
llarp_rc_set_pubsigkey(struct llarp_rc *rc, const uint8_t *pubsigkey)
|
||||
{
|
||||
// set public signing key
|
||||
memcpy(rc->pubkey, pubsigkey, PUBKEYSIZE);
|
||||
}
|
||||
|
||||
void
|
||||
llarp_rc_set_pubkey(struct llarp_rc *rc, const uint8_t *pubenckey,
|
||||
const uint8_t *pubsigkey)
|
||||
{
|
||||
// set public encryption key
|
||||
llarp_rc_set_pubenckey(rc, pubenckey);
|
||||
// set public signing key
|
||||
llarp_rc_set_pubsigkey(rc, pubsigkey);
|
||||
}
|
||||
|
||||
bool
|
||||
llarp_rc_read(const char *fpath, llarp_rc *result)
|
||||
{
|
||||
fs::path our_rc_file(fpath);
|
||||
std::error_code ec;
|
||||
if(!fs::exists(our_rc_file, ec))
|
||||
{
|
||||
printf("File[%s] not found\n", fpath);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::ifstream f(our_rc_file.string(), std::ios::binary);
|
||||
|
||||
if(!f.is_open())
|
||||
{
|
||||
printf("Can't open file [%s]\n", fpath);
|
||||
return false;
|
||||
}
|
||||
byte_t tmp[MAX_RC_SIZE];
|
||||
llarp_buffer_t buf = llarp::StackBuffer< decltype(tmp) >(tmp);
|
||||
f.seekg(0, std::ios::end);
|
||||
size_t sz = f.tellg();
|
||||
f.seekg(0, std::ios::beg);
|
||||
|
||||
if(sz > buf.sz)
|
||||
return false;
|
||||
|
||||
f.read((char *)buf.base, sz);
|
||||
// printf("contents[%s]\n", tmpc);
|
||||
llarp::Zero(result, sizeof(llarp_rc));
|
||||
if(!llarp_rc_bdecode(result, &buf))
|
||||
{
|
||||
llarp::LogError("Can't decode ", fpath);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
llarp_rc_addr_list_iter(struct llarp_ai_list_iter *iter, struct llarp_ai *ai)
|
||||
{
|
||||
struct llarp_rc *rc = (llarp_rc *)iter->user;
|
||||
llarp_ai_list_pushback(rc->addrs, ai);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
llarp_rc_set_addrs(struct llarp_rc *rc, struct llarp_alloc *mem,
|
||||
struct llarp_ai_list *addr)
|
||||
{
|
||||
rc->addrs = llarp_ai_list_new();
|
||||
struct llarp_ai_list_iter ai_itr;
|
||||
ai_itr.user = rc;
|
||||
ai_itr.visit = &llarp_rc_addr_list_iter;
|
||||
llarp_ai_list_iterate(addr, &ai_itr);
|
||||
}
|
||||
|
||||
bool
|
||||
llarp_rc_write(struct llarp_rc *rc, const char *fpath)
|
||||
{
|
||||
fs::path our_rc_file(fpath);
|
||||
byte_t tmp[MAX_RC_SIZE];
|
||||
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
|
||||
|
||||
if(llarp_rc_bencode(rc, &buf))
|
||||
{
|
||||
std::ofstream f(our_rc_file.string(), std::ios::binary);
|
||||
if(f.is_open())
|
||||
{
|
||||
f.write((char *)buf.base, buf.cur - buf.base);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
llarp_rc_sign(llarp_crypto *crypto, const byte_t *seckey, struct llarp_rc *rc)
|
||||
{
|
||||
byte_t buf[MAX_RC_SIZE];
|
||||
auto signbuf = llarp::StackBuffer< decltype(buf) >(buf);
|
||||
// zero out previous signature
|
||||
llarp::Zero(rc->signature, sizeof(rc->signature));
|
||||
// encode
|
||||
if(llarp_rc_bencode(rc, &signbuf))
|
||||
{
|
||||
// sign
|
||||
signbuf.sz = signbuf.cur - signbuf.base;
|
||||
crypto->sign(rc->signature, seckey, signbuf);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
llarp_stop_router(struct llarp_router *router)
|
||||
{
|
||||
|
@ -1052,14 +876,6 @@ llarp_free_router(struct llarp_router **router)
|
|||
*router = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
llarp_router_override_path_selection(struct llarp_router *router,
|
||||
llarp_pathbuilder_select_hop_func func)
|
||||
{
|
||||
if(func)
|
||||
router->selectHopFunc = func;
|
||||
}
|
||||
|
||||
bool
|
||||
llarp_findOrCreateIdentity(llarp_crypto *crypto, const char *fpath,
|
||||
byte_t *secretkey)
|
||||
|
@ -1226,13 +1042,9 @@ namespace llarp
|
|||
{
|
||||
if(StrEq(key, "nickname"))
|
||||
{
|
||||
if(llarp_rc_set_nickname(&self->rc, val))
|
||||
{
|
||||
// set logger name here
|
||||
_glog.nodeName = self->rc.Nick();
|
||||
}
|
||||
else
|
||||
llarp::LogWarn("failed to set nickname to ", val);
|
||||
self->rc.SetNick(val);
|
||||
// set logger name here
|
||||
_glog.nodeName = self->rc.Nick();
|
||||
}
|
||||
if(StrEq(key, "encryption-privkey"))
|
||||
{
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#ifndef LLARP_ROUTER_HPP
|
||||
#define LLARP_ROUTER_HPP
|
||||
#include <llarp/dht.h>
|
||||
#include <llarp/nodedb.h>
|
||||
#include <llarp/router_contact.h>
|
||||
#include <llarp/nodedb.hpp>
|
||||
#include <llarp/router_contact.hpp>
|
||||
#include <llarp/path.hpp>
|
||||
|
||||
#include <functional>
|
||||
|
@ -24,25 +24,12 @@
|
|||
/** 2^15 bytes */
|
||||
#define MAX_LINK_MSG_SIZE (32768)
|
||||
|
||||
// TODO: unused. remove?
|
||||
// struct try_connect_ctx
|
||||
// {
|
||||
// llarp_router *router = nullptr;
|
||||
// llarp_ai addr;
|
||||
// };
|
||||
|
||||
// // forward declare
|
||||
// namespace path
|
||||
// {
|
||||
// struct TransitHop;
|
||||
// }
|
||||
|
||||
struct llarp_link;
|
||||
struct llarp_link_session_iter;
|
||||
|
||||
bool
|
||||
llarp_findOrCreateEncryption(llarp_crypto *crypto, const char *fpath,
|
||||
llarp::SecretKey *encryption);
|
||||
llarp::SecretKey &encryption);
|
||||
|
||||
struct llarp_router
|
||||
{
|
||||
|
@ -62,12 +49,12 @@ struct llarp_router
|
|||
fs::path our_rc_file = "rc.signed";
|
||||
|
||||
// our router contact
|
||||
llarp_rc rc;
|
||||
llarp::RouterContact rc;
|
||||
|
||||
// our ipv4 public setting
|
||||
bool publicOverride = false;
|
||||
struct sockaddr_in ip4addr;
|
||||
llarp_ai addrInfo;
|
||||
llarp::AddressInfo addrInfo;
|
||||
|
||||
llarp_ev_loop *netloop;
|
||||
llarp_threadpool *tp;
|
||||
|
@ -92,9 +79,6 @@ struct llarp_router
|
|||
llarp::InboundMessageParser inbound_link_msg_parser;
|
||||
llarp::routing::InboundMessageParser inbound_routing_msg_parser;
|
||||
|
||||
llarp_pathbuilder_select_hop_func selectHopFunc = nullptr;
|
||||
llarp_pathbuilder_context *explorePool = nullptr;
|
||||
|
||||
llarp::service::Context hiddenServiceContext;
|
||||
|
||||
llarp_link *outboundLink = nullptr;
|
||||
|
@ -107,7 +91,7 @@ struct llarp_router
|
|||
std::map< llarp::RouterID, MessageQueue > outboundMessageQueue;
|
||||
|
||||
/// loki verified routers
|
||||
std::map< llarp::RouterID, llarp_rc > validRouters;
|
||||
std::map< llarp::RouterID, llarp::RouterContact > validRouters;
|
||||
|
||||
// pending establishing session with routers
|
||||
std::map< llarp::PubKey, llarp_link_establish_job > pendingEstablishJobs;
|
||||
|
@ -222,12 +206,20 @@ struct llarp_router
|
|||
NumberOfConnectedRouters() const;
|
||||
|
||||
bool
|
||||
GetRandomConnectedRouter(llarp_rc *result) const;
|
||||
GetRandomConnectedRouter(llarp::RouterContact &result) const;
|
||||
|
||||
void
|
||||
async_verify_RC(llarp_rc *rc, bool isExpectingClient,
|
||||
async_verify_RC(const llarp::RouterContact &rc, bool isExpectingClient,
|
||||
llarp_link_establish_job *job = nullptr);
|
||||
|
||||
void
|
||||
HandleDHTLookupForSendTo(llarp::RouterID remote,
|
||||
const std::vector< llarp::RouterContact > &results);
|
||||
|
||||
void
|
||||
HandleDHTLookupForTryEstablishTo(
|
||||
const std::vector< llarp::RouterContact > &results);
|
||||
|
||||
static bool
|
||||
iter_try_connect(llarp_router_link_iter *i, llarp_router *router,
|
||||
llarp_link *l);
|
||||
|
@ -253,15 +245,6 @@ struct llarp_router
|
|||
|
||||
static void
|
||||
HandleAsyncLoadRCForSendTo(llarp_async_load_rc *async);
|
||||
|
||||
static void
|
||||
HandleDHTLookupForSendTo(llarp_router_lookup_job *job);
|
||||
|
||||
static void
|
||||
HandleExploritoryPathBuildStarted(llarp_pathbuild_job *job);
|
||||
|
||||
static void
|
||||
HandleDHTLookupForTryEstablishTo(llarp_router_lookup_job *job);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,264 +1,98 @@
|
|||
#include <llarp/bencode.h>
|
||||
#include <llarp/router_contact.h>
|
||||
#include <llarp/bencode.hpp>
|
||||
#include <llarp/router_contact.hpp>
|
||||
#include <llarp/version.h>
|
||||
#include <llarp/crypto.hpp>
|
||||
#include "buffer.hpp"
|
||||
#include "logger.hpp"
|
||||
#include "mem.hpp"
|
||||
|
||||
bool
|
||||
llarp_rc_new(struct llarp_rc *rc)
|
||||
namespace llarp
|
||||
{
|
||||
rc->addrs = llarp_ai_list_new();
|
||||
rc->exits = llarp_xi_list_new();
|
||||
rc->last_updated = 0;
|
||||
llarp::Zero(rc->nickname, sizeof(rc->nickname));
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
llarp_rc_free(struct llarp_rc *rc)
|
||||
{
|
||||
if(rc->exits)
|
||||
llarp_xi_list_free(rc->exits);
|
||||
if(rc->addrs)
|
||||
llarp_ai_list_free(rc->addrs);
|
||||
|
||||
rc->exits = 0;
|
||||
rc->addrs = 0;
|
||||
}
|
||||
|
||||
struct llarp_rc_decoder
|
||||
{
|
||||
struct llarp_rc *rc;
|
||||
struct llarp_alloc *mem;
|
||||
};
|
||||
|
||||
static bool
|
||||
llarp_rc_decode_dict(struct dict_reader *r, llarp_buffer_t *key)
|
||||
{
|
||||
uint64_t v;
|
||||
llarp_buffer_t strbuf;
|
||||
llarp_rc *rc = static_cast< llarp_rc * >(r->user);
|
||||
|
||||
if(!key)
|
||||
return true;
|
||||
|
||||
if(llarp_buffer_eq(*key, "a"))
|
||||
bool
|
||||
RouterContact::BEncode(llarp_buffer_t *buf) const
|
||||
{
|
||||
if(rc->addrs)
|
||||
{
|
||||
llarp_ai_list_free(rc->addrs);
|
||||
}
|
||||
rc->addrs = llarp_ai_list_new();
|
||||
return llarp_ai_list_bdecode(rc->addrs, r->buffer);
|
||||
}
|
||||
|
||||
if(llarp_buffer_eq(*key, "k"))
|
||||
{
|
||||
if(!bencode_read_string(r->buffer, &strbuf))
|
||||
/* write dict begin */
|
||||
if(!bencode_start_dict(buf))
|
||||
return false;
|
||||
if(strbuf.sz != PUBKEYSIZE)
|
||||
return false;
|
||||
memcpy(rc->pubkey, strbuf.base, PUBKEYSIZE);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(llarp_buffer_eq(*key, "n"))
|
||||
{
|
||||
if(!bencode_read_string(r->buffer, &strbuf))
|
||||
return false;
|
||||
if(strbuf.sz > sizeof(rc->nickname))
|
||||
return false;
|
||||
llarp::Zero(rc->nickname, sizeof(rc->nickname));
|
||||
memcpy(rc->nickname, strbuf.base, strbuf.sz);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(llarp_buffer_eq(*key, "p"))
|
||||
{
|
||||
if(!bencode_read_string(r->buffer, &strbuf))
|
||||
return false;
|
||||
if(strbuf.sz != PUBKEYSIZE)
|
||||
return false;
|
||||
memcpy(rc->enckey, strbuf.base, PUBKEYSIZE);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(llarp_buffer_eq(*key, "u"))
|
||||
{
|
||||
if(!bencode_read_integer(r->buffer, &rc->last_updated))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(llarp_buffer_eq(*key, "v"))
|
||||
{
|
||||
if(!bencode_read_integer(r->buffer, &v))
|
||||
return false;
|
||||
return v == LLARP_PROTO_VERSION;
|
||||
}
|
||||
|
||||
if(llarp_buffer_eq(*key, "x"))
|
||||
{
|
||||
if(rc->exits)
|
||||
{
|
||||
llarp_xi_list_free(rc->exits);
|
||||
}
|
||||
rc->exits = llarp_xi_list_new();
|
||||
return llarp_xi_list_bdecode(rc->exits, r->buffer);
|
||||
}
|
||||
|
||||
if(llarp_buffer_eq(*key, "z"))
|
||||
{
|
||||
if(!bencode_read_string(r->buffer, &strbuf))
|
||||
return false;
|
||||
if(strbuf.sz != SIGSIZE)
|
||||
return false;
|
||||
memcpy(rc->signature, strbuf.base, SIGSIZE);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
llarp_rc_is_public_router(const struct llarp_rc *const rc)
|
||||
{
|
||||
return rc->addrs && llarp_ai_list_size(rc->addrs) > 0;
|
||||
}
|
||||
|
||||
bool
|
||||
llarp_rc_set_nickname(struct llarp_rc *rc, const char *nick)
|
||||
{
|
||||
strncpy((char *)rc->nickname, nick, sizeof(rc->nickname));
|
||||
/// TODO: report nickname truncation
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
llarp_rc_copy(struct llarp_rc *dst, const struct llarp_rc *src)
|
||||
{
|
||||
llarp_rc_free(dst);
|
||||
llarp_rc_clear(dst);
|
||||
memcpy(dst->pubkey, src->pubkey, PUBKEYSIZE);
|
||||
memcpy(dst->enckey, src->enckey, PUBKEYSIZE);
|
||||
memcpy(dst->signature, src->signature, SIGSIZE);
|
||||
dst->last_updated = src->last_updated;
|
||||
|
||||
if(src->addrs)
|
||||
{
|
||||
dst->addrs = llarp_ai_list_new();
|
||||
llarp_ai_list_copy(dst->addrs, src->addrs);
|
||||
}
|
||||
if(src->exits)
|
||||
{
|
||||
dst->exits = llarp_xi_list_new();
|
||||
llarp_xi_list_copy(dst->exits, src->exits);
|
||||
}
|
||||
memcpy(dst->nickname, src->nickname, sizeof(dst->nickname));
|
||||
}
|
||||
|
||||
bool
|
||||
llarp_rc_bdecode(struct llarp_rc *rc, llarp_buffer_t *buff)
|
||||
{
|
||||
dict_reader r = {buff, rc, &llarp_rc_decode_dict};
|
||||
return bencode_read_dict(buff, &r);
|
||||
}
|
||||
|
||||
bool
|
||||
llarp_rc_verify_sig(struct llarp_crypto *crypto, struct llarp_rc *rc)
|
||||
{
|
||||
// maybe we should copy rc before modifying it
|
||||
// would that make it more thread safe?
|
||||
// jeff agrees
|
||||
bool result = false;
|
||||
llarp::Signature sig;
|
||||
byte_t tmp[MAX_RC_SIZE];
|
||||
|
||||
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
|
||||
// copy sig
|
||||
memcpy(sig, rc->signature, SIGSIZE);
|
||||
// zero sig
|
||||
size_t sz = 0;
|
||||
while(sz < SIGSIZE)
|
||||
rc->signature[sz++] = 0;
|
||||
|
||||
// bencode
|
||||
if(llarp_rc_bencode(rc, &buf))
|
||||
{
|
||||
buf.sz = buf.cur - buf.base;
|
||||
buf.cur = buf.base;
|
||||
result = crypto->verify(rc->pubkey, buf, sig);
|
||||
}
|
||||
else
|
||||
llarp::LogWarn("RC encode failed");
|
||||
// restore sig
|
||||
memcpy(rc->signature, sig, SIGSIZE);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool
|
||||
llarp_rc_bencode(const struct llarp_rc *rc, llarp_buffer_t *buff)
|
||||
{
|
||||
/* write dict begin */
|
||||
if(!bencode_start_dict(buff))
|
||||
return false;
|
||||
|
||||
if(rc->addrs)
|
||||
{
|
||||
/* write ai if they exist */
|
||||
if(!bencode_write_bytestring(buff, "a", 1))
|
||||
if(!bencode_write_bytestring(buf, "a", 1))
|
||||
return false;
|
||||
if(!llarp_ai_list_bencode(rc->addrs, buff))
|
||||
if(!BEncodeWriteList(addrs.begin(), addrs.end(), buf))
|
||||
return false;
|
||||
}
|
||||
|
||||
/* write signing pubkey */
|
||||
if(!bencode_write_bytestring(buff, "k", 1))
|
||||
return false;
|
||||
if(!bencode_write_bytestring(buff, rc->pubkey, PUBKEYSIZE))
|
||||
return false;
|
||||
|
||||
auto nicklen = strnlen((char *)rc->nickname, sizeof(rc->nickname));
|
||||
if(nicklen)
|
||||
{
|
||||
/* write nickname */
|
||||
if(!bencode_write_bytestring(buff, "n", 1))
|
||||
/* write signing pubkey */
|
||||
if(!bencode_write_bytestring(buf, "k", 1))
|
||||
return false;
|
||||
if(!bencode_write_bytestring(buff, rc->nickname, nicklen))
|
||||
if(!pubkey.BEncode(buf))
|
||||
return false;
|
||||
}
|
||||
|
||||
/* write encryption pubkey */
|
||||
if(!bencode_write_bytestring(buff, "p", 1))
|
||||
return false;
|
||||
if(!bencode_write_bytestring(buff, rc->enckey, PUBKEYSIZE))
|
||||
return false;
|
||||
std::string nick = Nick();
|
||||
if(nick.size())
|
||||
{
|
||||
/* write nickname */
|
||||
if(!bencode_write_bytestring(buf, "n", 1))
|
||||
return false;
|
||||
if(!bencode_write_bytestring(buf, nick.c_str(), nick.size()))
|
||||
return false;
|
||||
}
|
||||
|
||||
/* write last updated */
|
||||
if(!bencode_write_bytestring(buff, "u", 1))
|
||||
return false;
|
||||
if(!bencode_write_uint64(buff, rc->last_updated))
|
||||
return false;
|
||||
/* write encryption pubkey */
|
||||
if(!bencode_write_bytestring(buf, "p", 1))
|
||||
return false;
|
||||
if(!enckey.BEncode(buf))
|
||||
return false;
|
||||
|
||||
/* write version */
|
||||
if(!bencode_write_version_entry(buff))
|
||||
return false;
|
||||
/* write last updated */
|
||||
if(!bencode_write_bytestring(buf, "u", 1))
|
||||
return false;
|
||||
if(!bencode_write_uint64(buf, last_updated))
|
||||
return false;
|
||||
|
||||
/* write version */
|
||||
if(!bencode_write_version_entry(buf))
|
||||
return false;
|
||||
|
||||
if(rc->exits)
|
||||
{
|
||||
/* write ai if they exist */
|
||||
if(!bencode_write_bytestring(buff, "x", 1))
|
||||
if(!bencode_write_bytestring(buf, "x", 1))
|
||||
return false;
|
||||
if(!llarp_xi_list_bencode(rc->exits, buff))
|
||||
if(!BEncodeWriteList(exits.begin(), exits.end(), buf))
|
||||
return false;
|
||||
|
||||
/* write signature */
|
||||
if(!bencode_write_bytestring(buf, "z", 1))
|
||||
return false;
|
||||
if(!signature.BEncode(buf))
|
||||
return false;
|
||||
return bencode_end(buf);
|
||||
}
|
||||
|
||||
/* write signature */
|
||||
if(!bencode_write_bytestring(buff, "z", 1))
|
||||
return false;
|
||||
if(!bencode_write_bytestring(buff, rc->signature, SIGSIZE))
|
||||
return false;
|
||||
return bencode_end(buff);
|
||||
}
|
||||
bool
|
||||
RouterContact::DecodeKey(llarp_buffer_t key, llarp_buffer_t *buf)
|
||||
{
|
||||
bool read = false;
|
||||
if(!BEncodeMaybeReadDictList("a", addrs, read, key, buf))
|
||||
return false;
|
||||
|
||||
if(!BEncodeMaybeReadDictEntry("k", pubkey, read, key, buf))
|
||||
return false;
|
||||
|
||||
if(!BEncodeMaybeReadDictEntry("n", nickname, read, key, buf))
|
||||
return false;
|
||||
|
||||
if(!BEncodeMaybeReadDictEntry("p", enckey, read, key, buf))
|
||||
return false;
|
||||
|
||||
if(!BEncodeMaybeReadDictInt("u", last_updated, read, key, buf))
|
||||
return false;
|
||||
|
||||
if(!BEncodeMaybeReadDictList("x", exits, read, key, buf))
|
||||
return false;
|
||||
|
||||
if(!BEncodeMaybeReadDictEntry("z", signature, read, key, buf))
|
||||
return false;
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
} // namespace llarp
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
#ifndef LLARP_RC_HPP
|
||||
#define LLARP_RC_HPP
|
||||
#include <llarp/router_contact.h>
|
||||
|
||||
#endif
|
|
@ -11,7 +11,7 @@ namespace llarp
|
|||
namespace service
|
||||
{
|
||||
Endpoint::Endpoint(const std::string& name, llarp_router* r)
|
||||
: llarp_pathbuilder_context(r, r->dht, 2, 4), m_Router(r), m_Name(name)
|
||||
: path::Builder(r, r->dht, 2, 4), m_Router(r), m_Name(name)
|
||||
{
|
||||
m_Tag.Zero();
|
||||
}
|
||||
|
@ -594,8 +594,7 @@ namespace llarp
|
|||
job->diskworker = m_Router->disk;
|
||||
job->logic = nullptr;
|
||||
job->hook = nullptr;
|
||||
llarp_rc_clear(&job->rc);
|
||||
llarp_rc_copy(&job->rc, &msg->R[0]);
|
||||
job->rc = msg->R[0];
|
||||
llarp_nodedb_async_verify(job);
|
||||
return true;
|
||||
}
|
||||
|
@ -607,7 +606,8 @@ namespace llarp
|
|||
{
|
||||
if(router.IsZero())
|
||||
return;
|
||||
if(!llarp_nodedb_get_rc(m_Router->nodedb, router))
|
||||
RouterContact rc;
|
||||
if(!llarp_nodedb_get_rc(m_Router->nodedb, router, rc))
|
||||
{
|
||||
if(m_PendingRouters.find(router) == m_PendingRouters.end())
|
||||
{
|
||||
|
@ -712,8 +712,7 @@ namespace llarp
|
|||
|
||||
Endpoint::OutboundContext::OutboundContext(const IntroSet& intro,
|
||||
Endpoint* parent)
|
||||
: llarp_pathbuilder_context(parent->m_Router, parent->m_Router->dht, 2,
|
||||
4)
|
||||
: path::Builder(parent->m_Router, parent->m_Router->dht, 2, 4)
|
||||
, currentIntroSet(intro)
|
||||
, m_Parent(parent)
|
||||
|
||||
|
@ -976,15 +975,14 @@ namespace llarp
|
|||
}
|
||||
|
||||
bool
|
||||
Endpoint::OutboundContext::SelectHop(llarp_nodedb* db, llarp_rc* prev,
|
||||
llarp_rc* cur, size_t hop)
|
||||
Endpoint::OutboundContext::SelectHop(llarp_nodedb* db,
|
||||
const RouterContact& prev,
|
||||
RouterContact& cur, size_t hop)
|
||||
{
|
||||
if(hop == numHops - 1)
|
||||
{
|
||||
auto localcopy = llarp_nodedb_get_rc(db, selectedIntro.router);
|
||||
if(localcopy)
|
||||
if(llarp_nodedb_get_rc(db, selectedIntro.router, cur))
|
||||
{
|
||||
llarp_rc_copy(cur, localcopy);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
@ -999,7 +997,7 @@ namespace llarp
|
|||
}
|
||||
}
|
||||
else
|
||||
return llarp_pathbuilder_context::SelectHop(db, prev, cur, hop);
|
||||
return path::Builder::SelectHop(db, prev, cur, hop);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
|
|
|
@ -49,7 +49,7 @@ namespace llarp
|
|||
}
|
||||
for(;;)
|
||||
{
|
||||
llarp_thread_job job;
|
||||
Job_t job;
|
||||
{
|
||||
lock_t lock(this->queue_mutex);
|
||||
this->condition.WaitUntil(
|
||||
|
@ -59,18 +59,15 @@ namespace llarp
|
|||
// discard pending jobs
|
||||
while(this->jobs.size())
|
||||
{
|
||||
delete this->jobs.top().job;
|
||||
this->jobs.pop();
|
||||
}
|
||||
return;
|
||||
}
|
||||
job.user = this->jobs.top().job->user;
|
||||
job.work = this->jobs.top().job->work;
|
||||
delete this->jobs.top().job;
|
||||
job = std::move(this->jobs.top());
|
||||
this->jobs.pop();
|
||||
}
|
||||
// do work
|
||||
job.work(job.user);
|
||||
job();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -104,8 +101,7 @@ namespace llarp
|
|||
// don't allow enqueueing after stopping the pool
|
||||
if(stop)
|
||||
return;
|
||||
|
||||
jobs.emplace(ids++, new llarp_thread_job(job.user, job.work));
|
||||
jobs.emplace(ids++, job);
|
||||
}
|
||||
condition.NotifyOne();
|
||||
}
|
||||
|
@ -197,7 +193,8 @@ struct llarp_threadpool
|
|||
llarp::thread::Pool *impl;
|
||||
|
||||
llarp::util::Mutex m_access;
|
||||
std::queue< llarp_thread_job * > jobs;
|
||||
uint32_t ids = 0;
|
||||
std::queue< llarp::thread::Pool::Job_t > jobs;
|
||||
|
||||
llarp_threadpool(int workers, const char *name, bool isolate,
|
||||
setup_net_func setup = nullptr,
|
||||
|
@ -284,15 +281,11 @@ llarp_threadpool_queue_job(struct llarp_threadpool *pool,
|
|||
{
|
||||
if(pool->impl)
|
||||
pool->impl->QueueJob(job);
|
||||
else if(job.user && job.work)
|
||||
else
|
||||
{
|
||||
auto j = new llarp_thread_job;
|
||||
j->work = job.work;
|
||||
j->user = job.user;
|
||||
{
|
||||
llarp::util::Lock lock(pool->m_access);
|
||||
pool->jobs.push(j);
|
||||
}
|
||||
// single threaded mode
|
||||
llarp::util::Lock lock(pool->m_access);
|
||||
pool->jobs.emplace(++pool->ids, job);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -301,14 +294,13 @@ llarp_threadpool_tick(struct llarp_threadpool *pool)
|
|||
{
|
||||
while(pool->jobs.size())
|
||||
{
|
||||
llarp_thread_job *job;
|
||||
llarp::thread::Pool::Job_t job;
|
||||
{
|
||||
llarp::util::Lock lock(pool->m_access);
|
||||
job = pool->jobs.front();
|
||||
job = std::move(pool->jobs.front());
|
||||
pool->jobs.pop();
|
||||
}
|
||||
job->work(job->user);
|
||||
delete job;
|
||||
job();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,8 +34,13 @@ namespace llarp
|
|||
struct Job_t
|
||||
{
|
||||
uint32_t id;
|
||||
llarp_thread_job* job;
|
||||
Job_t(uint32_t jobid, llarp_thread_job* j) : id(jobid), job(j)
|
||||
void* user;
|
||||
llarp_thread_work_func work;
|
||||
|
||||
Job_t() = default;
|
||||
|
||||
Job_t(uint32_t jobid, const llarp_thread_job& j)
|
||||
: id(jobid), user(j.user), work(j.work)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -44,6 +49,12 @@ namespace llarp
|
|||
{
|
||||
return id < j.id;
|
||||
}
|
||||
|
||||
void
|
||||
operator()() const
|
||||
{
|
||||
work(user);
|
||||
}
|
||||
};
|
||||
|
||||
std::priority_queue< Job_t > jobs;
|
||||
|
|
|
@ -56,8 +56,8 @@ namespace llarp
|
|||
struct llarp_timer_context
|
||||
{
|
||||
llarp::util::Mutex timersMutex;
|
||||
std::unordered_map< uint32_t, llarp::timer* > timers;
|
||||
std::priority_queue< llarp::timer* > calling;
|
||||
std::unordered_map< uint32_t, std::unique_ptr< llarp::timer > > timers;
|
||||
std::priority_queue< std::unique_ptr< llarp::timer > > calling;
|
||||
llarp::util::Mutex tickerMutex;
|
||||
llarp::util::Condition* ticker = nullptr;
|
||||
std::chrono::milliseconds nextTickLen = std::chrono::milliseconds(100);
|
||||
|
@ -87,7 +87,7 @@ struct llarp_timer_context
|
|||
cancel(uint32_t id)
|
||||
{
|
||||
llarp::util::Lock lock(timersMutex);
|
||||
auto itr = timers.find(id);
|
||||
const auto& itr = timers.find(id);
|
||||
if(itr == timers.end())
|
||||
return;
|
||||
itr->second->canceled = true;
|
||||
|
@ -97,7 +97,7 @@ struct llarp_timer_context
|
|||
remove(uint32_t id)
|
||||
{
|
||||
llarp::util::Lock lock(timersMutex);
|
||||
auto itr = timers.find(id);
|
||||
const auto& itr = timers.find(id);
|
||||
if(itr == timers.end())
|
||||
return;
|
||||
itr->second->func = nullptr;
|
||||
|
@ -109,7 +109,10 @@ struct llarp_timer_context
|
|||
{
|
||||
llarp::util::Lock lock(timersMutex);
|
||||
uint32_t id = ++ids;
|
||||
timers[id] = new llarp::timer(timeout_ms, user, func);
|
||||
timers.insert(
|
||||
std::make_pair(id,
|
||||
std::unique_ptr< llarp::timer >(
|
||||
new llarp::timer(timeout_ms, user, func))));
|
||||
return id;
|
||||
}
|
||||
|
||||
|
@ -184,24 +187,30 @@ llarp_timer_tick_all(struct llarp_timer_context* t)
|
|||
if(!t->run())
|
||||
return;
|
||||
auto now = llarp_time_now_ms();
|
||||
auto itr = t->timers.begin();
|
||||
while(itr != t->timers.end())
|
||||
std::list< std::unique_ptr< llarp::timer > > hit;
|
||||
{
|
||||
if(now - itr->second->started >= itr->second->timeout
|
||||
|| itr->second->canceled)
|
||||
llarp::util::Lock lock(t->timersMutex);
|
||||
auto itr = t->timers.begin();
|
||||
while(itr != t->timers.end())
|
||||
{
|
||||
if(itr->second->func && itr->second->called_at == 0)
|
||||
if(now - itr->second->started >= itr->second->timeout
|
||||
|| itr->second->canceled)
|
||||
{
|
||||
// timer hit
|
||||
itr->second->called_at = now;
|
||||
itr->second->exec();
|
||||
llarp::timer* timer = itr->second;
|
||||
itr = t->timers.erase(itr);
|
||||
delete timer;
|
||||
continue;
|
||||
hit.emplace_back(std::move(itr->second));
|
||||
itr = t->timers.erase(itr);
|
||||
}
|
||||
else
|
||||
++itr;
|
||||
}
|
||||
}
|
||||
for(const auto& h : hit)
|
||||
{
|
||||
if(h->func)
|
||||
{
|
||||
h->called_at = now;
|
||||
h->exec();
|
||||
}
|
||||
++itr;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue