2019-01-14 21:46:07 +00:00
|
|
|
#include <router/router.hpp>
|
2019-01-10 19:41:51 +00:00
|
|
|
|
2019-07-02 21:28:28 +00:00
|
|
|
#include <config/config.hpp>
|
2019-08-12 11:27:46 +00:00
|
|
|
#include <constants/limits.hpp>
|
2019-09-01 12:10:49 +00:00
|
|
|
#include <constants/proto.hpp>
|
2019-01-26 15:40:58 +00:00
|
|
|
#include <crypto/crypto_libsodium.hpp>
|
2019-09-01 12:10:49 +00:00
|
|
|
#include <crypto/crypto.hpp>
|
2019-01-11 00:12:43 +00:00
|
|
|
#include <dht/context.hpp>
|
2019-01-19 18:16:40 +00:00
|
|
|
#include <dht/node.hpp>
|
2019-03-29 15:17:49 +00:00
|
|
|
#include <iwp/iwp.hpp>
|
2018-12-12 01:32:10 +00:00
|
|
|
#include <link/server.hpp>
|
2019-01-14 21:46:07 +00:00
|
|
|
#include <messages/link_message.hpp>
|
2019-01-11 01:42:02 +00:00
|
|
|
#include <net/net.hpp>
|
2019-01-14 21:46:07 +00:00
|
|
|
#include <rpc/rpc.hpp>
|
2019-01-10 19:41:51 +00:00
|
|
|
#include <util/buffer.hpp>
|
|
|
|
#include <util/encode.hpp>
|
2019-09-01 12:10:49 +00:00
|
|
|
#include <util/logging/file_logger.hpp>
|
|
|
|
#include <util/logging/json_logger.hpp>
|
|
|
|
#include <util/logging/logger_syslog.hpp>
|
|
|
|
#include <util/logging/logger.hpp>
|
2019-09-01 12:38:03 +00:00
|
|
|
#include <util/meta/memfn.hpp>
|
2019-09-01 12:58:27 +00:00
|
|
|
#include <util/metrics/metrics.hpp>
|
2019-01-10 19:41:51 +00:00
|
|
|
#include <util/str.hpp>
|
2019-09-05 17:39:09 +00:00
|
|
|
#include <ev/ev.hpp>
|
2017-11-28 14:05:31 +00:00
|
|
|
|
2018-05-20 17:45:47 +00:00
|
|
|
#include <fstream>
|
2018-10-09 01:38:25 +00:00
|
|
|
#include <cstdlib>
|
2019-01-02 17:41:13 +00:00
|
|
|
#include <iterator>
|
2019-07-08 15:26:06 +00:00
|
|
|
#include <unordered_map>
|
2019-09-01 12:10:49 +00:00
|
|
|
#include <utility>
|
2019-11-26 21:58:20 +00:00
|
|
|
#if defined(ANDROID) || defined(IOS)
|
2018-11-08 12:31:50 +00:00
|
|
|
#include <unistd.h>
|
2019-11-26 21:58:20 +00:00
|
|
|
#else
|
2019-11-26 22:11:13 +00:00
|
|
|
#if defined(_WIN32)
|
|
|
|
#else
|
2019-11-26 21:58:20 +00:00
|
|
|
#include <curl/curl.h>
|
2018-11-08 12:31:50 +00:00
|
|
|
#endif
|
2019-11-26 22:11:13 +00:00
|
|
|
#endif
|
2018-05-20 17:45:47 +00:00
|
|
|
|
2019-01-21 15:45:18 +00:00
|
|
|
bool
|
2019-05-28 19:45:08 +00:00
|
|
|
llarp_loadServiceNodeIdentityKey(const fs::path &fpath,
|
2019-01-21 15:45:18 +00:00
|
|
|
llarp::SecretKey &secret)
|
|
|
|
{
|
|
|
|
std::string path = fpath.string();
|
|
|
|
llarp::IdentitySecret ident;
|
|
|
|
|
|
|
|
if(!ident.LoadFromFile(path.c_str()))
|
|
|
|
return false;
|
|
|
|
|
2019-05-28 19:45:08 +00:00
|
|
|
return llarp::CryptoManager::instance()->seed_to_secretkey(secret, ident);
|
2019-01-21 15:45:18 +00:00
|
|
|
}
|
|
|
|
|
2018-08-30 18:48:43 +00:00
|
|
|
bool
|
2019-05-28 19:45:08 +00:00
|
|
|
llarp_findOrCreateIdentity(const fs::path &path, llarp::SecretKey &secretkey)
|
2018-05-25 17:52:10 +00:00
|
|
|
{
|
2019-01-10 22:35:38 +00:00
|
|
|
std::string fpath = path.string();
|
|
|
|
llarp::LogDebug("find or create ", fpath);
|
2018-12-10 16:26:46 +00:00
|
|
|
std::error_code ec;
|
|
|
|
if(!fs::exists(path, ec))
|
2018-10-03 11:01:42 +00:00
|
|
|
{
|
2018-12-10 16:26:46 +00:00
|
|
|
llarp::LogInfo("generating new identity key");
|
2019-05-28 19:45:08 +00:00
|
|
|
llarp::CryptoManager::instance()->identity_keygen(secretkey);
|
2019-01-10 22:35:38 +00:00
|
|
|
if(!secretkey.SaveToFile(fpath.c_str()))
|
|
|
|
return false;
|
2018-12-10 16:26:46 +00:00
|
|
|
}
|
2019-01-10 22:35:38 +00:00
|
|
|
return secretkey.LoadFromFile(fpath.c_str());
|
2018-08-14 21:17:18 +00:00
|
|
|
}
|
|
|
|
|
2018-12-10 16:26:46 +00:00
|
|
|
// C++ ...
|
2018-05-26 18:31:45 +00:00
|
|
|
bool
|
2019-05-28 19:45:08 +00:00
|
|
|
llarp_findOrCreateEncryption(const fs::path &path, llarp::SecretKey &encryption)
|
2018-05-26 18:31:45 +00:00
|
|
|
{
|
2019-01-10 22:35:38 +00:00
|
|
|
std::string fpath = path.string();
|
2019-01-11 01:42:02 +00:00
|
|
|
llarp::LogDebug("find or create ", fpath);
|
2018-12-10 16:26:46 +00:00
|
|
|
std::error_code ec;
|
|
|
|
if(!fs::exists(path, ec))
|
2018-09-30 12:01:58 +00:00
|
|
|
{
|
2018-12-10 16:26:46 +00:00
|
|
|
llarp::LogInfo("generating new encryption key");
|
2019-05-28 19:45:08 +00:00
|
|
|
llarp::CryptoManager::instance()->encryption_keygen(encryption);
|
2019-01-10 22:35:38 +00:00
|
|
|
if(!encryption.SaveToFile(fpath.c_str()))
|
|
|
|
return false;
|
2018-06-20 12:34:48 +00:00
|
|
|
}
|
2019-01-10 22:35:38 +00:00
|
|
|
return encryption.LoadFromFile(fpath.c_str());
|
2018-12-10 16:26:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
namespace llarp
|
|
|
|
{
|
2019-07-09 13:47:24 +00:00
|
|
|
Router::Router(std::shared_ptr< llarp::thread::ThreadPool > _tp,
|
|
|
|
llarp_ev_loop_ptr __netloop, std::shared_ptr< Logic > l)
|
2018-12-10 16:26:46 +00:00
|
|
|
: ready(false)
|
2019-07-30 23:42:13 +00:00
|
|
|
, _netloop(std::move(__netloop))
|
|
|
|
, cryptoworker(std::move(_tp))
|
|
|
|
, _logic(std::move(l))
|
2018-12-10 16:26:46 +00:00
|
|
|
, paths(this)
|
2019-02-11 19:45:42 +00:00
|
|
|
, _exitContext(this)
|
2019-07-09 13:58:16 +00:00
|
|
|
, disk(std::make_shared< llarp::thread::ThreadPool >(1, 1000,
|
|
|
|
"diskworker"))
|
2019-01-29 02:16:31 +00:00
|
|
|
, _dht(llarp_dht_context_new(this))
|
2018-12-10 16:26:46 +00:00
|
|
|
, inbound_link_msg_parser(this)
|
2019-02-22 16:21:05 +00:00
|
|
|
, _hiddenServiceContext(this)
|
2018-06-20 17:45:44 +00:00
|
|
|
{
|
2018-12-10 16:26:46 +00:00
|
|
|
// set rational defaults
|
|
|
|
this->ip4addr.sin_family = AF_INET;
|
|
|
|
this->ip4addr.sin_port = htons(1090);
|
|
|
|
|
2018-12-24 16:09:05 +00:00
|
|
|
_stopping.store(false);
|
|
|
|
_running.store(false);
|
2018-06-20 17:45:44 +00:00
|
|
|
}
|
2018-09-18 20:56:22 +00:00
|
|
|
|
2018-12-10 16:26:46 +00:00
|
|
|
Router::~Router()
|
2018-09-19 13:27:15 +00:00
|
|
|
{
|
2019-01-29 02:16:31 +00:00
|
|
|
llarp_dht_context_free(_dht);
|
2018-09-19 13:27:15 +00:00
|
|
|
}
|
2018-12-10 16:26:46 +00:00
|
|
|
|
2019-02-11 17:14:43 +00:00
|
|
|
util::StatusObject
|
|
|
|
Router::ExtractStatus() const
|
2019-02-08 19:43:25 +00:00
|
|
|
{
|
2019-10-04 09:10:55 +00:00
|
|
|
if(_running)
|
|
|
|
{
|
|
|
|
return util::StatusObject{
|
2019-10-04 19:43:30 +00:00
|
|
|
{"running", true},
|
2019-10-11 15:59:32 +00:00
|
|
|
{"numNodesKnown", _nodedb->num_loaded()},
|
2019-10-04 09:10:55 +00:00
|
|
|
{"dht", _dht->impl->ExtractStatus()},
|
|
|
|
{"services", _hiddenServiceContext.ExtractStatus()},
|
|
|
|
{"exit", _exitContext.ExtractStatus()},
|
|
|
|
{"links", _linkManager.ExtractStatus()}};
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-10-04 19:43:30 +00:00
|
|
|
return util::StatusObject{{"running", false}};
|
2019-10-04 09:10:55 +00:00
|
|
|
}
|
2019-02-08 19:43:25 +00:00
|
|
|
}
|
|
|
|
|
2018-12-10 16:26:46 +00:00
|
|
|
bool
|
2019-02-11 19:45:42 +00:00
|
|
|
Router::HandleRecvLinkMessageBuffer(ILinkSession *session,
|
2019-02-01 01:58:06 +00:00
|
|
|
const llarp_buffer_t &buf)
|
2018-09-18 20:56:22 +00:00
|
|
|
{
|
2018-12-24 16:09:05 +00:00
|
|
|
if(_stopping)
|
|
|
|
return true;
|
|
|
|
|
2018-12-10 16:26:46 +00:00
|
|
|
if(!session)
|
|
|
|
{
|
2019-02-11 19:45:42 +00:00
|
|
|
LogWarn("no link session");
|
2018-12-10 16:26:46 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return inbound_link_msg_parser.ProcessFrom(session, buf);
|
2018-10-07 15:29:36 +00:00
|
|
|
}
|
2018-12-10 16:26:46 +00:00
|
|
|
|
|
|
|
void
|
2019-02-11 19:45:42 +00:00
|
|
|
Router::PersistSessionUntil(const RouterID &remote, llarp_time_t until)
|
2018-10-07 15:29:36 +00:00
|
|
|
{
|
2019-06-26 21:39:29 +00:00
|
|
|
_linkManager.PersistSessionUntil(remote, until);
|
2018-06-01 14:08:54 +00:00
|
|
|
}
|
2018-06-26 10:08:51 +00:00
|
|
|
|
2018-12-13 00:03:19 +00:00
|
|
|
bool
|
|
|
|
Router::GetRandomGoodRouter(RouterID &router)
|
|
|
|
{
|
2019-06-26 21:39:29 +00:00
|
|
|
if(whitelistRouters)
|
|
|
|
{
|
|
|
|
return _rcLookupHandler.GetRandomWhitelistRouter(router);
|
|
|
|
}
|
|
|
|
|
2019-05-14 14:36:18 +00:00
|
|
|
auto pick_router = [&](auto &collection) -> bool {
|
|
|
|
const auto sz = collection.size();
|
|
|
|
auto itr = collection.begin();
|
2019-05-09 12:31:10 +00:00
|
|
|
if(sz == 0)
|
|
|
|
return false;
|
|
|
|
if(sz > 1)
|
|
|
|
std::advance(itr, randint() % sz);
|
|
|
|
router = itr->first;
|
|
|
|
return true;
|
2019-05-14 14:36:18 +00:00
|
|
|
};
|
2019-06-26 21:39:29 +00:00
|
|
|
|
2019-03-03 20:51:47 +00:00
|
|
|
absl::ReaderMutexLock l(&nodedb()->access);
|
2019-05-14 14:36:18 +00:00
|
|
|
return pick_router(nodedb()->entries);
|
2018-12-13 00:03:19 +00:00
|
|
|
}
|
|
|
|
|
2019-04-30 16:07:17 +00:00
|
|
|
void
|
|
|
|
Router::PumpLL()
|
|
|
|
{
|
2019-09-16 16:12:05 +00:00
|
|
|
if(_stopping.load())
|
|
|
|
return;
|
2019-10-25 21:13:11 +00:00
|
|
|
|
2019-09-16 10:21:12 +00:00
|
|
|
paths.PumpDownstream();
|
2019-11-04 18:25:05 +00:00
|
|
|
paths.PumpUpstream();
|
2019-10-25 21:13:11 +00:00
|
|
|
|
|
|
|
_outboundMessageHandler.Tick();
|
|
|
|
|
2019-06-26 21:39:29 +00:00
|
|
|
_linkManager.PumpLinks();
|
2019-04-30 16:07:17 +00:00
|
|
|
}
|
|
|
|
|
2018-12-10 16:26:46 +00:00
|
|
|
bool
|
2019-06-04 18:31:17 +00:00
|
|
|
Router::SendToOrQueue(const RouterID &remote, const ILinkMessage *msg,
|
|
|
|
SendStatusHandler handler)
|
2018-06-14 15:10:31 +00:00
|
|
|
{
|
2019-06-04 18:31:17 +00:00
|
|
|
if(handler == nullptr)
|
|
|
|
{
|
|
|
|
using std::placeholders::_1;
|
|
|
|
handler = std::bind(&Router::MessageSent, this, remote, _1);
|
|
|
|
}
|
|
|
|
return _outboundMessageHandler.QueueMessage(remote, msg, handler);
|
2018-10-25 18:18:12 +00:00
|
|
|
}
|
|
|
|
|
2018-12-10 16:26:46 +00:00
|
|
|
void
|
2019-04-05 14:58:22 +00:00
|
|
|
Router::ForEachPeer(std::function< void(const ILinkSession *, bool) > visit,
|
|
|
|
bool randomize) const
|
2018-05-22 15:54:19 +00:00
|
|
|
{
|
2019-06-26 21:39:29 +00:00
|
|
|
_linkManager.ForEachPeer(visit, randomize);
|
2018-05-22 15:54:19 +00:00
|
|
|
}
|
2018-12-10 16:26:46 +00:00
|
|
|
|
2018-12-19 16:17:41 +00:00
|
|
|
void
|
2019-02-11 19:45:42 +00:00
|
|
|
Router::ForEachPeer(std::function< void(ILinkSession *) > visit)
|
2018-12-19 16:17:41 +00:00
|
|
|
{
|
2019-06-26 21:39:29 +00:00
|
|
|
_linkManager.ForEachPeer(visit);
|
2018-12-19 16:17:41 +00:00
|
|
|
}
|
|
|
|
|
2018-12-10 16:26:46 +00:00
|
|
|
void
|
|
|
|
Router::try_connect(fs::path rcfile)
|
2018-05-16 18:13:18 +00:00
|
|
|
{
|
2019-02-11 19:45:42 +00:00
|
|
|
RouterContact remote;
|
2018-12-10 16:26:46 +00:00
|
|
|
if(!remote.Read(rcfile.string().c_str()))
|
2018-07-25 01:24:37 +00:00
|
|
|
{
|
2019-02-11 19:45:42 +00:00
|
|
|
LogError("failure to decode or verify of remote RC");
|
2018-12-10 16:26:46 +00:00
|
|
|
return;
|
2018-07-25 01:24:37 +00:00
|
|
|
}
|
2019-05-28 19:45:08 +00:00
|
|
|
if(remote.Verify(Now()))
|
2018-05-22 15:54:19 +00:00
|
|
|
{
|
2019-02-11 19:45:42 +00:00
|
|
|
LogDebug("verified signature");
|
2019-06-26 21:39:29 +00:00
|
|
|
_outboundSessionMaker.CreateSessionTo(remote, nullptr);
|
2018-05-22 15:54:19 +00:00
|
|
|
}
|
2018-12-10 16:26:46 +00:00
|
|
|
else
|
2019-02-11 19:45:42 +00:00
|
|
|
LogError(rcfile, " contains invalid RC");
|
2018-05-16 18:13:18 +00:00
|
|
|
}
|
2018-05-20 17:45:47 +00:00
|
|
|
|
2019-11-26 21:58:20 +00:00
|
|
|
static size_t
|
|
|
|
RecvIdentKey(char *ptr, size_t, size_t nmemb, void *userdata)
|
|
|
|
{
|
|
|
|
for(size_t idx = 0; idx < nmemb; idx++)
|
|
|
|
static_cast< std::vector< char > * >(userdata)->push_back(ptr[idx]);
|
|
|
|
return nmemb;
|
|
|
|
}
|
|
|
|
|
2018-12-10 16:26:46 +00:00
|
|
|
bool
|
|
|
|
Router::EnsureIdentity()
|
|
|
|
{
|
|
|
|
if(!EnsureEncryptionKey())
|
|
|
|
return false;
|
2019-11-26 21:58:20 +00:00
|
|
|
if(whitelistRouters)
|
|
|
|
{
|
|
|
|
#if defined(ANDROID) || defined(IOS)
|
|
|
|
LogError("running a service node on mobile device is not possible.");
|
|
|
|
return false;
|
2019-11-26 22:11:13 +00:00
|
|
|
#else
|
|
|
|
#if defined(_WIN32)
|
|
|
|
LogError("running a service node on windows is not possible.");
|
|
|
|
return false;
|
2019-11-26 21:58:20 +00:00
|
|
|
#else
|
|
|
|
CURL *curl = curl_easy_init();
|
|
|
|
if(curl)
|
|
|
|
{
|
|
|
|
CURLcode res;
|
|
|
|
std::stringstream ss;
|
|
|
|
ss << "http://" << lokidRPCAddr << "/json_rpc";
|
|
|
|
const auto url = ss.str();
|
|
|
|
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
|
|
|
|
curl_easy_setopt(curl, CURLOPT_HTTPAUTH, (long)CURLAUTH_ANY);
|
|
|
|
const auto auth = lokidRPCUser + ":" + lokidRPCPassword;
|
|
|
|
curl_easy_setopt(curl, CURLOPT_USERPWD, auth.c_str());
|
|
|
|
curl_slist *list = nullptr;
|
|
|
|
list = curl_slist_append(list, "Content-Type: application/json");
|
|
|
|
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);
|
|
|
|
|
|
|
|
nlohmann::json request = {{"id", "0"},
|
|
|
|
{"jsonrpc", "2.0"},
|
|
|
|
{"method", "get_service_node_privkey"}};
|
|
|
|
const auto data = request.dump();
|
|
|
|
std::vector< char > resp;
|
|
|
|
|
|
|
|
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, data.size());
|
|
|
|
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data.c_str());
|
|
|
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &resp);
|
|
|
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &RecvIdentKey);
|
|
|
|
do
|
|
|
|
{
|
2019-11-26 22:13:41 +00:00
|
|
|
resp.clear();
|
2019-11-26 22:04:52 +00:00
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
2019-11-26 21:58:20 +00:00
|
|
|
LogInfo("Getting Identity Keys from lokid...");
|
|
|
|
res = curl_easy_perform(curl);
|
|
|
|
if(res == CURLE_OK)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
auto j = nlohmann::json::parse(resp);
|
|
|
|
if(not j.is_object())
|
|
|
|
continue;
|
|
|
|
|
|
|
|
const auto itr = j.find("result");
|
|
|
|
if(itr == j.end())
|
|
|
|
continue;
|
|
|
|
if(not itr->is_object())
|
|
|
|
continue;
|
|
|
|
const auto k =
|
|
|
|
(*itr)["service_node_ed25519_privkey"].get< std::string >();
|
|
|
|
if(k.empty())
|
|
|
|
continue;
|
|
|
|
if(not HexDecode(k.c_str(), _identity.data(), _identity.size()))
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
catch(nlohmann::json::exception &ex)
|
|
|
|
{
|
|
|
|
LogError("Bad response from lokid: ", ex.what());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
LogError("failed to get identity Keys");
|
|
|
|
}
|
|
|
|
} while(res != CURLE_OK);
|
|
|
|
curl_easy_cleanup(curl);
|
|
|
|
curl_slist_free_all(list);
|
|
|
|
LogInfo("Got Identity Keys from lokid");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
LogError("failed to init curl");
|
|
|
|
return false;
|
|
|
|
}
|
2019-11-26 22:11:13 +00:00
|
|
|
#endif
|
2019-11-26 21:58:20 +00:00
|
|
|
#endif
|
|
|
|
}
|
2019-07-06 17:03:40 +00:00
|
|
|
return llarp_findOrCreateIdentity(ident_keyfile, _identity);
|
2018-12-10 16:26:46 +00:00
|
|
|
}
|
2018-04-05 14:23:14 +00:00
|
|
|
|
2018-12-10 16:26:46 +00:00
|
|
|
bool
|
|
|
|
Router::EnsureEncryptionKey()
|
|
|
|
{
|
2019-05-28 19:45:08 +00:00
|
|
|
return llarp_findOrCreateEncryption(encryption_keyfile, _encryption);
|
2018-12-10 16:26:46 +00:00
|
|
|
}
|
2018-01-29 14:27:24 +00:00
|
|
|
|
2018-12-10 16:26:46 +00:00
|
|
|
bool
|
2019-06-26 21:39:29 +00:00
|
|
|
Router::Configure(Config *conf, llarp_nodedb *nodedb)
|
2018-12-10 16:26:46 +00:00
|
|
|
{
|
2019-06-26 21:39:29 +00:00
|
|
|
if(nodedb == nullptr)
|
|
|
|
{
|
|
|
|
LogError(
|
|
|
|
"Attempting to Router::Configure but passed null nodedb pointer");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
_nodedb = nodedb;
|
|
|
|
|
2019-07-12 17:23:38 +00:00
|
|
|
if(!FromConfig(conf))
|
|
|
|
return false;
|
2019-07-02 21:28:28 +00:00
|
|
|
|
2019-01-05 13:45:05 +00:00
|
|
|
if(!InitOutboundLinks())
|
2018-12-10 16:26:46 +00:00
|
|
|
return false;
|
|
|
|
return EnsureIdentity();
|
|
|
|
}
|
2018-11-21 14:10:02 +00:00
|
|
|
|
2019-03-25 15:41:37 +00:00
|
|
|
/// called in disk worker thread
|
2019-05-18 18:46:49 +00:00
|
|
|
void
|
|
|
|
Router::HandleSaveRC() const
|
2019-03-25 15:41:37 +00:00
|
|
|
{
|
2019-05-18 18:46:49 +00:00
|
|
|
std::string fname = our_rc_file.string();
|
|
|
|
_rc.Write(fname.c_str());
|
2019-03-25 15:41:37 +00:00
|
|
|
}
|
|
|
|
|
2018-12-10 16:26:46 +00:00
|
|
|
bool
|
|
|
|
Router::SaveRC()
|
2018-08-18 14:01:21 +00:00
|
|
|
{
|
2019-02-11 19:45:42 +00:00
|
|
|
LogDebug("verify RC signature");
|
2019-05-28 19:45:08 +00:00
|
|
|
if(!_rc.Verify(Now()))
|
2018-12-10 16:26:46 +00:00
|
|
|
{
|
2019-05-24 02:01:36 +00:00
|
|
|
Dump< MAX_RC_SIZE >(rc());
|
2019-02-11 19:45:42 +00:00
|
|
|
LogError("RC is invalid, not saving");
|
2018-12-10 16:26:46 +00:00
|
|
|
return false;
|
|
|
|
}
|
2019-05-18 18:46:49 +00:00
|
|
|
diskworker()->addJob(std::bind(&Router::HandleSaveRC, this));
|
2019-03-25 15:41:37 +00:00
|
|
|
return true;
|
2018-06-20 12:34:48 +00:00
|
|
|
}
|
2018-05-29 13:40:26 +00:00
|
|
|
|
2018-12-10 16:26:46 +00:00
|
|
|
bool
|
|
|
|
Router::IsServiceNode() const
|
|
|
|
{
|
2019-06-26 21:39:29 +00:00
|
|
|
return m_isServiceNode;
|
2018-12-10 16:26:46 +00:00
|
|
|
}
|
2018-05-30 20:56:47 +00:00
|
|
|
|
2018-12-10 16:26:46 +00:00
|
|
|
void
|
|
|
|
Router::Close()
|
2018-05-26 18:31:45 +00:00
|
|
|
{
|
2019-02-11 19:45:42 +00:00
|
|
|
LogInfo("closing router");
|
2019-06-02 21:17:05 +00:00
|
|
|
llarp_ev_loop_stop(_netloop);
|
2019-07-09 13:47:24 +00:00
|
|
|
disk->stop();
|
|
|
|
disk->shutdown();
|
2018-12-10 16:26:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Router::handle_router_ticker(void *user, uint64_t orig, uint64_t left)
|
2018-11-28 15:18:18 +00:00
|
|
|
{
|
2018-12-10 16:26:46 +00:00
|
|
|
if(left)
|
|
|
|
return;
|
2019-07-30 23:42:13 +00:00
|
|
|
auto *self = static_cast< Router * >(user);
|
2018-12-10 16:26:46 +00:00
|
|
|
self->ticker_job_id = 0;
|
2019-11-14 21:56:01 +00:00
|
|
|
LogicCall(self->logic(), std::bind(&Router::Tick, self));
|
2018-12-10 16:26:46 +00:00
|
|
|
self->ScheduleTicker(orig);
|
2018-11-28 15:18:18 +00:00
|
|
|
}
|
|
|
|
|
2018-12-27 14:32:37 +00:00
|
|
|
bool
|
2019-02-01 01:58:06 +00:00
|
|
|
Router::ParseRoutingMessageBuffer(const llarp_buffer_t &buf,
|
2019-02-11 19:45:42 +00:00
|
|
|
routing::IMessageHandler *h,
|
|
|
|
const PathID_t &rxid)
|
2018-12-27 14:32:37 +00:00
|
|
|
{
|
|
|
|
return inbound_routing_msg_parser.ParseMessageBuffer(buf, h, rxid, this);
|
|
|
|
}
|
|
|
|
|
2018-12-10 16:26:46 +00:00
|
|
|
bool
|
2019-02-11 19:45:42 +00:00
|
|
|
Router::ConnectionToRouterAllowed(const RouterID &router) const
|
2018-11-28 14:58:38 +00:00
|
|
|
{
|
2019-06-26 21:39:29 +00:00
|
|
|
return _rcLookupHandler.RemoteIsAllowed(router);
|
2019-05-09 15:36:39 +00:00
|
|
|
}
|
|
|
|
|
2018-12-10 16:26:46 +00:00
|
|
|
size_t
|
|
|
|
Router::NumberOfConnectedRouters() const
|
2018-09-14 13:43:42 +00:00
|
|
|
{
|
2019-06-26 21:39:29 +00:00
|
|
|
return _linkManager.NumberOfConnectedRouters();
|
2019-05-09 15:36:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
size_t
|
|
|
|
Router::NumberOfConnectedClients() const
|
|
|
|
{
|
2019-06-26 21:39:29 +00:00
|
|
|
return _linkManager.NumberOfConnectedClients();
|
2018-09-14 13:43:42 +00:00
|
|
|
}
|
2018-06-19 17:11:24 +00:00
|
|
|
|
2018-12-19 16:17:41 +00:00
|
|
|
bool
|
|
|
|
Router::UpdateOurRC(bool rotateKeys)
|
|
|
|
{
|
2019-02-11 19:45:42 +00:00
|
|
|
SecretKey nextOnionKey;
|
|
|
|
RouterContact nextRC = _rc;
|
2018-12-19 16:17:41 +00:00
|
|
|
if(rotateKeys)
|
|
|
|
{
|
2019-05-28 19:45:08 +00:00
|
|
|
CryptoManager::instance()->encryption_keygen(nextOnionKey);
|
2019-01-29 13:20:27 +00:00
|
|
|
std::string f = encryption_keyfile.string();
|
2019-03-25 15:41:37 +00:00
|
|
|
// TODO: use disk worker
|
2019-01-29 13:20:27 +00:00
|
|
|
if(nextOnionKey.SaveToFile(f.c_str()))
|
|
|
|
{
|
2019-02-11 19:45:42 +00:00
|
|
|
nextRC.enckey = seckey_topublic(nextOnionKey);
|
|
|
|
_encryption = nextOnionKey;
|
2019-01-29 13:20:27 +00:00
|
|
|
}
|
2018-12-19 16:17:41 +00:00
|
|
|
}
|
2019-05-28 19:45:08 +00:00
|
|
|
if(!nextRC.Sign(identity()))
|
2018-12-19 16:17:41 +00:00
|
|
|
return false;
|
2019-08-28 11:38:32 +00:00
|
|
|
if(!nextRC.Verify(time_now_ms(), false))
|
|
|
|
return false;
|
|
|
|
_rc = std::move(nextRC);
|
2019-01-29 12:33:33 +00:00
|
|
|
// propagate RC by renegotiating sessions
|
2019-02-11 19:45:42 +00:00
|
|
|
ForEachPeer([](ILinkSession *s) {
|
2019-01-29 12:33:33 +00:00
|
|
|
if(s->RenegotiateSession())
|
2019-02-11 19:45:42 +00:00
|
|
|
LogInfo("renegotiated session");
|
2019-01-29 12:33:33 +00:00
|
|
|
else
|
2019-02-11 19:45:42 +00:00
|
|
|
LogWarn("failed to renegotiate session");
|
2019-01-29 12:33:33 +00:00
|
|
|
});
|
2019-02-04 23:18:43 +00:00
|
|
|
|
2018-12-19 16:17:41 +00:00
|
|
|
return SaveRC();
|
2019-03-25 15:41:37 +00:00
|
|
|
}
|
2018-12-19 16:17:41 +00:00
|
|
|
|
2019-07-12 17:21:29 +00:00
|
|
|
bool
|
2019-07-12 17:23:38 +00:00
|
|
|
Router::FromConfig(Config *conf)
|
2019-02-11 14:43:48 +00:00
|
|
|
{
|
2019-07-07 11:29:44 +00:00
|
|
|
// Set netid before anything else
|
2019-09-09 11:36:21 +00:00
|
|
|
if(!conf->router.netId().empty()
|
|
|
|
&& strcmp(conf->router.netId().c_str(), Version::LLARP_NET_ID))
|
2019-02-11 14:43:48 +00:00
|
|
|
{
|
2019-07-01 23:55:02 +00:00
|
|
|
const auto &netid = conf->router.netId();
|
2019-07-07 11:29:44 +00:00
|
|
|
llarp::LogWarn("!!!! you have manually set netid to be '", netid,
|
|
|
|
"' which does not equal '", Version::LLARP_NET_ID,
|
|
|
|
"' you will run as a different network, good luck "
|
|
|
|
"and don't forget: something something MUH traffic "
|
|
|
|
"shape correlation !!!!");
|
|
|
|
NetID::DefaultValue() =
|
|
|
|
NetID(reinterpret_cast< const byte_t * >(netid.c_str()));
|
|
|
|
// reset netid in our rc
|
|
|
|
_rc.netID = llarp::NetID();
|
2019-02-11 14:43:48 +00:00
|
|
|
}
|
2019-08-07 16:33:29 +00:00
|
|
|
const auto linktypename = conf->router.defaultLinkProto();
|
|
|
|
_defaultLinkType = LinkFactory::TypeFromName(linktypename);
|
|
|
|
if(_defaultLinkType == LinkFactory::LinkType::eLinkUnknown)
|
|
|
|
{
|
|
|
|
LogError("failed to set link type to '", linktypename,
|
|
|
|
"' as that is invalid");
|
|
|
|
return false;
|
|
|
|
}
|
2019-07-07 11:29:44 +00:00
|
|
|
|
2019-07-02 21:28:28 +00:00
|
|
|
// IWP config
|
2019-08-07 16:33:29 +00:00
|
|
|
m_OutboundPort = std::get< LinksConfig::Port >(conf->links.outboundLink());
|
2019-07-12 17:21:29 +00:00
|
|
|
// Router config
|
|
|
|
_rc.SetNick(conf->router.nickname());
|
2019-08-12 12:40:38 +00:00
|
|
|
_outboundSessionMaker.maxConnectedRouters =
|
|
|
|
conf->router.maxConnectedRouters();
|
|
|
|
_outboundSessionMaker.minConnectedRouters =
|
|
|
|
conf->router.minConnectedRouters();
|
|
|
|
encryption_keyfile = conf->router.encryptionKeyfile();
|
|
|
|
our_rc_file = conf->router.ourRcFile();
|
|
|
|
transport_keyfile = conf->router.transportKeyfile();
|
|
|
|
addrInfo = conf->router.addrInfo();
|
|
|
|
publicOverride = conf->router.publicOverride();
|
|
|
|
ip4addr = conf->router.ip4addr();
|
2019-07-12 17:21:29 +00:00
|
|
|
|
2019-08-26 23:29:17 +00:00
|
|
|
if(!conf->router.blockBogons().value_or(true))
|
|
|
|
{
|
|
|
|
RouterContact::BlockBogons = false;
|
|
|
|
}
|
|
|
|
|
2019-07-12 17:21:29 +00:00
|
|
|
// Lokid Config
|
|
|
|
usingSNSeed = conf->lokid.usingSNSeed;
|
|
|
|
ident_keyfile = conf->lokid.ident_keyfile;
|
|
|
|
whitelistRouters = conf->lokid.whitelistRouters;
|
|
|
|
lokidRPCAddr = conf->lokid.lokidRPCAddr;
|
|
|
|
lokidRPCUser = conf->lokid.lokidRPCUser;
|
|
|
|
lokidRPCPassword = conf->lokid.lokidRPCPassword;
|
|
|
|
|
2019-06-26 21:39:29 +00:00
|
|
|
// TODO: add config flag for "is service node"
|
2019-08-07 16:33:29 +00:00
|
|
|
if(conf->links.inboundLinks().size())
|
2019-02-11 14:43:48 +00:00
|
|
|
{
|
2019-06-26 21:39:29 +00:00
|
|
|
m_isServiceNode = true;
|
2019-02-11 14:43:48 +00:00
|
|
|
}
|
|
|
|
|
2019-06-26 21:39:29 +00:00
|
|
|
std::set< RouterID > strictConnectPubkeys;
|
2019-07-02 21:28:28 +00:00
|
|
|
|
2019-07-02 00:20:58 +00:00
|
|
|
if(!conf->network.strictConnect().empty())
|
2019-02-11 14:43:48 +00:00
|
|
|
{
|
2019-07-02 00:20:58 +00:00
|
|
|
const auto &val = conf->network.strictConnect();
|
2019-07-02 21:28:28 +00:00
|
|
|
if(IsServiceNode())
|
2019-04-25 11:00:18 +00:00
|
|
|
{
|
2019-07-02 21:28:28 +00:00
|
|
|
llarp::LogError("cannot use strict-connect option as service node");
|
2019-07-12 17:21:29 +00:00
|
|
|
return false;
|
2019-04-25 11:00:18 +00:00
|
|
|
}
|
2019-07-02 21:28:28 +00:00
|
|
|
llarp::RouterID snode;
|
|
|
|
llarp::PubKey pk;
|
|
|
|
if(pk.FromString(val))
|
2019-02-11 14:43:48 +00:00
|
|
|
{
|
2019-07-02 21:28:28 +00:00
|
|
|
if(strictConnectPubkeys.emplace(pk).second)
|
|
|
|
llarp::LogInfo("added ", pk, " to strict connect list");
|
|
|
|
else
|
|
|
|
llarp::LogWarn("duplicate key for strict connect: ", pk);
|
2019-02-11 14:43:48 +00:00
|
|
|
}
|
2019-07-02 21:28:28 +00:00
|
|
|
else if(snode.FromString(val))
|
2019-02-11 14:43:48 +00:00
|
|
|
{
|
2019-07-02 21:28:28 +00:00
|
|
|
if(strictConnectPubkeys.insert(snode).second)
|
2019-02-11 14:43:48 +00:00
|
|
|
{
|
2019-07-02 21:28:28 +00:00
|
|
|
llarp::LogInfo("added ", snode, " to strict connect list");
|
|
|
|
netConfig.emplace("strict-connect", val);
|
2019-02-11 14:43:48 +00:00
|
|
|
}
|
|
|
|
else
|
2019-07-02 21:28:28 +00:00
|
|
|
llarp::LogWarn("duplicate key for strict connect: ", snode);
|
2019-02-11 14:43:48 +00:00
|
|
|
}
|
|
|
|
else
|
2019-07-02 21:28:28 +00:00
|
|
|
llarp::LogError("invalid key for strict-connect: ", val);
|
2019-02-11 14:43:48 +00:00
|
|
|
}
|
2019-07-02 21:28:28 +00:00
|
|
|
|
|
|
|
std::vector< std::string > configRouters = conf->connect.routers;
|
|
|
|
configRouters.insert(configRouters.end(), conf->bootstrap.routers.begin(),
|
|
|
|
conf->bootstrap.routers.end());
|
|
|
|
for(const auto &router : configRouters)
|
2019-02-11 14:43:48 +00:00
|
|
|
{
|
|
|
|
// llarp::LogDebug("connect section has ", key, "=", val);
|
2019-05-09 15:36:39 +00:00
|
|
|
RouterContact rc;
|
2019-07-02 21:28:28 +00:00
|
|
|
if(!rc.Read(router.c_str()))
|
2019-02-11 14:43:48 +00:00
|
|
|
{
|
2019-07-02 21:28:28 +00:00
|
|
|
llarp::LogWarn("failed to decode bootstrap RC, file='", router,
|
2019-02-11 14:43:48 +00:00
|
|
|
"' rc=", rc);
|
2019-07-12 17:21:29 +00:00
|
|
|
return false;
|
2019-02-11 14:43:48 +00:00
|
|
|
}
|
2019-05-28 19:45:08 +00:00
|
|
|
if(rc.Verify(Now()))
|
2019-02-11 14:43:48 +00:00
|
|
|
{
|
2019-05-11 20:47:37 +00:00
|
|
|
const auto result = bootstrapRCList.insert(rc);
|
2019-05-09 15:36:39 +00:00
|
|
|
if(result.second)
|
|
|
|
llarp::LogInfo("Added bootstrap node ", RouterID(rc.pubkey));
|
|
|
|
else
|
|
|
|
llarp::LogWarn("Duplicate bootstrap node ", RouterID(rc.pubkey));
|
2019-02-11 14:43:48 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if(rc.IsExpired(Now()))
|
|
|
|
{
|
|
|
|
llarp::LogWarn("Bootstrap node ", RouterID(rc.pubkey),
|
|
|
|
" is too old and needs to be refreshed");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-07-02 21:28:28 +00:00
|
|
|
llarp::LogError("malformed rc file='", router, "' rc=", rc);
|
2019-02-11 14:43:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-26 21:39:29 +00:00
|
|
|
// Init components after relevant config settings loaded
|
|
|
|
_outboundMessageHandler.Init(&_linkManager, _logic);
|
|
|
|
_outboundSessionMaker.Init(&_linkManager, &_rcLookupHandler, _logic,
|
|
|
|
_nodedb, threadpool());
|
|
|
|
_linkManager.Init(&_outboundSessionMaker);
|
|
|
|
_rcLookupHandler.Init(_dht, _nodedb, threadpool(), &_linkManager,
|
|
|
|
&_hiddenServiceContext, strictConnectPubkeys,
|
|
|
|
bootstrapRCList, whitelistRouters, m_isServiceNode);
|
|
|
|
|
|
|
|
if(!usingSNSeed)
|
|
|
|
{
|
|
|
|
ident_keyfile = conf->router.identKeyfile();
|
|
|
|
}
|
|
|
|
|
|
|
|
// create inbound links, if we are a service node
|
2019-08-07 16:33:29 +00:00
|
|
|
for(const auto &serverConfig : conf->links.inboundLinks())
|
2019-06-26 21:39:29 +00:00
|
|
|
{
|
2019-08-07 16:33:29 +00:00
|
|
|
// get default factory
|
|
|
|
auto inboundLinkFactory = LinkFactory::Obtain(_defaultLinkType, true);
|
|
|
|
// for each option if provided ...
|
|
|
|
for(const auto &opt : std::get< LinksConfig::Options >(serverConfig))
|
|
|
|
{
|
|
|
|
// try interpreting it as a link type
|
|
|
|
const auto linktype = LinkFactory::TypeFromName(opt);
|
|
|
|
if(linktype != LinkFactory::LinkType::eLinkUnknown)
|
|
|
|
{
|
|
|
|
// override link factory if it's a valid link type
|
|
|
|
auto factory = LinkFactory::Obtain(linktype, true);
|
|
|
|
if(factory)
|
|
|
|
{
|
|
|
|
inboundLinkFactory = std::move(factory);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
auto server = inboundLinkFactory(
|
2019-06-26 21:39:29 +00:00
|
|
|
encryption(), util::memFn(&AbstractRouter::rc, this),
|
|
|
|
util::memFn(&AbstractRouter::HandleRecvLinkMessageBuffer, this),
|
2019-08-07 16:33:29 +00:00
|
|
|
util::memFn(&AbstractRouter::Sign, this),
|
2019-06-26 21:39:29 +00:00
|
|
|
util::memFn(&IOutboundSessionMaker::OnSessionEstablished,
|
|
|
|
&_outboundSessionMaker),
|
|
|
|
util::memFn(&AbstractRouter::CheckRenegotiateValid, this),
|
|
|
|
util::memFn(&IOutboundSessionMaker::OnConnectTimeout,
|
|
|
|
&_outboundSessionMaker),
|
2019-11-04 18:49:08 +00:00
|
|
|
util::memFn(&AbstractRouter::SessionClosed, this),
|
|
|
|
util::memFn(&AbstractRouter::PumpLL, this));
|
2019-06-26 21:39:29 +00:00
|
|
|
|
|
|
|
if(!server->EnsureKeys(transport_keyfile.string().c_str()))
|
|
|
|
{
|
|
|
|
llarp::LogError("failed to ensure keyfile ", transport_keyfile);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2019-08-07 16:33:29 +00:00
|
|
|
const auto &key = std::get< LinksConfig::Interface >(serverConfig);
|
|
|
|
int af = std::get< LinksConfig::AddressFamily >(serverConfig);
|
|
|
|
uint16_t port = std::get< LinksConfig::Port >(serverConfig);
|
2019-06-26 21:39:29 +00:00
|
|
|
if(!server->Configure(netloop(), key, af, port))
|
|
|
|
{
|
|
|
|
LogError("failed to bind inbound link on ", key, " port ", port);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
_linkManager.AddLink(std::move(server), true);
|
|
|
|
}
|
|
|
|
|
|
|
|
// set network config
|
|
|
|
netConfig = conf->network.netConfig();
|
2018-12-19 16:17:41 +00:00
|
|
|
|
2019-06-26 21:39:29 +00:00
|
|
|
// Network config
|
|
|
|
if(conf->network.enableProfiling().has_value())
|
2018-12-19 17:48:29 +00:00
|
|
|
{
|
2019-06-26 21:39:29 +00:00
|
|
|
if(conf->network.enableProfiling().value())
|
|
|
|
{
|
|
|
|
routerProfiling().Enable();
|
|
|
|
LogInfo("router profiling explicitly enabled");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
routerProfiling().Disable();
|
|
|
|
LogInfo("router profiling explicitly disabled");
|
|
|
|
}
|
2018-12-19 17:48:29 +00:00
|
|
|
}
|
2019-06-26 21:39:29 +00:00
|
|
|
|
|
|
|
if(!conf->network.routerProfilesFile().empty())
|
2018-12-19 16:17:41 +00:00
|
|
|
{
|
2019-06-26 21:39:29 +00:00
|
|
|
routerProfilesFile = conf->network.routerProfilesFile();
|
|
|
|
routerProfiling().Load(routerProfilesFile.c_str());
|
|
|
|
llarp::LogInfo("setting profiles to ", routerProfilesFile);
|
2018-12-19 16:17:41 +00:00
|
|
|
}
|
|
|
|
|
2019-06-26 21:39:29 +00:00
|
|
|
// API config
|
|
|
|
enableRPCServer = conf->api.enableRPCServer();
|
|
|
|
rpcBindAddr = conf->api.rpcBindAddr();
|
2019-06-04 13:19:45 +00:00
|
|
|
|
2019-06-26 21:39:29 +00:00
|
|
|
// Services config
|
|
|
|
for(const auto &service : conf->services.services)
|
2019-06-04 13:19:45 +00:00
|
|
|
{
|
2019-06-26 21:39:29 +00:00
|
|
|
if(LoadHiddenServiceConfig(service.second))
|
|
|
|
{
|
|
|
|
llarp::LogInfo("loaded hidden service config for ", service.first);
|
|
|
|
}
|
|
|
|
else
|
2019-06-04 13:19:45 +00:00
|
|
|
{
|
2019-06-26 21:39:29 +00:00
|
|
|
llarp::LogWarn("failed to load hidden service config for ",
|
|
|
|
service.first);
|
2019-06-04 13:19:45 +00:00
|
|
|
}
|
|
|
|
}
|
2019-06-26 21:39:29 +00:00
|
|
|
|
|
|
|
// Logging config
|
|
|
|
|
|
|
|
auto logfile = conf->logging.m_LogFile;
|
|
|
|
|
|
|
|
if(conf->logging.m_LogJSON)
|
2019-06-04 13:29:16 +00:00
|
|
|
{
|
2019-06-26 21:39:29 +00:00
|
|
|
LogContext::Instance().logStream = std::make_unique< JSONLogStream >(
|
|
|
|
diskworker(), logfile, 100, logfile != stdout);
|
2019-06-04 13:29:16 +00:00
|
|
|
}
|
2019-06-26 21:39:29 +00:00
|
|
|
else if(logfile != stdout)
|
2019-06-04 13:29:16 +00:00
|
|
|
{
|
2019-06-26 21:39:29 +00:00
|
|
|
LogContext::Instance().logStream =
|
|
|
|
std::make_unique< FileLogStream >(diskworker(), logfile, 100, true);
|
2019-06-04 13:29:16 +00:00
|
|
|
}
|
2018-12-19 17:48:29 +00:00
|
|
|
|
2019-06-26 21:39:29 +00:00
|
|
|
netConfig.insert(conf->dns.netConfig.begin(), conf->dns.netConfig.end());
|
|
|
|
|
|
|
|
return true;
|
2019-06-10 12:47:21 +00:00
|
|
|
}
|
|
|
|
|
2019-06-26 21:39:29 +00:00
|
|
|
bool
|
|
|
|
Router::CheckRenegotiateValid(RouterContact newrc, RouterContact oldrc)
|
2019-03-31 15:09:59 +00:00
|
|
|
{
|
2019-06-26 21:39:29 +00:00
|
|
|
return _rcLookupHandler.CheckRenegotiateValid(newrc, oldrc);
|
2019-03-31 15:09:59 +00:00
|
|
|
}
|
|
|
|
|
2019-04-03 19:05:44 +00:00
|
|
|
bool
|
2019-05-09 15:36:39 +00:00
|
|
|
Router::IsBootstrapNode(const RouterID r) const
|
2019-04-03 19:05:44 +00:00
|
|
|
{
|
2019-05-09 15:36:39 +00:00
|
|
|
return std::count_if(
|
|
|
|
bootstrapRCList.begin(), bootstrapRCList.end(),
|
|
|
|
[r](const RouterContact &rc) -> bool { return rc.pubkey == r; })
|
|
|
|
> 0;
|
2019-04-03 19:05:44 +00:00
|
|
|
}
|
2019-04-05 14:58:22 +00:00
|
|
|
|
2019-07-15 16:56:09 +00:00
|
|
|
bool
|
|
|
|
Router::ShouldReportStats(llarp_time_t now) const
|
|
|
|
{
|
2019-07-17 12:25:51 +00:00
|
|
|
static constexpr llarp_time_t ReportStatsInterval = 60 * 60 * 1000;
|
2019-07-15 16:56:09 +00:00
|
|
|
return now - m_LastStatsReport > ReportStatsInterval;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Router::ReportStats()
|
|
|
|
{
|
|
|
|
const auto now = Now();
|
|
|
|
LogInfo(nodedb()->num_loaded(), " RCs loaded");
|
|
|
|
LogInfo(bootstrapRCList.size(), " bootstrap peers");
|
|
|
|
LogInfo(NumberOfConnectedRouters(), " router connections");
|
|
|
|
if(IsServiceNode())
|
|
|
|
{
|
|
|
|
LogInfo(NumberOfConnectedClients(), " client connections");
|
|
|
|
LogInfo(_rc.Age(now), " ms since we last updated our RC");
|
|
|
|
LogInfo(_rc.TimeUntilExpires(now), " ms until our RC expires");
|
|
|
|
}
|
|
|
|
LogInfo(now, " system time");
|
|
|
|
LogInfo(m_LastStatsReport, " last reported stats");
|
|
|
|
m_LastStatsReport = now;
|
|
|
|
}
|
|
|
|
|
2018-12-10 16:26:46 +00:00
|
|
|
void
|
|
|
|
Router::Tick()
|
2018-06-19 17:11:24 +00:00
|
|
|
{
|
2019-04-23 18:29:42 +00:00
|
|
|
if(_stopping)
|
|
|
|
return;
|
2019-02-11 19:45:42 +00:00
|
|
|
// LogDebug("tick router");
|
2019-11-05 16:58:53 +00:00
|
|
|
const auto now = Now();
|
2018-12-19 17:48:29 +00:00
|
|
|
|
2019-03-04 17:03:18 +00:00
|
|
|
routerProfiling().Tick();
|
2019-06-10 12:47:21 +00:00
|
|
|
|
2019-07-15 16:56:09 +00:00
|
|
|
if(ShouldReportStats(now))
|
|
|
|
{
|
|
|
|
ReportStats();
|
|
|
|
}
|
|
|
|
|
2019-06-26 21:39:29 +00:00
|
|
|
_rcLookupHandler.PeriodicUpdate(now);
|
2019-07-15 16:56:09 +00:00
|
|
|
|
|
|
|
const bool isSvcNode = IsServiceNode();
|
|
|
|
|
2019-08-05 13:39:27 +00:00
|
|
|
if(_rc.ExpiresSoon(now, randint() % 10000)
|
|
|
|
|| (now - _rc.last_updated) > rcRegenInterval)
|
2018-12-19 17:48:29 +00:00
|
|
|
{
|
2019-08-05 13:39:27 +00:00
|
|
|
LogInfo("regenerating RC");
|
|
|
|
if(!UpdateOurRC(false))
|
|
|
|
LogError("Failed to update our RC");
|
|
|
|
}
|
2019-03-31 15:09:59 +00:00
|
|
|
|
2019-08-05 13:39:27 +00:00
|
|
|
if(isSvcNode)
|
|
|
|
{
|
2019-06-26 21:39:29 +00:00
|
|
|
// remove RCs for nodes that are no longer allowed by network policy
|
2019-05-09 15:36:39 +00:00
|
|
|
nodedb()->RemoveIf([&](const RouterContact &rc) -> bool {
|
2019-05-11 20:53:08 +00:00
|
|
|
if(IsBootstrapNode(rc.pubkey))
|
|
|
|
return false;
|
2019-06-26 21:39:29 +00:00
|
|
|
return !_rcLookupHandler.RemoteIsAllowed(rc.pubkey);
|
2019-05-09 15:36:39 +00:00
|
|
|
});
|
2018-12-19 17:48:29 +00:00
|
|
|
}
|
2019-02-25 12:46:40 +00:00
|
|
|
|
2019-06-26 21:39:29 +00:00
|
|
|
_linkManager.CheckPersistingSessions(now);
|
2018-12-10 16:26:46 +00:00
|
|
|
|
2019-03-29 15:08:31 +00:00
|
|
|
const size_t connected = NumberOfConnectedRouters();
|
|
|
|
const size_t N = nodedb()->num_loaded();
|
2019-08-13 12:40:22 +00:00
|
|
|
if(N < llarp::path::default_len)
|
2018-12-10 16:26:46 +00:00
|
|
|
{
|
2019-08-13 12:40:22 +00:00
|
|
|
LogInfo("We need at least ", llarp::path::default_len,
|
2019-02-11 19:45:42 +00:00
|
|
|
" service nodes to build paths but we have ", N, " in nodedb");
|
2019-06-26 21:39:29 +00:00
|
|
|
|
|
|
|
_rcLookupHandler.ExploreNetwork();
|
2018-12-18 17:37:59 +00:00
|
|
|
}
|
2019-09-03 15:56:56 +00:00
|
|
|
size_t connectToNum = _outboundSessionMaker.minConnectedRouters;
|
|
|
|
const auto strictConnect = _rcLookupHandler.NumberOfStrictConnectRouters();
|
|
|
|
if(strictConnect > 0 && connectToNum > strictConnect)
|
2018-12-18 17:37:59 +00:00
|
|
|
{
|
2019-09-03 15:56:56 +00:00
|
|
|
connectToNum = strictConnect;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(connected < connectToNum)
|
|
|
|
{
|
|
|
|
size_t dlt = connectToNum - connected;
|
2019-04-25 11:00:18 +00:00
|
|
|
LogInfo("connecting to ", dlt, " random routers to keep alive");
|
2019-06-26 21:39:29 +00:00
|
|
|
_outboundSessionMaker.ConnectToRandomRouters(dlt, now);
|
2018-08-14 21:17:18 +00:00
|
|
|
}
|
2019-03-25 12:52:32 +00:00
|
|
|
|
2019-11-05 16:58:53 +00:00
|
|
|
_hiddenServiceContext.Tick(now);
|
2019-02-11 19:45:42 +00:00
|
|
|
_exitContext.Tick(now);
|
2019-11-05 16:58:53 +00:00
|
|
|
|
2018-12-10 16:26:46 +00:00
|
|
|
if(rpcCaller)
|
|
|
|
rpcCaller->Tick(now);
|
2019-03-25 15:41:37 +00:00
|
|
|
// save profiles async
|
|
|
|
if(routerProfiling().ShouldSave(now))
|
|
|
|
{
|
2019-05-18 18:46:49 +00:00
|
|
|
diskworker()->addJob(
|
|
|
|
[&]() { routerProfiling().Save(routerProfilesFile.c_str()); });
|
2019-03-25 15:41:37 +00:00
|
|
|
}
|
2019-09-10 14:16:32 +00:00
|
|
|
|
|
|
|
// get connected peers
|
|
|
|
std::set< dht::Key_t > peersWeHave;
|
|
|
|
_linkManager.ForEachPeer([&peersWeHave](ILinkSession *s) {
|
|
|
|
if(!s->IsEstablished())
|
|
|
|
return;
|
|
|
|
peersWeHave.emplace(s->GetPubKey());
|
|
|
|
});
|
|
|
|
// remove any nodes we don't have connections to
|
|
|
|
_dht->impl->Nodes()->RemoveIf([&peersWeHave](const dht::Key_t &k) -> bool {
|
|
|
|
return peersWeHave.count(k) == 0;
|
|
|
|
});
|
2019-11-05 16:58:53 +00:00
|
|
|
// expire paths
|
|
|
|
paths.ExpirePaths(now);
|
2019-05-18 18:46:49 +00:00
|
|
|
} // namespace llarp
|
2018-08-22 16:19:51 +00:00
|
|
|
|
2018-12-17 20:46:08 +00:00
|
|
|
bool
|
2019-02-11 19:45:42 +00:00
|
|
|
Router::Sign(Signature &sig, const llarp_buffer_t &buf) const
|
2018-12-17 20:46:08 +00:00
|
|
|
{
|
2019-06-13 21:58:17 +00:00
|
|
|
metrics::TimerGuard t("Router", "Sign");
|
2019-05-28 19:45:08 +00:00
|
|
|
return CryptoManager::instance()->sign(sig, identity(), buf);
|
2018-12-17 20:46:08 +00:00
|
|
|
}
|
|
|
|
|
2018-12-10 16:26:46 +00:00
|
|
|
void
|
|
|
|
Router::ScheduleTicker(uint64_t ms)
|
2018-06-06 12:46:26 +00:00
|
|
|
{
|
2019-01-29 02:16:31 +00:00
|
|
|
ticker_job_id = _logic->call_later({ms, this, &handle_router_ticker});
|
2018-06-06 12:46:26 +00:00
|
|
|
}
|
2018-12-10 16:26:46 +00:00
|
|
|
|
|
|
|
void
|
2019-02-11 19:45:42 +00:00
|
|
|
Router::SessionClosed(RouterID remote)
|
2018-06-20 12:34:48 +00:00
|
|
|
{
|
2019-02-25 12:46:40 +00:00
|
|
|
dht::Key_t k(remote);
|
|
|
|
dht()->impl->Nodes()->DelNode(k);
|
2019-06-26 21:39:29 +00:00
|
|
|
|
2019-02-11 19:45:42 +00:00
|
|
|
LogInfo("Session to ", remote, " fully closed");
|
2018-06-20 12:34:48 +00:00
|
|
|
}
|
2018-12-10 16:26:46 +00:00
|
|
|
|
2019-06-26 21:39:29 +00:00
|
|
|
bool
|
|
|
|
Router::GetRandomConnectedRouter(RouterContact &result) const
|
2018-06-06 12:46:26 +00:00
|
|
|
{
|
2019-06-26 21:39:29 +00:00
|
|
|
return _linkManager.GetRandomConnectedRouter(result);
|
2018-06-06 12:46:26 +00:00
|
|
|
}
|
2018-05-30 20:56:47 +00:00
|
|
|
|
2018-12-10 16:26:46 +00:00
|
|
|
void
|
2019-08-01 07:44:26 +00:00
|
|
|
Router::HandleDHTLookupForExplore(ABSL_ATTRIBUTE_UNUSED RouterID remote,
|
2019-06-26 21:39:29 +00:00
|
|
|
const std::vector< RouterContact > &results)
|
2018-07-03 13:33:37 +00:00
|
|
|
{
|
2019-06-26 21:39:29 +00:00
|
|
|
for(const auto &rc : results)
|
2018-12-10 16:26:46 +00:00
|
|
|
{
|
2019-06-26 21:39:29 +00:00
|
|
|
_rcLookupHandler.CheckRC(rc);
|
2018-12-10 16:26:46 +00:00
|
|
|
}
|
2018-06-01 14:08:54 +00:00
|
|
|
}
|
2018-06-13 12:58:51 +00:00
|
|
|
|
2019-06-26 21:39:29 +00:00
|
|
|
// TODO: refactor callers and remove this function
|
2018-12-10 16:26:46 +00:00
|
|
|
void
|
2019-06-26 21:39:29 +00:00
|
|
|
Router::LookupRouter(RouterID remote, RouterLookupHandler resultHandler)
|
2018-10-09 12:06:30 +00:00
|
|
|
{
|
2019-06-26 21:39:29 +00:00
|
|
|
_rcLookupHandler.GetRC(
|
|
|
|
remote,
|
|
|
|
[=](const RouterID &id, const RouterContact *const rc,
|
|
|
|
const RCRequestResult result) {
|
|
|
|
(void)id;
|
2019-07-26 12:10:04 +00:00
|
|
|
if(resultHandler)
|
2019-06-26 21:39:29 +00:00
|
|
|
{
|
2019-07-26 12:10:04 +00:00
|
|
|
std::vector< RouterContact > routers;
|
|
|
|
if(result == RCRequestResult::Success && rc != nullptr)
|
|
|
|
{
|
|
|
|
routers.push_back(*rc);
|
|
|
|
}
|
2019-06-26 21:39:29 +00:00
|
|
|
resultHandler(routers);
|
|
|
|
}
|
|
|
|
});
|
2018-12-10 16:26:46 +00:00
|
|
|
}
|
|
|
|
|
2019-02-15 22:19:19 +00:00
|
|
|
void
|
2019-02-17 12:13:34 +00:00
|
|
|
Router::SetRouterWhitelist(const std::vector< RouterID > &routers)
|
2019-02-15 22:19:19 +00:00
|
|
|
{
|
2019-06-26 21:39:29 +00:00
|
|
|
_rcLookupHandler.SetRouterWhitelist(routers);
|
2019-02-15 22:19:19 +00:00
|
|
|
}
|
|
|
|
|
2019-07-08 15:26:06 +00:00
|
|
|
/// this function ensure there are sane defualts in a net config
|
|
|
|
static void
|
|
|
|
EnsureNetConfigDefaultsSane(
|
|
|
|
std::unordered_multimap< std::string, std::string > &netConfig)
|
|
|
|
{
|
|
|
|
static const std::unordered_map< std::string,
|
|
|
|
std::function< std::string(void) > >
|
|
|
|
netConfigDefaults = {
|
|
|
|
{"ifname", llarp::FindFreeTun},
|
|
|
|
{"ifaddr", llarp::FindFreeRange},
|
|
|
|
{"local-dns", []() -> std::string { return "127.0.0.1:53"; }}};
|
|
|
|
// populate with fallback defaults if values not present
|
|
|
|
auto itr = netConfigDefaults.begin();
|
|
|
|
while(itr != netConfigDefaults.end())
|
|
|
|
{
|
|
|
|
auto found = netConfig.find(itr->first);
|
|
|
|
if(found == netConfig.end() || found->second.empty())
|
|
|
|
{
|
2019-09-09 12:10:26 +00:00
|
|
|
auto val = itr->second();
|
|
|
|
if(!val.empty())
|
|
|
|
netConfig.emplace(itr->first, std::move(val));
|
2019-07-08 15:26:06 +00:00
|
|
|
}
|
|
|
|
++itr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-10 16:26:46 +00:00
|
|
|
bool
|
2019-10-04 09:10:55 +00:00
|
|
|
Router::StartJsonRpc()
|
2018-12-10 16:26:46 +00:00
|
|
|
{
|
2018-12-24 16:09:05 +00:00
|
|
|
if(_running || _stopping)
|
|
|
|
return false;
|
2018-12-10 16:26:46 +00:00
|
|
|
|
|
|
|
if(enableRPCServer)
|
2018-10-09 12:06:30 +00:00
|
|
|
{
|
2018-12-10 16:26:46 +00:00
|
|
|
if(rpcBindAddr.empty())
|
|
|
|
{
|
|
|
|
rpcBindAddr = DefaultRPCBindAddr;
|
|
|
|
}
|
2019-02-11 19:45:42 +00:00
|
|
|
rpcServer = std::make_unique< rpc::Server >(this);
|
2018-12-10 16:26:46 +00:00
|
|
|
while(!rpcServer->Start(rpcBindAddr))
|
|
|
|
{
|
2019-02-11 19:45:42 +00:00
|
|
|
LogError("failed to bind jsonrpc to ", rpcBindAddr);
|
2018-11-08 12:31:50 +00:00
|
|
|
#if defined(ANDROID) || defined(RPI)
|
2018-12-10 16:26:46 +00:00
|
|
|
sleep(1);
|
2018-11-08 12:31:50 +00:00
|
|
|
#else
|
2018-12-10 16:26:46 +00:00
|
|
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
2018-11-08 12:31:50 +00:00
|
|
|
#endif
|
2018-12-10 16:26:46 +00:00
|
|
|
}
|
2019-02-11 19:45:42 +00:00
|
|
|
LogInfo("Bound RPC server to ", rpcBindAddr);
|
2018-10-09 12:06:30 +00:00
|
|
|
}
|
2019-10-04 09:10:55 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
Router::Run()
|
|
|
|
{
|
|
|
|
if(_running || _stopping)
|
|
|
|
return false;
|
|
|
|
|
2019-01-28 13:04:45 +00:00
|
|
|
if(whitelistRouters)
|
|
|
|
{
|
2019-02-11 19:45:42 +00:00
|
|
|
rpcCaller = std::make_unique< rpc::Caller >(this);
|
2019-03-13 20:01:10 +00:00
|
|
|
rpcCaller->SetAuth(lokidRPCUser, lokidRPCPassword);
|
2019-01-28 13:04:45 +00:00
|
|
|
while(!rpcCaller->Start(lokidRPCAddr))
|
|
|
|
{
|
2019-02-11 19:45:42 +00:00
|
|
|
LogError("failed to start jsonrpc caller to ", lokidRPCAddr);
|
2019-01-28 13:04:45 +00:00
|
|
|
#if defined(ANDROID) || defined(RPI)
|
|
|
|
sleep(1);
|
|
|
|
#else
|
|
|
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
|
|
|
#endif
|
|
|
|
}
|
2019-02-11 19:45:42 +00:00
|
|
|
LogInfo("RPC Caller to ", lokidRPCAddr, " started");
|
2019-01-28 13:04:45 +00:00
|
|
|
}
|
2018-10-09 12:06:30 +00:00
|
|
|
|
2019-07-15 17:19:31 +00:00
|
|
|
if(!cryptoworker->start())
|
|
|
|
{
|
|
|
|
LogError("crypto worker failed to start");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!disk->start())
|
|
|
|
{
|
|
|
|
LogError("disk worker failed to start");
|
|
|
|
return false;
|
|
|
|
}
|
2018-11-19 16:40:49 +00:00
|
|
|
|
2019-02-11 19:45:42 +00:00
|
|
|
routerProfiling().Load(routerProfilesFile.c_str());
|
2018-10-12 12:05:03 +00:00
|
|
|
|
2019-02-11 19:45:42 +00:00
|
|
|
Addr publicAddr(this->addrInfo);
|
2018-10-03 11:01:42 +00:00
|
|
|
|
2018-12-10 16:26:46 +00:00
|
|
|
if(this->publicOverride)
|
2018-07-30 05:58:20 +00:00
|
|
|
{
|
2019-02-11 19:45:42 +00:00
|
|
|
LogDebug("public address:port ", publicAddr);
|
2018-07-30 05:58:20 +00:00
|
|
|
}
|
2018-12-10 16:26:46 +00:00
|
|
|
|
2019-04-08 18:21:01 +00:00
|
|
|
// set public signing key
|
|
|
|
_rc.pubkey = seckey_topublic(identity());
|
|
|
|
|
2019-02-11 19:45:42 +00:00
|
|
|
AddressInfo ai;
|
2019-06-26 21:39:29 +00:00
|
|
|
_linkManager.ForEachInboundLink([&](LinkLayer_ptr link) {
|
2019-01-05 13:45:05 +00:00
|
|
|
if(link->GetOurAddressInfo(ai))
|
2018-12-10 16:26:46 +00:00
|
|
|
{
|
2019-01-05 13:45:05 +00:00
|
|
|
// override ip and port
|
|
|
|
if(this->publicOverride)
|
2018-12-10 16:26:46 +00:00
|
|
|
{
|
2019-01-05 13:45:05 +00:00
|
|
|
ai.ip = *publicAddr.addr6();
|
|
|
|
ai.port = publicAddr.port();
|
2018-12-10 16:26:46 +00:00
|
|
|
}
|
2019-08-26 23:29:17 +00:00
|
|
|
if(RouterContact::BlockBogons && IsBogon(ai.ip))
|
2019-06-26 21:39:29 +00:00
|
|
|
return;
|
2019-01-05 13:45:05 +00:00
|
|
|
_rc.addrs.push_back(ai);
|
2019-04-08 18:21:01 +00:00
|
|
|
if(ExitEnabled())
|
|
|
|
{
|
|
|
|
const llarp::Addr addr(ai);
|
2019-04-08 18:25:06 +00:00
|
|
|
const nuint32_t a{addr.addr4()->s_addr};
|
2019-04-08 18:21:01 +00:00
|
|
|
_rc.exits.emplace_back(_rc.pubkey, a);
|
2019-06-26 21:39:29 +00:00
|
|
|
LogInfo("Exit relay started, advertised as exiting at: ", a);
|
2019-04-08 18:21:01 +00:00
|
|
|
}
|
2018-06-28 11:29:10 +00:00
|
|
|
}
|
2019-06-26 21:39:29 +00:00
|
|
|
});
|
2018-12-10 16:26:46 +00:00
|
|
|
|
|
|
|
// set public encryption key
|
2019-02-11 19:45:42 +00:00
|
|
|
_rc.enckey = seckey_topublic(encryption());
|
2019-04-08 18:21:01 +00:00
|
|
|
|
2019-02-11 19:45:42 +00:00
|
|
|
LogInfo("Signing rc...");
|
2019-05-28 19:45:08 +00:00
|
|
|
if(!_rc.Sign(identity()))
|
2018-12-10 16:26:46 +00:00
|
|
|
{
|
2019-02-11 19:45:42 +00:00
|
|
|
LogError("failed to sign rc");
|
2018-12-10 16:26:46 +00:00
|
|
|
return false;
|
2018-06-28 11:29:10 +00:00
|
|
|
}
|
2018-05-22 15:54:19 +00:00
|
|
|
|
2018-12-10 16:26:46 +00:00
|
|
|
if(!SaveRC())
|
|
|
|
{
|
2019-02-11 19:45:42 +00:00
|
|
|
LogError("failed to save RC");
|
2018-12-10 16:26:46 +00:00
|
|
|
return false;
|
|
|
|
}
|
2019-08-23 11:32:52 +00:00
|
|
|
_outboundSessionMaker.SetOurRouter(pubkey());
|
2019-09-05 17:39:09 +00:00
|
|
|
if(!_linkManager.StartLinks(_logic, cryptoworker))
|
2018-06-10 14:05:48 +00:00
|
|
|
{
|
2019-06-26 21:39:29 +00:00
|
|
|
LogWarn("One or more links failed to start.");
|
|
|
|
return false;
|
2018-06-10 14:05:48 +00:00
|
|
|
}
|
2018-05-22 15:54:19 +00:00
|
|
|
|
2019-07-08 15:26:06 +00:00
|
|
|
EnsureNetConfigDefaultsSane(netConfig);
|
|
|
|
|
2019-08-12 11:20:57 +00:00
|
|
|
const auto limits =
|
|
|
|
IsServiceNode() ? llarp::limits::snode : llarp::limits::client;
|
|
|
|
|
2019-08-12 12:40:38 +00:00
|
|
|
_outboundSessionMaker.minConnectedRouters = std::max(
|
|
|
|
_outboundSessionMaker.minConnectedRouters, limits.DefaultMinRouters);
|
|
|
|
_outboundSessionMaker.maxConnectedRouters = std::max(
|
|
|
|
_outboundSessionMaker.maxConnectedRouters, limits.DefaultMaxRouters);
|
2019-08-12 11:20:57 +00:00
|
|
|
|
2019-06-26 21:39:29 +00:00
|
|
|
if(IsServiceNode())
|
2018-11-12 16:43:40 +00:00
|
|
|
{
|
2018-12-10 16:26:46 +00:00
|
|
|
// initialize as service node
|
|
|
|
if(!InitServiceNode())
|
|
|
|
{
|
2019-02-11 19:45:42 +00:00
|
|
|
LogError("Failed to initialize service node");
|
2018-12-10 16:26:46 +00:00
|
|
|
return false;
|
|
|
|
}
|
2019-02-11 19:45:42 +00:00
|
|
|
RouterID us = pubkey();
|
|
|
|
LogInfo("initalized service node: ", us);
|
2019-08-12 11:20:57 +00:00
|
|
|
|
2019-05-06 14:21:47 +00:00
|
|
|
// relays do not use profiling
|
|
|
|
routerProfiling().Disable();
|
2018-11-12 16:43:40 +00:00
|
|
|
}
|
2018-12-10 16:26:46 +00:00
|
|
|
else
|
2018-09-18 20:56:22 +00:00
|
|
|
{
|
2018-12-10 16:26:46 +00:00
|
|
|
// we are a client
|
|
|
|
// regenerate keys and resign rc before everything else
|
2019-05-28 19:45:08 +00:00
|
|
|
CryptoManager::instance()->identity_keygen(_identity);
|
|
|
|
CryptoManager::instance()->encryption_keygen(_encryption);
|
2019-02-11 19:45:42 +00:00
|
|
|
_rc.pubkey = seckey_topublic(identity());
|
|
|
|
_rc.enckey = seckey_topublic(encryption());
|
2019-05-28 19:45:08 +00:00
|
|
|
if(!_rc.Sign(identity()))
|
2018-12-10 16:26:46 +00:00
|
|
|
{
|
2019-02-11 19:45:42 +00:00
|
|
|
LogError("failed to regenerate keys and sign RC");
|
2018-12-10 16:26:46 +00:00
|
|
|
return false;
|
|
|
|
}
|
2019-01-16 21:16:23 +00:00
|
|
|
|
2019-07-03 14:32:51 +00:00
|
|
|
if(!CreateDefaultHiddenService())
|
2018-12-10 16:26:46 +00:00
|
|
|
{
|
2019-07-03 14:32:51 +00:00
|
|
|
LogError("failed to set up default network endpoint");
|
|
|
|
return false;
|
2018-12-10 16:26:46 +00:00
|
|
|
}
|
2018-09-18 20:56:22 +00:00
|
|
|
}
|
2018-12-10 16:26:46 +00:00
|
|
|
|
2019-02-11 19:45:42 +00:00
|
|
|
LogInfo("starting hidden service context...");
|
2019-02-22 16:21:05 +00:00
|
|
|
if(!hiddenServiceContext().StartAll())
|
2018-10-03 11:01:42 +00:00
|
|
|
{
|
2019-02-11 19:45:42 +00:00
|
|
|
LogError("Failed to start hidden service context");
|
2018-11-26 22:46:22 +00:00
|
|
|
return false;
|
2018-10-03 11:01:42 +00:00
|
|
|
}
|
2019-06-26 21:39:29 +00:00
|
|
|
|
2019-01-29 02:16:31 +00:00
|
|
|
llarp_dht_context_start(dht(), pubkey());
|
2019-06-26 21:39:29 +00:00
|
|
|
|
|
|
|
for(const auto &rc : bootstrapRCList)
|
|
|
|
{
|
|
|
|
if(this->nodedb()->Insert(rc))
|
|
|
|
{
|
|
|
|
LogInfo("added bootstrap node ", RouterID(rc.pubkey));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
LogError("Failed to add bootstrap node ", RouterID(rc.pubkey));
|
|
|
|
}
|
|
|
|
_dht->impl->Nodes()->PutNode(rc);
|
|
|
|
}
|
|
|
|
|
2019-10-04 09:10:55 +00:00
|
|
|
LogInfo("have ", _nodedb->num_loaded(), " routers");
|
2019-06-26 21:39:29 +00:00
|
|
|
|
2019-09-16 16:12:05 +00:00
|
|
|
_netloop->add_ticker(std::bind(&Router::PumpLL, this));
|
2019-10-07 10:08:47 +00:00
|
|
|
|
2018-12-10 16:26:46 +00:00
|
|
|
ScheduleTicker(1000);
|
2018-12-24 16:09:05 +00:00
|
|
|
_running.store(true);
|
2019-04-22 12:25:25 +00:00
|
|
|
_startedAt = Now();
|
2018-12-24 16:09:05 +00:00
|
|
|
return _running;
|
|
|
|
}
|
|
|
|
|
2019-10-09 13:08:38 +00:00
|
|
|
bool
|
|
|
|
Router::IsRunning() const
|
|
|
|
{
|
|
|
|
return _running;
|
|
|
|
}
|
|
|
|
|
2019-04-22 12:25:25 +00:00
|
|
|
llarp_time_t
|
|
|
|
Router::Uptime() const
|
|
|
|
{
|
|
|
|
const llarp_time_t _now = Now();
|
|
|
|
if(_startedAt && _now > _startedAt)
|
|
|
|
return _now - _startedAt;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-12-24 16:09:05 +00:00
|
|
|
static void
|
|
|
|
RouterAfterStopLinks(void *u, uint64_t, uint64_t)
|
|
|
|
{
|
2019-07-30 23:42:13 +00:00
|
|
|
auto *self = static_cast< Router * >(u);
|
2018-12-24 16:09:05 +00:00
|
|
|
self->Close();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
RouterAfterStopIssued(void *u, uint64_t, uint64_t)
|
|
|
|
{
|
2019-07-30 23:42:13 +00:00
|
|
|
auto *self = static_cast< Router * >(u);
|
2018-12-24 16:09:05 +00:00
|
|
|
self->StopLinks();
|
2019-07-09 19:44:53 +00:00
|
|
|
self->nodedb()->AsyncFlushToDisk();
|
2019-01-29 02:16:31 +00:00
|
|
|
self->_logic->call_later({200, self, &RouterAfterStopLinks});
|
2018-12-24 16:09:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Router::StopLinks()
|
|
|
|
{
|
2019-06-26 21:39:29 +00:00
|
|
|
_linkManager.Stop();
|
2018-06-10 14:05:48 +00:00
|
|
|
}
|
|
|
|
|
2018-12-10 16:26:46 +00:00
|
|
|
void
|
|
|
|
Router::Stop()
|
2018-11-26 13:29:45 +00:00
|
|
|
{
|
2018-12-24 16:09:05 +00:00
|
|
|
if(!_running)
|
|
|
|
return;
|
|
|
|
if(_stopping)
|
|
|
|
return;
|
|
|
|
|
|
|
|
_stopping.store(true);
|
2019-02-11 19:45:42 +00:00
|
|
|
LogInfo("stopping router");
|
2019-02-22 16:21:05 +00:00
|
|
|
hiddenServiceContext().StopAll();
|
2019-02-11 19:45:42 +00:00
|
|
|
_exitContext.Stop();
|
2018-12-24 16:09:05 +00:00
|
|
|
if(rpcServer)
|
|
|
|
rpcServer->Stop();
|
2019-09-16 10:21:12 +00:00
|
|
|
paths.PumpUpstream();
|
2019-06-26 21:39:29 +00:00
|
|
|
_linkManager.PumpLinks();
|
2019-01-29 02:16:31 +00:00
|
|
|
_logic->call_later({200, this, &RouterAfterStopIssued});
|
2018-11-26 13:29:45 +00:00
|
|
|
}
|
2018-08-02 23:30:34 +00:00
|
|
|
|
2018-12-10 16:26:46 +00:00
|
|
|
bool
|
2019-02-11 19:45:42 +00:00
|
|
|
Router::HasSessionTo(const RouterID &remote) const
|
2018-09-03 13:10:56 +00:00
|
|
|
{
|
2019-06-26 21:39:29 +00:00
|
|
|
return _linkManager.HasSessionTo(remote);
|
2018-09-03 13:10:56 +00:00
|
|
|
}
|
|
|
|
|
2018-12-10 16:26:46 +00:00
|
|
|
void
|
|
|
|
Router::ConnectToRandomRouters(int want)
|
|
|
|
{
|
2019-06-26 21:39:29 +00:00
|
|
|
_outboundSessionMaker.ConnectToRandomRouters(want, Now());
|
2018-06-07 16:22:49 +00:00
|
|
|
}
|
|
|
|
|
2018-12-10 16:26:46 +00:00
|
|
|
bool
|
|
|
|
Router::InitServiceNode()
|
2018-11-26 13:29:45 +00:00
|
|
|
{
|
2019-02-11 19:45:42 +00:00
|
|
|
LogInfo("accepting transit traffic");
|
2018-12-10 16:26:46 +00:00
|
|
|
paths.AllowTransit();
|
2019-01-29 02:16:31 +00:00
|
|
|
llarp_dht_allow_transit(dht());
|
2019-02-11 19:45:42 +00:00
|
|
|
return _exitContext.AddExitEndpoint("default-connectivity", netConfig);
|
2018-11-26 13:29:45 +00:00
|
|
|
}
|
2018-06-14 17:35:12 +00:00
|
|
|
|
2018-12-24 16:09:05 +00:00
|
|
|
bool
|
2019-07-02 21:28:28 +00:00
|
|
|
Router::ValidateConfig(ABSL_ATTRIBUTE_UNUSED Config *conf) const
|
2018-12-24 16:09:05 +00:00
|
|
|
{
|
2019-07-02 21:28:28 +00:00
|
|
|
return true;
|
2018-12-24 16:09:05 +00:00
|
|
|
}
|
|
|
|
|
2018-12-10 16:26:46 +00:00
|
|
|
bool
|
2019-02-11 14:43:48 +00:00
|
|
|
Router::Reconfigure(Config *)
|
2018-06-18 22:05:02 +00:00
|
|
|
{
|
2018-12-10 16:26:46 +00:00
|
|
|
// TODO: implement me
|
|
|
|
return true;
|
2018-05-20 17:45:47 +00:00
|
|
|
}
|
2018-01-08 13:49:05 +00:00
|
|
|
|
2019-06-26 21:39:29 +00:00
|
|
|
bool
|
|
|
|
Router::TryConnectAsync(RouterContact rc, uint16_t tries)
|
|
|
|
{
|
|
|
|
(void)tries;
|
|
|
|
|
|
|
|
if(rc.pubkey == pubkey())
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!_rcLookupHandler.RemoteIsAllowed(rc.pubkey))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
_outboundSessionMaker.CreateSessionTo(rc, nullptr);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-12-10 16:26:46 +00:00
|
|
|
bool
|
2019-01-05 13:45:05 +00:00
|
|
|
Router::InitOutboundLinks()
|
2018-06-18 22:03:50 +00:00
|
|
|
{
|
2019-08-07 16:33:29 +00:00
|
|
|
const auto linkTypeName = LinkFactory::NameFromType(_defaultLinkType);
|
|
|
|
LogInfo("initialize outbound link: ", linkTypeName);
|
|
|
|
auto factory = LinkFactory::Obtain(_defaultLinkType, false);
|
|
|
|
if(factory == nullptr)
|
|
|
|
{
|
|
|
|
LogError("cannot initialize outbound link of type '", linkTypeName,
|
|
|
|
"' as it has no implementation");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
auto link =
|
|
|
|
factory(encryption(), util::memFn(&AbstractRouter::rc, this),
|
|
|
|
util::memFn(&AbstractRouter::HandleRecvLinkMessageBuffer, this),
|
|
|
|
util::memFn(&AbstractRouter::Sign, this),
|
|
|
|
util::memFn(&IOutboundSessionMaker::OnSessionEstablished,
|
|
|
|
&_outboundSessionMaker),
|
|
|
|
util::memFn(&AbstractRouter::CheckRenegotiateValid, this),
|
|
|
|
util::memFn(&IOutboundSessionMaker::OnConnectTimeout,
|
|
|
|
&_outboundSessionMaker),
|
2019-11-04 18:53:53 +00:00
|
|
|
util::memFn(&AbstractRouter::SessionClosed, this),
|
|
|
|
util::memFn(&AbstractRouter::PumpLL, this));
|
2019-08-07 16:33:29 +00:00
|
|
|
|
|
|
|
if(!link)
|
|
|
|
return false;
|
|
|
|
if(!link->EnsureKeys(transport_keyfile.string().c_str()))
|
|
|
|
{
|
|
|
|
LogError("failed to load ", transport_keyfile);
|
|
|
|
return false;
|
|
|
|
}
|
2018-05-21 12:43:32 +00:00
|
|
|
|
2019-08-07 16:33:29 +00:00
|
|
|
const auto afs = {AF_INET, AF_INET6};
|
2018-06-28 11:29:10 +00:00
|
|
|
|
2019-08-07 16:33:29 +00:00
|
|
|
for(const auto af : afs)
|
2018-12-10 16:26:46 +00:00
|
|
|
{
|
2019-08-07 16:33:29 +00:00
|
|
|
if(!link->Configure(netloop(), "*", af, m_OutboundPort))
|
2019-01-05 13:48:00 +00:00
|
|
|
continue;
|
2019-08-07 16:33:29 +00:00
|
|
|
_linkManager.AddLink(std::move(link), false);
|
|
|
|
return true;
|
2018-06-21 12:52:45 +00:00
|
|
|
}
|
2019-08-07 16:33:29 +00:00
|
|
|
return false;
|
2018-06-21 12:52:45 +00:00
|
|
|
}
|
2018-06-21 13:33:42 +00:00
|
|
|
|
2018-12-10 16:26:46 +00:00
|
|
|
bool
|
|
|
|
Router::CreateDefaultHiddenService()
|
|
|
|
{
|
|
|
|
// add endpoint
|
2019-02-22 16:21:05 +00:00
|
|
|
return hiddenServiceContext().AddDefaultEndpoint(netConfig);
|
2018-06-21 12:52:45 +00:00
|
|
|
}
|
2018-08-02 23:30:34 +00:00
|
|
|
|
2018-12-10 16:26:46 +00:00
|
|
|
bool
|
2019-07-02 21:28:28 +00:00
|
|
|
Router::LoadHiddenServiceConfig(string_view fname)
|
2018-07-09 17:32:11 +00:00
|
|
|
{
|
2019-02-11 19:45:42 +00:00
|
|
|
LogDebug("opening hidden service config ", fname);
|
|
|
|
service::Config conf;
|
2018-12-10 16:26:46 +00:00
|
|
|
if(!conf.Load(fname))
|
2018-07-09 17:32:11 +00:00
|
|
|
return false;
|
2018-12-10 16:26:46 +00:00
|
|
|
for(const auto &config : conf.services)
|
|
|
|
{
|
2019-02-11 19:45:42 +00:00
|
|
|
service::Config::section_t filteredConfig;
|
2018-12-10 16:26:46 +00:00
|
|
|
mergeHiddenServiceConfig(config.second, filteredConfig.second);
|
|
|
|
filteredConfig.first = config.first;
|
2019-02-22 16:21:05 +00:00
|
|
|
if(!hiddenServiceContext().AddEndpoint(filteredConfig))
|
2018-12-10 16:26:46 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
2018-07-09 17:32:11 +00:00
|
|
|
}
|
2019-06-26 21:39:29 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
Router::MessageSent(const RouterID &remote, SendStatus status)
|
|
|
|
{
|
|
|
|
if(status == SendStatus::Success)
|
|
|
|
{
|
2019-07-25 18:31:53 +00:00
|
|
|
LogDebug("Message successfully sent to ", remote);
|
2019-06-26 21:39:29 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-09-09 11:36:21 +00:00
|
|
|
LogDebug("Message failed sending to ", remote);
|
2019-06-26 21:39:29 +00:00
|
|
|
}
|
|
|
|
}
|
2018-02-01 13:21:00 +00:00
|
|
|
} // namespace llarp
|