diff --git a/CMakeLists.txt b/CMakeLists.txt index 113857903..319d9d63e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,6 +24,7 @@ set(LIB_SRC llarp/address_info.cpp llarp/buffer.cpp llarp/config.cpp + llarp/context.cpp llarp/crypto_async.cpp llarp/crypto_libsodium.cpp llarp/ev.cpp diff --git a/daemon/main.cpp b/daemon/main.cpp index 5518feaac..f45e89618 100644 --- a/daemon/main.cpp +++ b/daemon/main.cpp @@ -1,148 +1,14 @@ -#include -#include #include -#include -#include -#include +#include +#include -#include -#include - -static void -progress() -{ - printf("."); - fflush(stdout); -} - -struct llarp_main -{ - struct llarp_alloc mem; - int num_nethreads = 1; - std::vector< std::thread > netio_threads; - struct llarp_crypto crypto; - struct llarp_router *router = nullptr; - struct llarp_threadpool *worker = nullptr; - struct llarp_logic *logic = nullptr; - struct llarp_config *config = nullptr; - struct llarp_nodedb *nodedb = nullptr; - struct llarp_ev_loop *mainloop = nullptr; - char nodedb_dir[256]; - int exitcode; - - int - shutdown() - { - printf("Shutting down "); - - progress(); - if(mainloop) - llarp_ev_loop_stop(mainloop); - - progress(); - if(worker) - llarp_threadpool_stop(worker); - - progress(); - - if(worker) - llarp_threadpool_join(worker); - - progress(); - if(logic) - llarp_logic_stop(logic); - - progress(); - - if(router) - llarp_stop_router(router); - - progress(); - llarp_free_router(&router); - - progress(); - llarp_free_config(&config); - - progress(); - llarp_ev_loop_free(&mainloop); - - progress(); - llarp_free_threadpool(&worker); - - progress(); - - llarp_free_logic(&logic); - - progress(); - llarp_nodedb_free(&nodedb); - - for(auto &t : netio_threads) - { - progress(); - t.join(); - } - progress(); - netio_threads.clear(); - - printf("stopped\n"); - fflush(stdout); - return exitcode; - } -}; - -void -iter_main_config(struct llarp_config_iterator *itr, const char *section, - const char *key, const char *val) -{ - llarp_main *m = static_cast< llarp_main * >(itr->user); - - if(!strcmp(section, "router")) - { - if(!strcmp(key, "worker-threads")) - { - int workers = atoi(val); - if(workers > 0 && m->worker == nullptr) - { - m->worker = llarp_init_threadpool(workers, "llarp-worker"); - } - } - if(!strcmp(key, "net-threads")) - { - m->num_nethreads = atoi(val); - if(m->num_nethreads <= 0) - m->num_nethreads = 1; - } - } - if(!strcmp(section, "netdb")) - { - if(!strcmp(key, "dir")) - { - strncpy(m->nodedb_dir, val, sizeof(m->nodedb_dir)); - } - } -} - -llarp_main *sllarp = nullptr; +std::unique_ptr< llarp::Context > ctx; void handle_signal(int sig) { - if(sllarp->logic) - llarp_logic_stop(sllarp->logic); - if(sllarp->mainloop) - llarp_ev_loop_stop(sllarp->mainloop); - - if(sllarp) - { - for(auto &t : sllarp->netio_threads) - { - progress(); - t.join(); - } - progress(); - sllarp->netio_threads.clear(); - } - printf("\ninterrupted\n"); + if(ctx) + ctx->HandleSignal(sig); } int @@ -151,69 +17,15 @@ main(int argc, char *argv[]) const char *conffname = "daemon.ini"; if(argc > 1) conffname = argv[1]; - sllarp = new llarp_main; - llarp_mem_stdlib(&sllarp->mem); - auto mem = &sllarp->mem; - llarp_new_config(&sllarp->config); - llarp_ev_loop_alloc(&sllarp->mainloop); - llarp_crypto_libsodium_init(&sllarp->crypto); - llarp::Info(__FILE__, LLARP_VERSION, " loading config at ", conffname); - if(!llarp_load_config(sllarp->config, conffname)) - { - llarp_config_iterator iter; - iter.user = sllarp; - iter.visit = iter_main_config; - llarp_config_iter(sllarp->config, &iter); - - sllarp->nodedb = llarp_nodedb_new(mem, &sllarp->crypto); - if(sllarp->nodedb_dir[0]) - { - sllarp->nodedb_dir[sizeof(sllarp->nodedb_dir) - 1] = 0; - if(llarp_nodedb_ensure_dir(sllarp->nodedb_dir)) - { - // ensure worker thread pool - if(!sllarp->worker) - sllarp->worker = llarp_init_threadpool(2, "llarp-worker"); - // ensure netio thread - sllarp->logic = llarp_init_logic(mem); + ctx.reset(new llarp::Context(std::cout)); - sllarp->router = llarp_init_router(mem, sllarp->worker, - sllarp->mainloop, sllarp->logic); + signal(SIGINT, handle_signal); - if(llarp_configure_router(sllarp->router, sllarp->config)) - { - signal(SIGINT, handle_signal); + if(!ctx->LoadConfig(conffname)) + return 1; - llarp_run_router(sllarp->router); - // run net io thread - auto netio = sllarp->mainloop; - while(sllarp->num_nethreads--) - { - sllarp->netio_threads.emplace_back( - [netio]() { llarp_ev_loop_run(netio); }); - pthread_setname_np(sllarp->netio_threads.back().native_handle(), - "llarp-netio"); - } - llarp::Info(__FILE__, "running"); - sllarp->exitcode = 0; - llarp_logic_mainloop(sllarp->logic); - } - else - llarp::Error(__FILE__, "failed to start router"); - } - else - llarp::Error(__FILE__, "Failed to initialize nodedb"); - } - else - llarp::Error(__FILE__, "no nodedb defined"); - auto code = sllarp->shutdown(); - delete sllarp; - sllarp = nullptr; - return code; - } - else - llarp::Error(__FILE__, "failed to load config"); - delete sllarp; - return 1; + auto exitcode = ctx->Run(); + ctx->Close(); + return exitcode; } diff --git a/include/llarp.hpp b/include/llarp.hpp new file mode 100644 index 000000000..51f347b7d --- /dev/null +++ b/include/llarp.hpp @@ -0,0 +1,61 @@ +#ifndef LLARP_HPP +#define LLARP_HPP + +#include +#include +#include +#include +#include + +namespace llarp +{ + struct Context + { + Context(std::ostream &stdout); + ~Context(); + + int num_nethreads = 1; + std::vector< std::thread > netio_threads; + llarp_alloc mem; + llarp_crypto crypto; + llarp_router *router = nullptr; + llarp_threadpool *worker = nullptr; + llarp_logic *logic = nullptr; + llarp_config *config = nullptr; + llarp_nodedb *nodedb = nullptr; + llarp_ev_loop *mainloop = nullptr; + char nodedb_dir[256] = {0}; + + bool + LoadConfig(const std::string &fname); + + void + Close(); + + int + Run(); + + void + HandleSignal(int sig); + + private: + void + SigINT(); + + bool + ReloadConfig(); + + static void + iter_config(llarp_config_iterator *itr, const char *section, + const char *key, const char *val); + + void + progress(); + + std::string configfile; + + std::ostream &out; + }; +} + +#endif diff --git a/llarp/context.cpp b/llarp/context.cpp new file mode 100644 index 000000000..66cfc713d --- /dev/null +++ b/llarp/context.cpp @@ -0,0 +1,203 @@ +#include +#include +#include "logger.hpp" + +namespace llarp +{ + Context::Context(std::ostream &stdout) : out(stdout) + { + } + + Context::~Context() + { + } + + void + Context::progress() + { + out << "." << std::flush; + } + + bool + Context::ReloadConfig() + { + llarp::Info(__FILE__, LLARP_VERSION, " loading config at ", configfile); + if(!llarp_load_config(config, configfile.c_str())) + { + llarp_config_iterator iter; + iter.user = this; + iter.visit = &iter_config; + llarp_config_iter(config, &iter); + return true; + } + return false; + } + + void + Context::iter_config(llarp_config_iterator *itr, const char *section, + const char *key, const char *val) + { + Context *ctx = static_cast< Context * >(itr->user); + if(!strcmp(section, "router")) + { + if(!strcmp(key, "worker-threads")) + { + int workers = atoi(val); + if(workers > 0 && ctx->worker == nullptr) + { + ctx->worker = llarp_init_threadpool(workers, "llarp-worker"); + } + } + if(!strcmp(key, "net-threads")) + { + ctx->num_nethreads = atoi(val); + if(ctx->num_nethreads <= 0) + ctx->num_nethreads = 1; + } + } + if(!strcmp(section, "netdb")) + { + if(!strcmp(key, "dir")) + { + strncpy(ctx->nodedb_dir, val, sizeof(ctx->nodedb_dir)); + } + } + } + + int + Context::Run() + { + llarp_mem_stdlib(&mem); + llarp_ev_loop_alloc(&mainloop); + llarp_crypto_libsodium_init(&crypto); + nodedb = llarp_nodedb_new(&mem, &crypto); + if(nodedb_dir[0]) + { + nodedb_dir[sizeof(nodedb_dir) - 1] = 0; + if(llarp_nodedb_ensure_dir(nodedb_dir)) + { + // ensure worker thread pool + if(!worker) + worker = llarp_init_threadpool(2, "llarp-worker"); + // ensure netio thread + logic = llarp_init_logic(&mem); + + router = llarp_init_router(&mem, worker, mainloop, logic); + + if(llarp_configure_router(router, config)) + { + llarp_run_router(router); + // run net io thread + auto netio = mainloop; + while(num_nethreads--) + { + netio_threads.emplace_back([netio]() { llarp_ev_loop_run(netio); }); + pthread_setname_np(netio_threads.back().native_handle(), + "llarp-netio"); + } + llarp::Info(__FILE__, "running"); + llarp_logic_mainloop(logic); + return 0; + } + else + llarp::Error(__FILE__, "failed to start router"); + } + else + llarp::Error(__FILE__, "Failed to initialize nodedb"); + } + else + llarp::Error(__FILE__, "no nodedb defined"); + return 1; + } + + void + Context::HandleSignal(int sig) + { + if(sig == SIGINT) + { + llarp::Info(__FILE__, "SIGINT"); + SigINT(); + } + if(sig == SIGHUP) + { + llarp::Info(__FILE__, "SIGHUP"); + ReloadConfig(); + } + } + + void + Context::SigINT() + { + if(logic) + llarp_logic_stop(logic); + if(mainloop) + llarp_ev_loop_stop(mainloop); + for(auto &t : netio_threads) + { + t.join(); + } + netio_threads.clear(); + } + + void + Context::Close() + { + progress(); + if(mainloop) + llarp_ev_loop_stop(mainloop); + + progress(); + if(worker) + llarp_threadpool_stop(worker); + + progress(); + + if(worker) + llarp_threadpool_join(worker); + + progress(); + if(logic) + llarp_logic_stop(logic); + + progress(); + + if(router) + llarp_stop_router(router); + + progress(); + llarp_free_router(&router); + + progress(); + llarp_free_config(&config); + + progress(); + llarp_ev_loop_free(&mainloop); + + progress(); + llarp_free_threadpool(&worker); + + progress(); + + llarp_free_logic(&logic); + + progress(); + llarp_nodedb_free(&nodedb); + + for(auto &t : netio_threads) + { + progress(); + t.join(); + } + progress(); + netio_threads.clear(); + out << std::endl << "done" << std::endl; + } + + bool + Context::LoadConfig(const std::string &fname) + { + llarp_new_config(&config); + configfile = fname; + return ReloadConfig(); + } +}