mirror of https://github.com/oxen-io/lokinet
tweaks to testnet
This commit is contained in:
parent
78f3ca0155
commit
44e34f81e8
2
Makefile
2
Makefile
|
@ -59,7 +59,7 @@ shadow: shadow-build
|
|||
bash -c "$(SHADOW_BIN) -w $$(cat /proc/cpuinfo | grep processor | wc -l) $(SHADOW_CONFIG) &> $(SHADOW_LOG) || true"
|
||||
|
||||
testnet-configure: clean
|
||||
cmake -GNinja -DCMAKE_BUILD_TYPE=Debug
|
||||
cmake -GNinja -DCMAKE_BUILD_TYPE=Debug
|
||||
|
||||
testnet-build: testnet-configure
|
||||
ninja
|
||||
|
|
|
@ -6,25 +6,34 @@ import os
|
|||
|
||||
from xml.etree import ElementTree as etree
|
||||
|
||||
getSetting = lambda s, name, fallback : name in s and s[name] or fallback
|
||||
|
||||
shadowRoot = getSetting(os.environ, "SHADOW_ROOT", os.path.join(os.environ['HOME'], '.shadow'))
|
||||
def getSetting(s, name, fallback): return name in s and s[name] or fallback
|
||||
|
||||
|
||||
shadowRoot = getSetting(os.environ, "SHADOW_ROOT",
|
||||
os.path.join(os.environ['HOME'], '.shadow'))
|
||||
|
||||
libpath = 'libshadow-plugin-llarp.so'
|
||||
|
||||
|
||||
def nodeconf(conf, baseDir, name, ifname=None, port=None):
|
||||
conf['netdb'] = {'dir': 'tmp-nodes'}
|
||||
conf['router'] = {}
|
||||
conf['router']['contact-file'] = os.path.join(baseDir, '{}.signed'.format(name))
|
||||
conf['router']['ident-privkey'] = os.path.join(baseDir, '{}-ident.key'.format(name))
|
||||
conf['router']['transport-privkey'] = os.path.join(baseDir, '{}-transport.key'.format(name))
|
||||
conf['router'] = {}
|
||||
conf['router']['contact-file'] = os.path.join(
|
||||
baseDir, '{}.signed'.format(name))
|
||||
conf['router']['ident-privkey'] = os.path.join(
|
||||
baseDir, '{}-ident.key'.format(name))
|
||||
conf['router']['transport-privkey'] = os.path.join(
|
||||
baseDir, '{}-transport.key'.format(name))
|
||||
if ifname and port:
|
||||
conf['bind'] = {ifname: port}
|
||||
conf['connect'] = {}
|
||||
|
||||
|
||||
def addPeer(conf, baseDir, peer):
|
||||
conf['connect'][peer] = os.path.join(baseDir, '{}.signed'.format(peer))
|
||||
|
||||
|
||||
def createNode(pluginName, root, peer):
|
||||
node = etree.SubElement(root, 'node')
|
||||
node.attrib['id'] = peer['name']
|
||||
|
@ -38,39 +47,42 @@ def createNode(pluginName, root, peer):
|
|||
def makeBase(settings, name, id):
|
||||
return {
|
||||
'id': id,
|
||||
'name' : name,
|
||||
'contact-file' : os.path.join(getSetting(settings, 'baseDir', 'tmp'), '{}.signed'.format(name)),
|
||||
'configfile' : os.path.join(getSetting(settings, 'baseDir', 'tmp'), '{}.ini'.format(name)),
|
||||
'name': name,
|
||||
'contact-file': os.path.join(getSetting(settings, 'baseDir', 'tmp'), '{}.signed'.format(name)),
|
||||
'configfile': os.path.join(getSetting(settings, 'baseDir', 'tmp'), '{}.ini'.format(name)),
|
||||
'config': configparser.ConfigParser()
|
||||
}
|
||||
|
||||
|
||||
def makeClient(settings, name, id):
|
||||
peer = makeBase(settings, name, id)
|
||||
nodeconf(peer['config'], getSetting(settings, 'baseDir', 'tmp'), name)
|
||||
return peer
|
||||
|
||||
|
||||
def makeSVCNode(settings, name, id, port):
|
||||
peer = makeBase(settings, name, id)
|
||||
nodeconf(peer['config'], getSetting(settings, 'baseDir', 'tmp'), name, 'eth0', port)
|
||||
nodeconf(peer['config'], getSetting(
|
||||
settings, 'baseDir', 'tmp'), name, 'eth0', port)
|
||||
return peer
|
||||
|
||||
|
||||
def genconf(settings, outf):
|
||||
root = etree.Element('shadow')
|
||||
topology = etree.SubElement(root, 'topology')
|
||||
topology.attrib['path'] = getSetting(settings, 'topology', os.path.join(shadowRoot, 'share', 'topology.graphml.xml'))
|
||||
|
||||
topology.attrib['path'] = getSetting(settings, 'topology', os.path.join(
|
||||
shadowRoot, 'share', 'topology.graphml.xml'))
|
||||
|
||||
pluginName = getSetting(settings, 'name', 'llarpd')
|
||||
|
||||
kill = etree.SubElement(root, 'kill')
|
||||
kill.attrib['time'] = getSetting(settings, 'runFor', '600')
|
||||
|
||||
|
||||
baseDir = getSetting(settings, 'baseDir', 'tmp')
|
||||
|
||||
if not os.path.exists(baseDir):
|
||||
os.mkdir(baseDir)
|
||||
|
||||
|
||||
plugin = etree.SubElement(root, "plugin")
|
||||
plugin.attrib['id'] = pluginName
|
||||
plugin.attrib['path'] = libpath
|
||||
|
@ -78,7 +90,8 @@ def genconf(settings, outf):
|
|||
svcNodeCount = getSetting(settings, 'service-nodes', 20)
|
||||
peers = list()
|
||||
for nodeid in range(svcNodeCount):
|
||||
peers.append(makeSVCNode(settings, 'svc-node-{}'.format(nodeid), str(nodeid), basePort + 1))
|
||||
peers.append(makeSVCNode(
|
||||
settings, 'svc-node-{}'.format(nodeid), str(nodeid), basePort + 1))
|
||||
basePort += 1
|
||||
|
||||
# make all service nodes know each other
|
||||
|
@ -86,14 +99,15 @@ def genconf(settings, outf):
|
|||
for nodeid in range(svcNodeCount):
|
||||
if str(nodeid) != peer['id']:
|
||||
addPeer(peer['config'], baseDir, 'svc-node-{}'.format(nodeid))
|
||||
|
||||
|
||||
# add client nodes
|
||||
for nodeid in range(getSetting(settings, 'client-nodes', 200)):
|
||||
peer = makeClient(settings, 'client-node-{}'.format(nodeid), str(nodeid))
|
||||
peer = makeClient(
|
||||
settings, 'client-node-{}'.format(nodeid), str(nodeid))
|
||||
peers.append(peer)
|
||||
for p in range(getSetting(settings, 'client-connect-to', 3)):
|
||||
addPeer(peer['config'], baseDir, 'svc-node-{}'.format((p + nodeid) % svcNodeCount))
|
||||
|
||||
for p in range(getSetting(settings, 'client-connect-to', 10)):
|
||||
addPeer(peer['config'], baseDir,
|
||||
'svc-node-{}'.format((p + nodeid) % svcNodeCount))
|
||||
|
||||
# generate xml and settings files
|
||||
for peer in peers:
|
||||
|
@ -105,9 +119,10 @@ def genconf(settings, outf):
|
|||
# render
|
||||
outf.write(etree.tostring(root).decode('utf-8'))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
settings = {
|
||||
'topology': os.path.join(shadowRoot, 'share', 'topology.graphml.xml')
|
||||
'topology': os.path.join(shadowRoot, 'share', 'topology.graphml.xml')
|
||||
}
|
||||
with open(sys.argv[1], 'w') as f:
|
||||
genconf(settings, f)
|
||||
|
|
|
@ -43,7 +43,7 @@ typedef byte_t llarp_tunnel_nonce_t[TUNNONCESIZE];
|
|||
|
||||
/// label functors
|
||||
|
||||
/// PKE(result, publickey, nonce, secretkey)
|
||||
/// PKE(result, publickey, secretkey, nonce)
|
||||
typedef bool (*llarp_path_dh_func)(byte_t *, byte_t *, byte_t *, byte_t *);
|
||||
|
||||
/// TKE(result publickey, secretkey, nonce)
|
||||
|
|
|
@ -187,8 +187,8 @@ 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.nonce,
|
||||
hop.commkey))
|
||||
if(!ctx->crypto->dh_client(hop.shared, hop.router.enckey, hop.commkey,
|
||||
hop.nonce))
|
||||
{
|
||||
llarp::Error("Failed to generate shared key for path build");
|
||||
abort();
|
||||
|
|
|
@ -27,10 +27,8 @@ namespace iwp
|
|||
{
|
||||
iwp_async_keygen *keygen = static_cast< iwp_async_keygen * >(user);
|
||||
keygen->iwp->crypto->encryption_keygen(keygen->keybuf);
|
||||
llarp_thread_job job;
|
||||
job.user = user;
|
||||
job.work = &inform_keygen;
|
||||
llarp_logic_queue_job(keygen->iwp->logic, job);
|
||||
keygen->hook(keygen);
|
||||
// llarp_logic_queue_job(keygen->iwp->logic, job);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -71,7 +69,8 @@ namespace iwp
|
|||
buf.sz = intro->sz - 32;
|
||||
crypto->hmac(intro->buf, buf, sharedkey);
|
||||
// inform result
|
||||
llarp_logic_queue_job(intro->iwp->logic, {intro, &inform_intro});
|
||||
intro->hook(intro);
|
||||
// llarp_logic_queue_job(intro->iwp->logic, {intro, &inform_intro});
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -128,7 +127,7 @@ namespace iwp
|
|||
{
|
||||
iwp_async_introack *introack = static_cast< iwp_async_introack * >(user);
|
||||
auto crypto = introack->iwp->crypto;
|
||||
auto logic = introack->iwp->logic;
|
||||
// auto logic = introack->iwp->logic;
|
||||
|
||||
llarp::ShortHash digest;
|
||||
llarp::SharedSecret sharedkey;
|
||||
|
@ -165,7 +164,8 @@ namespace iwp
|
|||
// copy token
|
||||
memcpy(introack->token, token, 32);
|
||||
}
|
||||
llarp_logic_queue_job(logic, {introack, &inform_introack});
|
||||
introack->hook(introack);
|
||||
// llarp_logic_queue_job(logic, {introack, &inform_introack});
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -193,8 +193,9 @@ namespace iwp
|
|||
buf.sz = introack->sz - 32;
|
||||
buf.cur = buf.base;
|
||||
crypto->hmac(introack->buf, buf, sharedkey);
|
||||
|
||||
llarp_logic_queue_job(introack->iwp->logic, {introack, &inform_introack});
|
||||
introack->hook(introack);
|
||||
// llarp_logic_queue_job(introack->iwp->logic, {introack,
|
||||
// &inform_introack});
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -217,7 +218,7 @@ namespace iwp
|
|||
auto hmac = crypto->hmac;
|
||||
auto encrypt = crypto->xchacha20;
|
||||
|
||||
auto logic = session->iwp->logic;
|
||||
// auto logic = session->iwp->logic;
|
||||
auto a_sK = session->secretkey;
|
||||
auto b_K = session->remote_pubkey;
|
||||
auto N = session->nonce;
|
||||
|
@ -251,8 +252,8 @@ namespace iwp
|
|||
buf.base = (session->buf + 32);
|
||||
buf.sz = session->sz - 32;
|
||||
hmac(session->buf, buf, e_K);
|
||||
|
||||
llarp_logic_queue_job(logic, {user, &inform_session_start});
|
||||
session->hook(session);
|
||||
// llarp_logic_queue_job(logic, {user, &inform_session_start});
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -267,7 +268,7 @@ namespace iwp
|
|||
auto hmac = crypto->hmac;
|
||||
auto decrypt = crypto->xchacha20;
|
||||
|
||||
auto logic = session->iwp->logic;
|
||||
// auto logic = session->iwp->logic;
|
||||
auto b_sK = session->secretkey;
|
||||
auto a_K = session->remote_pubkey;
|
||||
auto N = session->nonce;
|
||||
|
@ -316,8 +317,8 @@ namespace iwp
|
|||
}
|
||||
else // hmac fail
|
||||
session->buf = nullptr;
|
||||
|
||||
llarp_logic_queue_job(logic, {user, &inform_session_start});
|
||||
session->hook(session);
|
||||
// llarp_logic_queue_job(logic, {user, &inform_session_start});
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -353,6 +354,9 @@ namespace iwp
|
|||
buf.cur = buf.base;
|
||||
buf.sz = frame->sz - 64;
|
||||
crypto->xchacha20(buf, frame->sessionkey, nonce);
|
||||
// call result RIGHT HERE
|
||||
// frame->hook(frame);
|
||||
// delete frame;
|
||||
// inform result
|
||||
llarp_logic_queue_job(frame->iwp->logic, {frame, &inform_frame_done});
|
||||
}
|
||||
|
|
|
@ -131,34 +131,33 @@ namespace llarp
|
|||
|
||||
} // namespace llarp
|
||||
|
||||
extern "C"
|
||||
extern "C" {
|
||||
const byte_t *
|
||||
llarp_seckey_topublic(const byte_t *secret)
|
||||
{
|
||||
const byte_t *
|
||||
llarp_seckey_topublic(const byte_t *secret)
|
||||
{
|
||||
return secret + 32;
|
||||
}
|
||||
|
||||
void
|
||||
llarp_crypto_libsodium_init(struct llarp_crypto *c)
|
||||
{
|
||||
assert(sodium_init() != -1);
|
||||
c->xchacha20 = llarp::sodium::xchacha20;
|
||||
c->dh_client = llarp::sodium::dh_client;
|
||||
c->dh_server = llarp::sodium::dh_server;
|
||||
c->transport_dh_client = llarp::sodium::dh_client;
|
||||
c->transport_dh_server = llarp::sodium::dh_server;
|
||||
c->hash = llarp::sodium::hash;
|
||||
c->shorthash = llarp::sodium::shorthash;
|
||||
c->hmac = llarp::sodium::hmac;
|
||||
c->sign = llarp::sodium::sign;
|
||||
c->verify = llarp::sodium::verify;
|
||||
c->randomize = llarp::sodium::randomize;
|
||||
c->randbytes = llarp::sodium::randbytes;
|
||||
c->identity_keygen = llarp::sodium::sigkeygen;
|
||||
c->encryption_keygen = llarp::sodium::enckeygen;
|
||||
int seed;
|
||||
c->randbytes(&seed, sizeof(seed));
|
||||
srand(seed);
|
||||
}
|
||||
return secret + 32;
|
||||
}
|
||||
|
||||
void
|
||||
llarp_crypto_libsodium_init(struct llarp_crypto *c)
|
||||
{
|
||||
assert(sodium_init() != -1);
|
||||
c->xchacha20 = llarp::sodium::xchacha20;
|
||||
c->dh_client = llarp::sodium::dh_client;
|
||||
c->dh_server = llarp::sodium::dh_server;
|
||||
c->transport_dh_client = llarp::sodium::dh_client;
|
||||
c->transport_dh_server = llarp::sodium::dh_server;
|
||||
c->hash = llarp::sodium::hash;
|
||||
c->shorthash = llarp::sodium::shorthash;
|
||||
c->hmac = llarp::sodium::hmac;
|
||||
c->sign = llarp::sodium::sign;
|
||||
c->verify = llarp::sodium::verify;
|
||||
c->randomize = llarp::sodium::randomize;
|
||||
c->randbytes = llarp::sodium::randbytes;
|
||||
c->identity_keygen = llarp::sodium::sigkeygen;
|
||||
c->encryption_keygen = llarp::sodium::enckeygen;
|
||||
int seed;
|
||||
c->randbytes(&seed, sizeof(seed));
|
||||
srand(seed);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -853,7 +853,9 @@ namespace iwp
|
|||
// when we are done doing stuff with all of our frames from the crypto
|
||||
// workers we are done
|
||||
llarp::Debug(addr, " timed out with ", frames, " frames left");
|
||||
return frames == 0 && !working;
|
||||
if(working)
|
||||
return false;
|
||||
return frames == 0;
|
||||
}
|
||||
if(is_invalidated())
|
||||
{
|
||||
|
@ -862,12 +864,17 @@ namespace iwp
|
|||
// are done
|
||||
llarp::Debug(addr, " invaldiated session with ", frames,
|
||||
" frames left");
|
||||
return frames == 0 && !working;
|
||||
if(working)
|
||||
return false;
|
||||
return frames == 0;
|
||||
}
|
||||
// send keepalive if we are established or a session is made
|
||||
if(state == eEstablished || state == eLIMSent)
|
||||
{
|
||||
send_keepalive(this);
|
||||
|
||||
// pump frames
|
||||
if(state == eEstablished)
|
||||
{
|
||||
frame.retransmit();
|
||||
pump();
|
||||
}
|
||||
|
@ -1104,7 +1111,7 @@ namespace iwp
|
|||
{
|
||||
// too big?
|
||||
llarp::Error("intro too big");
|
||||
// TOOD: session destroy ?
|
||||
delete this;
|
||||
return;
|
||||
}
|
||||
// copy so we own it
|
||||
|
@ -1128,30 +1135,7 @@ namespace iwp
|
|||
}
|
||||
|
||||
void
|
||||
on_intro_ack(const void *buf, size_t sz)
|
||||
{
|
||||
if(sz >= sizeof(workbuf))
|
||||
{
|
||||
// too big?
|
||||
llarp::Error("introack too big");
|
||||
// TOOD: session destroy ?
|
||||
return;
|
||||
}
|
||||
// copy buffer so we own it
|
||||
memcpy(workbuf, buf, sz);
|
||||
// set intro ack parameters
|
||||
introack.buf = workbuf;
|
||||
introack.sz = sz;
|
||||
introack.nonce = workbuf + 32;
|
||||
introack.remote_pubkey = remote;
|
||||
introack.token = token;
|
||||
introack.secretkey = eph_seckey;
|
||||
introack.user = this;
|
||||
introack.hook = &handle_verify_introack;
|
||||
// async verify
|
||||
working = true;
|
||||
iwp_call_async_verify_introack(iwp, &introack);
|
||||
}
|
||||
on_intro_ack(const void *buf, size_t sz);
|
||||
|
||||
static llarp_link *
|
||||
get_parent(llarp_link_session *s);
|
||||
|
@ -1410,7 +1394,9 @@ namespace iwp
|
|||
if(itr != m_sessions.end())
|
||||
{
|
||||
llarp::Debug("removing session ", addr);
|
||||
UnmapAddr(addr);
|
||||
session *s = static_cast< session * >(itr->second.impl);
|
||||
m_sessions.erase(itr);
|
||||
s->done();
|
||||
if(s->frames)
|
||||
{
|
||||
|
@ -1420,8 +1406,6 @@ namespace iwp
|
|||
}
|
||||
else
|
||||
delete s;
|
||||
m_sessions.erase(itr);
|
||||
UnmapAddr(addr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1488,7 +1472,6 @@ namespace iwp
|
|||
{
|
||||
// new inbound session
|
||||
s = link->create_session(*saddr);
|
||||
llarp::Debug("new inbound session from ", s->addr);
|
||||
}
|
||||
s->recv(buf, sz);
|
||||
}
|
||||
|
@ -1573,6 +1556,7 @@ namespace iwp
|
|||
{
|
||||
llarp::Error("intro verify failed from ", self->addr, " via ",
|
||||
self->serv->addr);
|
||||
delete self;
|
||||
return;
|
||||
}
|
||||
self->intro_ack();
|
||||
|
@ -1591,6 +1575,37 @@ namespace iwp
|
|||
void
|
||||
session::done()
|
||||
{
|
||||
if(establish_job_id)
|
||||
{
|
||||
llarp_logic_remove_call(logic, establish_job_id);
|
||||
handle_establish_timeout(this, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
session::on_intro_ack(const void *buf, size_t sz)
|
||||
{
|
||||
if(sz >= sizeof(workbuf))
|
||||
{
|
||||
// too big?
|
||||
llarp::Error("introack too big");
|
||||
serv->RemoveSessionByAddr(addr);
|
||||
return;
|
||||
}
|
||||
// copy buffer so we own it
|
||||
memcpy(workbuf, buf, sz);
|
||||
// set intro ack parameters
|
||||
introack.buf = workbuf;
|
||||
introack.sz = sz;
|
||||
introack.nonce = workbuf + 32;
|
||||
introack.remote_pubkey = remote;
|
||||
introack.token = token;
|
||||
introack.secretkey = eph_seckey;
|
||||
introack.user = this;
|
||||
introack.hook = &handle_verify_introack;
|
||||
// async verify
|
||||
working = true;
|
||||
iwp_call_async_verify_introack(iwp, &introack);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1677,6 +1692,7 @@ namespace iwp
|
|||
{
|
||||
// invalid signature
|
||||
llarp::Error("introack verify failed from ", link->addr);
|
||||
// link->serv->RemoveSessionByAddr(link->addr);
|
||||
return;
|
||||
}
|
||||
link->EnterState(eIntroAckRecv);
|
||||
|
@ -1881,14 +1897,15 @@ namespace iwp
|
|||
void
|
||||
session::handle_establish_timeout(void *user, uint64_t orig, uint64_t left)
|
||||
{
|
||||
if(orig == 0)
|
||||
return;
|
||||
session *self = static_cast< session * >(user);
|
||||
self->establish_job_id = 0;
|
||||
if(self->establish_job)
|
||||
{
|
||||
self->establish_job->link = self->serv->parent;
|
||||
if(left)
|
||||
if(self->IsEstablished())
|
||||
{
|
||||
// timer cancelled which means we were established
|
||||
self->establish_job->session = self->parent;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -204,10 +204,14 @@ namespace llarp
|
|||
std::size_t
|
||||
operator()(Addr const& a) const noexcept
|
||||
{
|
||||
if(a.af() == AF_INET)
|
||||
{
|
||||
return a.port() + a.addr4()->s_addr;
|
||||
}
|
||||
uint8_t empty[16] = {0};
|
||||
return (a.af() + memcmp(a.addr6(), empty, 16)) ^ a.port();
|
||||
}
|
||||
};
|
||||
}
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
||||
|
|
363
llarp/router.cpp
363
llarp/router.cpp
|
@ -78,6 +78,11 @@ llarp_router::SendToOrQueue(const llarp::RouterID &remote,
|
|||
return true;
|
||||
}
|
||||
// this will create an entry in the obmq if it's not already there
|
||||
auto itr = outboundMesssageQueue.find(remote);
|
||||
if(itr == outboundMesssageQueue.end())
|
||||
{
|
||||
outboundMesssageQueue.emplace(std::make_pair(remote, MessageQueue()));
|
||||
}
|
||||
outboundMesssageQueue[remote].push(msg);
|
||||
|
||||
// we don't have an open session to that router right now
|
||||
|
@ -498,7 +503,6 @@ llarp_router::FlushOutboundFor(const llarp::RouterID &remote,
|
|||
auto itr = outboundMesssageQueue.find(remote);
|
||||
if(itr == outboundMesssageQueue.end())
|
||||
{
|
||||
llarp::Error("outbound queue not found for ", remote);
|
||||
return;
|
||||
}
|
||||
while(itr->second.size())
|
||||
|
@ -643,15 +647,21 @@ llarp_router::Run()
|
|||
{
|
||||
// initialize as service node
|
||||
InitServiceNode();
|
||||
// immediate connect all for service node
|
||||
auto delay = rand() % 100;
|
||||
llarp_logic_call_later(logic, {delay, this, &ConnectAll});
|
||||
}
|
||||
else
|
||||
{ // delayed connect all for clients
|
||||
auto delay = ((rand() % 10) * 500) + 1000;
|
||||
llarp_logic_call_later(logic, {delay, this, &ConnectAll});
|
||||
}
|
||||
|
||||
llarp::PubKey ourPubkey = pubkey();
|
||||
llarp::Info("starting dht context as ", ourPubkey);
|
||||
llarp_dht_context_start(dht, ourPubkey);
|
||||
|
||||
llarp_logic_call_later(logic, {1000, this, &ConnectAll});
|
||||
|
||||
ScheduleTicker(500);
|
||||
ScheduleTicker(1000);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -715,210 +725,209 @@ llarp_router::HasPendingConnectJob(const llarp::RouterID &remote)
|
|||
return pendingEstablishJobs.find(remote) != pendingEstablishJobs.end();
|
||||
}
|
||||
|
||||
extern "C"
|
||||
extern "C" {
|
||||
struct llarp_router *
|
||||
llarp_init_router(struct llarp_threadpool *tp, struct llarp_ev_loop *netloop,
|
||||
struct llarp_logic *logic)
|
||||
{
|
||||
struct llarp_router *
|
||||
llarp_init_router(struct llarp_threadpool *tp, struct llarp_ev_loop *netloop,
|
||||
struct llarp_logic *logic)
|
||||
llarp_router *router = new llarp_router();
|
||||
if(router)
|
||||
{
|
||||
llarp_router *router = new llarp_router();
|
||||
if(router)
|
||||
{
|
||||
router->netloop = netloop;
|
||||
router->tp = tp;
|
||||
router->logic = logic;
|
||||
// TODO: make disk io threadpool count configurable
|
||||
router->netloop = netloop;
|
||||
router->tp = tp;
|
||||
router->logic = logic;
|
||||
// TODO: make disk io threadpool count configurable
|
||||
#ifdef TESTNET
|
||||
router->disk = tp;
|
||||
router->disk = tp;
|
||||
#else
|
||||
router->disk = llarp_init_threadpool(1, "llarp-diskio");
|
||||
router->disk = llarp_init_threadpool(1, "llarp-diskio");
|
||||
#endif
|
||||
llarp_crypto_libsodium_init(&router->crypto);
|
||||
}
|
||||
return router;
|
||||
llarp_crypto_libsodium_init(&router->crypto);
|
||||
}
|
||||
return router;
|
||||
}
|
||||
|
||||
bool
|
||||
llarp_configure_router(struct llarp_router *router, struct llarp_config *conf)
|
||||
bool
|
||||
llarp_configure_router(struct llarp_router *router, struct llarp_config *conf)
|
||||
{
|
||||
llarp_config_iterator iter;
|
||||
iter.user = router;
|
||||
iter.visit = llarp::router_iter_config;
|
||||
llarp_config_iter(conf, &iter);
|
||||
if(!router->InitOutboundLink())
|
||||
return false;
|
||||
if(!router->Ready())
|
||||
{
|
||||
llarp_config_iterator iter;
|
||||
iter.user = router;
|
||||
iter.visit = llarp::router_iter_config;
|
||||
llarp_config_iter(conf, &iter);
|
||||
if(!router->InitOutboundLink())
|
||||
return false;
|
||||
if(!router->Ready())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return router->EnsureIdentity();
|
||||
}
|
||||
|
||||
void
|
||||
llarp_run_router(struct llarp_router *router, struct llarp_nodedb *nodedb)
|
||||
{
|
||||
router->nodedb = nodedb;
|
||||
router->Run();
|
||||
}
|
||||
|
||||
bool
|
||||
llarp_router_try_connect(struct llarp_router *router, struct llarp_rc *remote,
|
||||
uint16_t numretries)
|
||||
{
|
||||
// do we already have a pending job for this remote?
|
||||
if(router->HasPendingConnectJob(remote->pubkey))
|
||||
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.emplace(
|
||||
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(link, job);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return router->EnsureIdentity();
|
||||
}
|
||||
|
||||
void
|
||||
llarp_rc_clear(struct llarp_rc *rc)
|
||||
{
|
||||
// zero out router contact
|
||||
llarp::Zero(rc, sizeof(llarp_rc));
|
||||
}
|
||||
void
|
||||
llarp_run_router(struct llarp_router *router, struct llarp_nodedb *nodedb)
|
||||
{
|
||||
router->nodedb = nodedb;
|
||||
router->Run();
|
||||
}
|
||||
|
||||
bool
|
||||
llarp_rc_addr_list_iter(struct llarp_ai_list_iter *iter, struct llarp_ai *ai)
|
||||
bool
|
||||
llarp_router_try_connect(struct llarp_router *router, struct llarp_rc *remote,
|
||||
uint16_t numretries)
|
||||
{
|
||||
// do we already have a pending job for this remote?
|
||||
if(router->HasPendingConnectJob(remote->pubkey))
|
||||
return false;
|
||||
// try first address only
|
||||
llarp_ai addr;
|
||||
if(llarp_ai_list_index(remote->addrs, 0, &addr))
|
||||
{
|
||||
struct llarp_rc *rc = (llarp_rc *)iter->user;
|
||||
llarp_ai_list_pushback(rc->addrs, ai);
|
||||
auto link = router->outboundLink;
|
||||
auto itr = router->pendingEstablishJobs.emplace(
|
||||
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(link, job);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
void
|
||||
llarp_rc_clear(struct llarp_rc *rc)
|
||||
{
|
||||
// zero out router contact
|
||||
llarp::Zero(rc, sizeof(llarp_rc));
|
||||
}
|
||||
|
||||
void
|
||||
llarp_rc_set_pubkey(struct llarp_rc *rc, const uint8_t *pubkey)
|
||||
{
|
||||
// set public key
|
||||
memcpy(rc->pubkey, pubkey, 32);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
bool
|
||||
llarp_findOrCreateIdentity(llarp_crypto *crypto, const char *fpath,
|
||||
byte_t *secretkey)
|
||||
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);
|
||||
}
|
||||
|
||||
void
|
||||
llarp_rc_set_pubkey(struct llarp_rc *rc, const uint8_t *pubkey)
|
||||
{
|
||||
// set public key
|
||||
memcpy(rc->pubkey, pubkey, 32);
|
||||
}
|
||||
|
||||
bool
|
||||
llarp_findOrCreateIdentity(llarp_crypto *crypto, const char *fpath,
|
||||
byte_t *secretkey)
|
||||
{
|
||||
llarp::Debug("find or create ", fpath);
|
||||
fs::path path(fpath);
|
||||
std::error_code ec;
|
||||
if(!fs::exists(path, ec))
|
||||
{
|
||||
llarp::Debug("find or create ", fpath);
|
||||
fs::path path(fpath);
|
||||
std::error_code ec;
|
||||
if(!fs::exists(path, ec))
|
||||
{
|
||||
llarp::Info("regenerated identity key");
|
||||
crypto->identity_keygen(secretkey);
|
||||
std::ofstream f(path, std::ios::binary);
|
||||
if(f.is_open())
|
||||
{
|
||||
f.write((char *)secretkey, SECKEYSIZE);
|
||||
}
|
||||
}
|
||||
std::ifstream f(path, std::ios::binary);
|
||||
llarp::Info("regenerated identity key");
|
||||
crypto->identity_keygen(secretkey);
|
||||
std::ofstream f(path, std::ios::binary);
|
||||
if(f.is_open())
|
||||
{
|
||||
f.read((char *)secretkey, SECKEYSIZE);
|
||||
f.write((char *)secretkey, SECKEYSIZE);
|
||||
}
|
||||
}
|
||||
std::ifstream f(path, std::ios::binary);
|
||||
if(f.is_open())
|
||||
{
|
||||
f.read((char *)secretkey, SECKEYSIZE);
|
||||
return true;
|
||||
}
|
||||
llarp::Info("failed to get identity key");
|
||||
return false;
|
||||
}
|
||||
|
||||
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, std::ios::binary);
|
||||
if(f.is_open())
|
||||
{
|
||||
f.write((char *)buf.base, buf.cur - buf.base);
|
||||
return true;
|
||||
}
|
||||
llarp::Info("failed to get identity key");
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
llarp_rc_write(struct llarp_rc *rc, const char *fpath)
|
||||
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))
|
||||
{
|
||||
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, std::ios::binary);
|
||||
if(f.is_open())
|
||||
{
|
||||
f.write((char *)buf.base, buf.cur - buf.base);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
// sign
|
||||
signbuf.sz = signbuf.cur - signbuf.base;
|
||||
crypto->sign(rc->signature, seckey, signbuf);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
llarp_rc_sign(llarp_crypto *crypto, const byte_t *seckey, struct llarp_rc *rc)
|
||||
void
|
||||
llarp_stop_router(struct llarp_router *router)
|
||||
{
|
||||
if(router)
|
||||
router->Close();
|
||||
}
|
||||
|
||||
void
|
||||
llarp_router_iterate_links(struct llarp_router *router,
|
||||
struct llarp_router_link_iter i)
|
||||
{
|
||||
for(auto link : router->inboundLinks)
|
||||
if(!i.visit(&i, router, link))
|
||||
return;
|
||||
i.visit(&i, router, router->outboundLink);
|
||||
}
|
||||
|
||||
void
|
||||
llarp_free_router(struct llarp_router **router)
|
||||
{
|
||||
if(*router)
|
||||
{
|
||||
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);
|
||||
}
|
||||
delete *router;
|
||||
}
|
||||
*router = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
llarp_stop_router(struct llarp_router *router)
|
||||
{
|
||||
if(router)
|
||||
router->Close();
|
||||
}
|
||||
|
||||
void
|
||||
llarp_router_iterate_links(struct llarp_router *router,
|
||||
struct llarp_router_link_iter i)
|
||||
{
|
||||
for(auto link : router->inboundLinks)
|
||||
if(!i.visit(&i, router, link))
|
||||
return;
|
||||
i.visit(&i, router, router->outboundLink);
|
||||
}
|
||||
|
||||
void
|
||||
llarp_free_router(struct llarp_router **router)
|
||||
{
|
||||
if(*router)
|
||||
{
|
||||
delete *router;
|
||||
}
|
||||
*router = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
llarp_router_override_path_selection(struct llarp_router *router,
|
||||
llarp_pathbuilder_select_hop_func func)
|
||||
{
|
||||
if(func)
|
||||
router->selectHopFunc = func;
|
||||
}
|
||||
void
|
||||
llarp_router_override_path_selection(struct llarp_router *router,
|
||||
llarp_pathbuilder_select_hop_func func)
|
||||
{
|
||||
if(func)
|
||||
router->selectHopFunc = func;
|
||||
}
|
||||
}
|
||||
|
||||
namespace llarp
|
||||
|
|
Loading…
Reference in New Issue