get rid of wizard and autogenerate configs if not present with sane defaults

pull/7/head
Jeff Becker 6 years ago
parent 976ca3015c
commit 48cfdab63c

@ -63,6 +63,7 @@
"future": "cpp", "future": "cpp",
"map": "cpp", "map": "cpp",
"vector": "cpp", "vector": "cpp",
"new": "cpp" "new": "cpp",
"shared_mutex": "cpp"
} }
} }

@ -1,8 +0,0 @@
#!/usr/bin/env bash
root=$(dirname $(realpath -L $0))
if [ ! -d v ] ; then
echo "setting up wizard for the first time..."
python3 -m venv v && v/bin/pip install -r "$root/requirements.txt" &> /dev/null || echo "failed"
fi
v/bin/python "$root/lokinet.py" $@

@ -1,50 +0,0 @@
#!/usr/bin/env python3
from configparser import ConfigParser as Config
import netifaces
import ipaddress
import os
def yield_public_addresses():
for ifname in netifaces.interfaces():
addrs = netifaces.ifaddresses(ifname)
if netifaces.AF_INET in addrs:
for addr in addrs[netifaces.AF_INET]:
ip = addr['addr']
if not ipaddress.ip_address(ip).is_private:
yield ifname, ip
def genconf(rootdir):
conf = Config()
conf['router'] = {
'threads': '2',
'net-threads': '1',
'contact-file': os.path.join(rootdir, 'self.signed'),
'transport-privkey': os.path.join(rootdir, 'transport.key'),
'identity-privkey': os.path.join(rootdir, 'identity.key')
}
conf['netdb'] = {
'dir': os.path.join(rootdir, 'netdb')
}
conf['bind'] = {}
found = False
for ifname, ip in yield_public_addresses():
conf['bind'][ifname] = '1090'
print("using public address {}".format(ip))
break
else:
print("This machine has no public network addresses")
return conf
def main(args):
fname = 'daemon.ini'
if len(args) == 1:
fname = args[0]
conf = genconf(os.path.realpath('.'))
if conf:
with open(fname, 'w') as f:
conf.write(f)
print("wrote config to {}".format(fname))
if __name__ == '__main__':
import sys
main(sys.argv[1:])

@ -1 +0,0 @@
netifaces==0.10.7

@ -1,12 +1,3 @@
[router]
threads = 2
net-threads = 1
contact-file = /home/jeff/git/llarp/self.signed
transport-privkey = /home/jeff/git/llarp/transport.key
identity-privkey = /home/jeff/git/llarp/identity.key
[netdb] [netdb]
dir = /home/jeff/git/llarp/netdb dir=netdb
[bind] [bind]

@ -3,12 +3,12 @@
#include <stdio.h> /* fprintf, printf */ #include <stdio.h> /* fprintf, printf */
#include <unistd.h> #include <unistd.h>
#include <llarp.h>
#include <llarp/logic.h> #include <llarp/logic.h>
#include "dnsd.hpp" #include "dnsd.hpp"
#include "ev.hpp" #include "ev.hpp"
#include "llarp/net.hpp"
#include "logger.hpp" #include "logger.hpp"
#include "net.hpp"
#include <llarp.h>
#include <thread> // for multithreaded version #include <thread> // for multithreaded version
#include <vector> #include <vector>
@ -18,7 +18,7 @@
#endif #endif
struct llarp_main *ctx = 0; struct llarp_main *ctx = 0;
bool done = false; bool done = false;
void void
handle_signal(int sig) handle_signal(int sig)
@ -38,14 +38,15 @@ hookChecker(std::string name)
#define SERVER "8.8.8.8" #define SERVER "8.8.8.8"
#define PORT 53 #define PORT 53
struct dns_relay_config { struct dns_relay_config
{
std::string upstream_host; std::string upstream_host;
uint16_t upstream_port; uint16_t upstream_port;
}; };
void void
dns_iter_config(llarp_config_iterator *itr, const char *section, dns_iter_config(llarp_config_iterator *itr, const char *section,
const char *key, const char *val) const char *key, const char *val)
{ {
dns_relay_config *config = (dns_relay_config *)itr->user; dns_relay_config *config = (dns_relay_config *)itr->user;
if(!strcmp(section, "dns")) if(!strcmp(section, "dns"))
@ -53,12 +54,14 @@ dns_iter_config(llarp_config_iterator *itr, const char *section,
if(!strcmp(key, "upstream-server")) if(!strcmp(key, "upstream-server"))
{ {
config->upstream_host = strdup(val); config->upstream_host = strdup(val);
llarp::LogDebug("Config file setting dns server to ", config->upstream_host); llarp::LogDebug("Config file setting dns server to ",
config->upstream_host);
} }
if(!strcmp(key, "upstream-port")) if(!strcmp(key, "upstream-port"))
{ {
config->upstream_port = atoi(val); config->upstream_port = atoi(val);
llarp::LogDebug("Config file setting dns server port to ", config->upstream_port); llarp::LogDebug("Config file setting dns server port to ",
config->upstream_port);
} }
} }
} }
@ -68,15 +71,15 @@ main(int argc, char *argv[])
{ {
int code = 1; int code = 1;
llarp::LogInfo("Starting up server"); llarp::LogInfo("Starting up server");
const char *conffname = handleBaseCmdLineArgs(argc, argv); const char *conffname = handleBaseCmdLineArgs(argc, argv);
dns_relay_config dnsr_config; dns_relay_config dnsr_config;
dnsr_config.upstream_host = "8.8.8.8"; dnsr_config.upstream_host = "8.8.8.8";
dnsr_config.upstream_port = 53; dnsr_config.upstream_port = 53;
llarp_config *config_reader; llarp_config *config_reader;
llarp_new_config(&config_reader); llarp_new_config(&config_reader);
//ctx = llarp_main_init(conffname, multiThreaded); // ctx = llarp_main_init(conffname, multiThreaded);
if(llarp_load_config(config_reader, conffname)) if(llarp_load_config(config_reader, conffname))
{ {
llarp_free_config(&config_reader); llarp_free_config(&config_reader);
@ -102,7 +105,9 @@ main(int argc, char *argv[])
// configure main netloop // configure main netloop
struct dnsd_context dnsd; struct dnsd_context dnsd;
if(!llarp_dnsd_init(&dnsd, netloop, "*", 1053, (const char *)dnsr_config.upstream_host.c_str(), dnsr_config.upstream_port)) if(!llarp_dnsd_init(&dnsd, netloop, "*", 1053,
(const char *)dnsr_config.upstream_host.c_str(),
dnsr_config.upstream_port))
{ {
// llarp::LogError("failed to initialize dns subsystem"); // llarp::LogError("failed to initialize dns subsystem");
llarp::LogError("Couldnt init dns daemon"); llarp::LogError("Couldnt init dns daemon");

@ -22,52 +22,9 @@ main(int argc, char *argv[])
multiThreaded = false; multiThreaded = false;
} }
const char *conffname = handleBaseCmdLineArgs(argc, argv); const char *conffname = handleBaseCmdLineArgs(argc, argv);
/*
const char *conffname = "daemon.ini"; if(!llarp_ensure_config(conffname))
int c; return 1;
while(1)
{
static struct option long_options[] = {
{"config", required_argument, 0, 'c'},
{"logLevel", required_argument, 0, 'o'},
{0, 0, 0, 0}};
int option_index = 0;
c = getopt_long(argc, argv, "c:o:", long_options, &option_index);
if(c == -1)
break;
switch(c)
{
case 0:
break;
case 'c':
conffname = optarg;
break;
case 'o':
if(strncmp(optarg, "debug", MIN(strlen(optarg), (unsigned long)5)) == 0)
{
cSetLogLevel(eLogDebug);
}
else if(strncmp(optarg, "info", MIN(strlen(optarg), (unsigned long)4))
== 0)
{
cSetLogLevel(eLogInfo);
}
else if(strncmp(optarg, "warn", MIN(strlen(optarg), (unsigned long)4))
== 0)
{
cSetLogLevel(eLogWarn);
}
else if(strncmp(optarg, "error", MIN(strlen(optarg), (unsigned long)5))
== 0)
{
cSetLogLevel(eLogError);
}
break;
default:
abort();
}
}
*/
ctx = llarp_main_init(conffname, multiThreaded); ctx = llarp_main_init(conffname, multiThreaded);
int code = 1; int code = 1;

@ -10,7 +10,7 @@
#include "buffer.hpp" #include "buffer.hpp"
#include "crypto.hpp" #include "crypto.hpp"
#include "fs.hpp" #include "fs.hpp"
#include "net.hpp" #include "llarp/net.hpp"
#include "router.hpp" #include "router.hpp"
struct llarp_main *ctx = 0; struct llarp_main *ctx = 0;

@ -38,4 +38,10 @@ void
llarp_config_iter(struct llarp_config *conf, llarp_config_iter(struct llarp_config *conf,
struct llarp_config_iterator *iter); struct llarp_config_iterator *iter);
/// ensure configuration exists
/// populate with defaults if it does not exist
/// return if this succeeded
bool
llarp_ensure_config(const char *fname);
#endif #endif

@ -38,7 +38,7 @@ struct llarp_link
const char *m_name; const char *m_name;
typedef std::unordered_map< llarp::Addr, llarp_link_session *, typedef std::unordered_map< llarp::Addr, llarp_link_session *,
llarp::addrhash > llarp::Addr::Hash >
LinkMap_t; LinkMap_t;
LinkMap_t m_sessions; LinkMap_t m_sessions;
@ -52,7 +52,7 @@ struct llarp_link
std::atomic< bool > pumpingLogic; std::atomic< bool > pumpingLogic;
typedef std::unordered_map< llarp::Addr, llarp_link_session *, typedef std::unordered_map< llarp::Addr, llarp_link_session *,
llarp::addrhash > llarp::Addr::Hash >
PendingSessionMap_t; PendingSessionMap_t;
PendingSessionMap_t m_PendingSessions; PendingSessionMap_t m_PendingSessions;
mtx_t m_PendingSessions_Mutex; mtx_t m_PendingSessions_Mutex;

@ -6,10 +6,10 @@
#include "llarp/buffer.h" #include "llarp/buffer.h"
#include "llarp/crypto.hpp" #include "llarp/crypto.hpp"
#include "llarp/crypto_async.h" #include "llarp/crypto_async.h"
#include "llarp/net.hpp"
#include "llarp/router_contact.h" #include "llarp/router_contact.h"
#include "llarp/time.h" #include "llarp/time.h"
#include "llarp/types.h" #include "llarp/types.h"
#include "net.hpp"
struct llarp_udp_io; struct llarp_udp_io;
struct llarp_async_iwp; struct llarp_async_iwp;

@ -2,6 +2,7 @@
#define LLARP_NET_HPP #define LLARP_NET_HPP
#include <llarp/address_info.h> #include <llarp/address_info.h>
#include <llarp/net.h> #include <llarp/net.h>
#include <functional>
#include <iostream> #include <iostream>
#include "mem.hpp" #include "mem.hpp"
@ -221,21 +222,32 @@ namespace llarp
return (byte1 == 10 || (byte1 == 192 && byte2 == 168) return (byte1 == 10 || (byte1 == 192 && byte2 == 168)
|| (byte1 == 172 && (byte2 & 0xf0) == 16)); || (byte1 == 172 && (byte2 & 0xf0) == 16));
} }
};
struct addrhash bool
{ isLoopback()
std::size_t
operator()(Addr const& a) const noexcept
{ {
if(a.af() == AF_INET) return (ntohl(addr4()->s_addr)) >> 24 == 127;
}
struct Hash
{
std::size_t
operator()(Addr const& a) const noexcept
{ {
return a.port() + a.addr4()->s_addr; 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();
} }
uint8_t empty[16] = {0}; };
return (a.af() + memcmp(a.addr6(), empty, 16)) ^ a.port();
}
}; };
/// get first network interface with public address
bool
GetBestNetIF(std::string& ifname, int af = AF_INET);
} // namespace llarp } // namespace llarp
#endif #endif

@ -1,6 +1,9 @@
#include "config.hpp" #include "config.hpp"
#include <llarp/config.h> #include <llarp/config.h>
#include <llarp/net.hpp>
#include "fs.hpp"
#include "ini.hpp" #include "ini.hpp"
#include "logger.hpp"
#include "mem.hpp" #include "mem.hpp"
namespace llarp namespace llarp
@ -78,3 +81,35 @@ llarp_config_iter(struct llarp_config *conf, struct llarp_config_iterator *iter)
iter->visit(iter, section.first.c_str(), item.first.c_str(), iter->visit(iter, section.first.c_str(), item.first.c_str(),
item.second.c_str()); item.second.c_str());
} }
bool
llarp_ensure_config(const char *fname)
{
std::error_code ec;
if(fs::exists(fname, ec))
return true;
if(ec)
{
llarp::LogError(ec);
return false;
}
std::ofstream f(fname);
if(!f.is_open())
{
llarp::LogError("failed to open ", fname, " for writing");
return false;
}
f << "[netdb]" << std::endl;
f << "dir=netdb" << std::endl;
f << "[bind]" << std::endl;
std::string ifname;
if(llarp::GetBestNetIF(ifname, AF_INET))
f << ifname << "=1090" << std::endl;
llarp::LogInfo("Generated new config ", fname);
return true;
}

@ -15,8 +15,8 @@
#include <cstdio> #include <cstdio>
#include <llarp/dns.h> #include <llarp/dns.h>
#include "llarp/net.hpp" // for llarp::Addr
#include "logger.hpp" #include "logger.hpp"
#include "net.hpp" // for llarp::Addr
// FIXME: make configurable // FIXME: make configurable
#define SERVER "8.8.8.8" #define SERVER "8.8.8.8"
@ -115,7 +115,7 @@ raw_resolve_host(const char *url)
dnsQuery.request[11] = 0x00; dnsQuery.request[11] = 0x00;
*/ */
//char *word; // char *word;
unsigned int i; unsigned int i;
llarp::LogDebug("Asking DNS server ", SERVER, " about ", url); llarp::LogDebug("Asking DNS server ", SERVER, " about ", url);
// dnsQuery.reqType = 0x01; // dnsQuery.reqType = 0x01;
@ -148,19 +148,19 @@ raw_resolve_host(const char *url)
int rcode; int rcode;
socklen_t size; socklen_t size;
int ip = 0; int ip = 0;
//int length; // int length;
unsigned char buffer[DNC_BUF_SIZE]; unsigned char buffer[DNC_BUF_SIZE];
// unsigned char tempBuf[3]; // unsigned char tempBuf[3];
uint16_t QDCOUNT; // No. of items in Question Section uint16_t QDCOUNT; // No. of items in Question Section
uint16_t ANCOUNT; // No. of items in Answer Section uint16_t ANCOUNT; // No. of items in Answer Section
uint16_t NSCOUNT; // No. of items in Authority Section uint16_t NSCOUNT; // No. of items in Authority Section
uint16_t ARCOUNT; // No. of items in Additional Section uint16_t ARCOUNT; // No. of items in Additional Section
//uint16_t QCLASS; // Specifies the class of the query // uint16_t QCLASS; // Specifies the class of the query
uint16_t ATYPE; // Specifies the meaning of the data in the RDATA field uint16_t ATYPE; // Specifies the meaning of the data in the RDATA field
//uint16_t ACLASS; // Specifies the class of the data in the RDATA field // uint16_t ACLASS; // Specifies the class of the data in the RDATA field
//uint32_t TTL; // The number of seconds the results can be cached // uint32_t TTL; // The number of seconds the results can be cached
//uint16_t RDLENGTH; // The length of the RDATA field // uint16_t RDLENGTH; // The length of the RDATA field
//uint16_t MSGID; // uint16_t MSGID;
int sockfd; int sockfd;
@ -307,8 +307,8 @@ llarp_handle_dnsc_recvfrom(struct llarp_udp_io *udp,
// llarp::LogInfo("got a response, udp user is ", udp->user); // llarp::LogInfo("got a response, udp user is ", udp->user);
unsigned char *castBuf = (unsigned char *)buf; unsigned char *castBuf = (unsigned char *)buf;
//auto buffer = llarp::StackBuffer< decltype(castBuf) >(castBuf); // auto buffer = llarp::StackBuffer< decltype(castBuf) >(castBuf);
dns_msg_header *hdr = decode_hdr((const char *)castBuf); dns_msg_header *hdr = decode_hdr((const char *)castBuf);
llarp::LogDebug("Header got client responses for id: ", hdr->id); llarp::LogDebug("Header got client responses for id: ", hdr->id);

@ -2,8 +2,8 @@
#include <llarp/dns.h> #include <llarp/dns.h>
#include <string> #include <string>
#include "ev.hpp" #include "ev.hpp"
#include "llarp/net.hpp"
#include "logger.hpp" #include "logger.hpp"
#include "net.hpp"
dns_tracker dns_udp_tracker; dns_tracker dns_udp_tracker;

@ -7,8 +7,8 @@
#include <unistd.h> #include <unistd.h>
#include <cstdio> #include <cstdio>
#include "ev.hpp" #include "ev.hpp"
#include "llarp/net.hpp"
#include "logger.hpp" #include "logger.hpp"
#include "net.hpp"
namespace llarp namespace llarp
{ {

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

@ -216,7 +216,6 @@ handle_generated_session_start(iwp_async_session_start *start)
if(llarp_ev_udp_sendto(link->udp, link->addr, start->buf, start->sz) == -1) if(llarp_ev_udp_sendto(link->udp, link->addr, start->buf, start->sz) == -1)
llarp::LogError("sendto failed"); llarp::LogError("sendto failed");
link->EnterState(llarp_link_session::State::eSessionStartSent); link->EnterState(llarp_link_session::State::eSessionStartSent);
link->serv->remove_intro_from(link->addr);
link->working = false; link->working = false;
} }
@ -247,8 +246,6 @@ handle_verify_introack(iwp_async_introack *introack)
{ {
// invalid signature // invalid signature
llarp::LogError("introack verify failed from ", link->addr); llarp::LogError("introack verify failed from ", link->addr);
link->serv->remove_intro_from(link->addr);
link->serv->RemoveSession(link);
return; return;
} }
// cancel resend // cancel resend
@ -380,10 +377,8 @@ llarp_link_session::on_intro_ack(const void *buf, size_t sz)
{ {
// too big? // too big?
llarp::LogError("introack too big"); llarp::LogError("introack too big");
serv->RemoveSession(this);
return; return;
} }
serv->put_intro_from(this);
// copy buffer so we own it // copy buffer so we own it
memcpy(workbuf, buf, sz); memcpy(workbuf, buf, sz);
// set intro ack parameters // set intro ack parameters

@ -1,4 +1,4 @@
#include "net.hpp" #include "llarp/net.hpp"
#include "str.hpp" #include "str.hpp"
#ifdef ANDROID #ifdef ANDROID
#include "android/ifaddrs.h" #include "android/ifaddrs.h"
@ -63,21 +63,21 @@ llarp_getifaddr(const char* ifname, int af, struct sockaddr* addr)
if(llarp::StrEq(i->ifa_name, ifname) && i->ifa_addr->sa_family == af) if(llarp::StrEq(i->ifa_name, ifname) && i->ifa_addr->sa_family == af)
{ {
// can't do this here // can't do this here
//llarp::Addr a(*i->ifa_addr); // llarp::Addr a(*i->ifa_addr);
//if(!a.isPrivate()) // if(!a.isPrivate())
//{ //{
// llarp::LogInfo(__FILE__, "found ", ifname, " af: ", af); // llarp::LogInfo(__FILE__, "found ", ifname, " af: ", af);
memcpy(addr, i->ifa_addr, sl); memcpy(addr, i->ifa_addr, sl);
if(af == AF_INET6) if(af == AF_INET6)
{ {
// set scope id // set scope id
sockaddr_in6* ip6addr = (sockaddr_in6*)addr; sockaddr_in6* ip6addr = (sockaddr_in6*)addr;
ip6addr->sin6_scope_id = if_nametoindex(ifname); ip6addr->sin6_scope_id = if_nametoindex(ifname);
ip6addr->sin6_flowinfo = 0; ip6addr->sin6_flowinfo = 0;
}
found = true;
break;
} }
found = true;
break;
}
//} //}
} }
i = i->ifa_next; i = i->ifa_next;
@ -86,3 +86,37 @@ llarp_getifaddr(const char* ifname, int af, struct sockaddr* addr)
freeifaddrs(ifa); freeifaddrs(ifa);
return found; return found;
} }
namespace llarp
{
bool
GetBestNetIF(std::string& ifname, int af)
{
ifaddrs* ifa = nullptr;
bool found = false;
if(getifaddrs(&ifa) == -1)
return false;
ifaddrs* i = ifa;
while(i)
{
if(i->ifa_addr)
{
if(i->ifa_addr->sa_family == af)
{
llarp::Addr a(*i->ifa_addr);
if(!(a.isPrivate() || a.isLoopback()))
{
ifname = i->ifa_name;
found = true;
break;
}
}
}
i = i->ifa_next;
}
if(ifa)
freeifaddrs(ifa);
return found;
}
} // namespace llarp

@ -9,8 +9,8 @@
#include "buffer.hpp" #include "buffer.hpp"
#include "encode.hpp" #include "encode.hpp"
#include "llarp/net.hpp"
#include "logger.hpp" #include "logger.hpp"
#include "net.hpp"
#include "str.hpp" #include "str.hpp"
#include <fstream> #include <fstream>

@ -1,5 +1,6 @@
#include <llarp/service.hpp> #include <llarp/service.hpp>
#include "buffer.hpp" #include "buffer.hpp"
#include "fs.hpp"
#include "ini.hpp" #include "ini.hpp"
#include "router.hpp" #include "router.hpp"
@ -157,14 +158,32 @@ namespace llarp
Identity::BEncode(llarp_buffer_t* buf) const Identity::BEncode(llarp_buffer_t* buf) const
{ {
/// TODO: implement me /// TODO: implement me
return false; if(!bencode_start_dict(buf))
return false;
if(!BEncodeWriteDictEntry("e", enckey, buf))
return false;
if(!BEncodeWriteDictEntry("s", signkey, buf))
return false;
if(!BEncodeWriteDictInt("v", version, buf))
return false;
if(!BEncodeWriteDictEntry("x", vanity, buf))
return false;
return bencode_end(buf);
} }
bool bool
Identity::DecodeKey(llarp_buffer_t key, llarp_buffer_t* buf) Identity::DecodeKey(llarp_buffer_t key, llarp_buffer_t* buf)
{ {
/// TODO: implement me bool read = false;
return false; if(!BEncodeMaybeReadDictEntry("e", enckey, read, key, buf))
return false;
if(!BEncodeMaybeReadDictEntry("s", signkey, read, key, buf))
return false;
if(!BEncodeMaybeReadDictInt("v", version, read, key, buf))
return false;
if(!BEncodeMaybeReadDictEntry("x", vanity, read, key, buf))
return false;
return read;
} }
void void
@ -180,8 +199,42 @@ namespace llarp
bool bool
Identity::EnsureKeys(const std::string& fname, llarp_crypto* c) Identity::EnsureKeys(const std::string& fname, llarp_crypto* c)
{ {
// TODO: implement me byte_t tmp[256];
return false; auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
std::error_code ec;
// check for file
if(!fs::exists(fname, ec))
{
if(ec)
{
llarp::LogError(ec);
return false;
}
// regen and encode
RegenerateKeys(c);
if(!BEncode(&buf))
return false;
// rewind
buf.sz = buf.cur - buf.base;
buf.cur = buf.base;
// write
std::ofstream f;
f.open(fname, std::ios::binary);
if(!f.is_open())
return false;
f.write((char*)buf.cur, buf.sz);
}
// read file
std::ifstream inf(fname, std::ios::binary);
inf.seekg(0, std::ios::end);
size_t sz = inf.tellg();
inf.seekg(0, std::ios::beg);
if(sz > sizeof(tmp))
return false;
// decode
inf.read((char*)buf.base, sz);
return BDecode(&buf);
} }
bool bool
@ -221,7 +274,6 @@ namespace llarp
bool bool
Config::Load(const std::string& fname) Config::Load(const std::string& fname)
{ {
// TODO: implement me
ini::Parser parser(fname); ini::Parser parser(fname);
for(const auto& sec : parser.top().ordered_sections) for(const auto& sec : parser.top().ordered_sections)
{ {

@ -40,8 +40,8 @@ namespace llarp
lock, [this] { return this->stop || !this->jobs.empty(); }); lock, [this] { return this->stop || !this->jobs.empty(); });
if(this->stop && this->jobs.empty()) if(this->stop && this->jobs.empty())
return; return;
job = this->jobs.front(); job = this->jobs.top().job;
this->jobs.pop_front(); this->jobs.pop();
} }
// do work // do work
job->work(job->user); job->work(job->user);
@ -81,7 +81,7 @@ namespace llarp
if(stop) if(stop)
return; return;
jobs.push_back(new llarp_thread_job(job.user, job.work)); jobs.emplace(ids++, new llarp_thread_job(job.user, job.work));
} }
condition.notify_one(); condition.notify_one();
} }

@ -4,7 +4,7 @@
#include <llarp/threadpool.h> #include <llarp/threadpool.h>
#include <llarp/threading.hpp> #include <llarp/threading.hpp>
#include <deque> #include <queue>
#include <thread> #include <thread>
#include <vector> #include <vector>
@ -27,8 +27,24 @@ namespace llarp
void void
Stop(); Stop();
std::vector< std::thread > threads; std::vector< std::thread > threads;
std::deque< llarp_thread_job* > jobs;
struct Job_t
{
uint32_t id;
llarp_thread_job* job;
Job_t(uint32_t jobid, llarp_thread_job* j) : id(jobid), job(j)
{
}
bool
operator<(const Job_t& j) const
{
return id < j.id;
}
};
std::priority_queue< Job_t > jobs;
uint32_t ids = 0;
mtx_t queue_mutex; mtx_t queue_mutex;
std::condition_variable condition; std::condition_variable condition;
std::condition_variable done; std::condition_variable done;

@ -3,6 +3,7 @@
#include <atomic> #include <atomic>
#include <condition_variable> #include <condition_variable>
#include <list> #include <list>
#include <queue>
#include <unordered_map> #include <unordered_map>
#include "logger.hpp" #include "logger.hpp"
@ -44,10 +45,10 @@ namespace llarp
static_cast< timer* >(user)->exec(); static_cast< timer* >(user)->exec();
} }
void bool
send_job(llarp_threadpool* pool) operator<(const timer& other) const
{ {
llarp_threadpool_queue_job(pool, {this, timer::call}); return (started + timeout) < (other.started + other.timeout);
} }
}; };
}; // namespace llarp }; // namespace llarp
@ -176,14 +177,29 @@ llarp_timer_cancel_job(struct llarp_timer_context* t, uint32_t id)
t->cancel(id); t->cancel(id);
} }
typedef std::priority_queue< llarp::timer* > timers_t;
static void
call_timers(void* user)
{
timers_t* t = static_cast< timers_t* >(user);
while(t->size())
{
t->top()->exec();
t->pop();
}
delete t;
}
void void
llarp_timer_tick_all(struct llarp_timer_context* t, llarp_timer_tick_all(struct llarp_timer_context* t,
struct llarp_threadpool* pool) struct llarp_threadpool* pool)
{ {
if(!t->run()) if(!t->run())
return; return;
auto now = llarp_time_now_ms(); auto now = llarp_time_now_ms();
auto itr = t->timers.begin(); auto itr = t->timers.begin();
timers_t* calling = new timers_t();
while(itr != t->timers.end()) while(itr != t->timers.end())
{ {
if(now - itr->second->started >= itr->second->timeout if(now - itr->second->started >= itr->second->timeout
@ -193,7 +209,7 @@ llarp_timer_tick_all(struct llarp_timer_context* t,
{ {
// timer hit // timer hit
itr->second->called_at = now; itr->second->called_at = now;
itr->second->send_job(pool); calling->push(itr->second);
++itr; ++itr;
} }
else if(itr->second->done) else if(itr->second->done)
@ -209,6 +225,10 @@ llarp_timer_tick_all(struct llarp_timer_context* t,
else // timer not hit yet else // timer not hit yet
++itr; ++itr;
} }
if(calling->size())
llarp_threadpool_queue_job(pool, {calling, &call_timers});
else
delete calling;
} }
void void

Loading…
Cancel
Save