Commit 93d666d3 authored by Ivan Vilata-i-Balaguer's avatar Ivan Vilata-i-Balaguer
Browse files

Merge branch 'connectivity-logging' into master.

This adds some client logging enhancements to more easily debug BEP5
connectivity issues.
parents 7c664ce1 b37db1d4
......@@ -374,13 +374,22 @@ void Bep5Client::start(asio::yield_context)
if (!_helpers_swarm_name.empty()) {
bt::NodeID infohash = util::sha1_digest(_helpers_swarm_name);
LOG_INFO("Helpers swarm: sha1('", _helpers_swarm_name, "'): ", infohash.to_hex());
LOG_INFO("Helper swarm (bridges): sha1('", _helpers_swarm_name, "'): ", infohash.to_hex());
_helpers_swarm.reset(new Swarm(this, infohash, _dht, _cancel, true));
_helpers_swarm->start();
_injector_pinger.reset(new InjectorPinger(_injector_swarm, _helpers_swarm_name, _dht, _cancel));
}
if (logger.get_threshold() > DEBUG)
return;
TRACK_SPAWN(get_executor(),
[=] (asio::yield_context yield) {
sys::error_code ec;
status_loop(yield[ec]);
});
}
void Bep5Client::stop()
......@@ -391,6 +400,36 @@ void Bep5Client::stop()
_injector_pinger = nullptr;
}
void Bep5Client::status_loop(asio::yield_context yield)
{
assert(!_cancel);
Cancel cancel(_cancel);
sys::error_code ec;
assert(_injector_swarm);
{
_injector_swarm->wait_for_ready(cancel, yield[ec]);
return_or_throw_on_error(yield, cancel, ec);
}
if (_helpers_swarm) {
_helpers_swarm->wait_for_ready(cancel, yield[ec]);
return_or_throw_on_error(yield, cancel, ec);
}
while (!cancel) {
auto inj_n = _injector_swarm->peers().size();
auto hlp_n = _helpers_swarm ? _helpers_swarm->peers().size() : 0;
logger.debug(util::str(
"Bep5Client: swarm status:",
" injectors=", inj_n, " bridges=", hlp_n));
ec = {};
async_sleep(get_executor(), 1min, cancel, yield[ec]);
}
}
std::vector<Bep5Client::Candidate> Bep5Client::get_peers(Target target)
{
std::vector<Candidate> inj;
......@@ -401,12 +440,12 @@ std::vector<Bep5Client::Candidate> Bep5Client::get_peers(Target target)
if (target & Target::injectors) {
inj.reserve(inj_m.size());
for (auto p : inj_m) inj.push_back({p.first, p.second});
for (auto p : inj_m) inj.push_back({p.first, p.second, Target::injectors});
}
if (hlp_m && (target & Target::helpers)) {
hlp.reserve(hlp_m->size());
for (auto p : *hlp_m) hlp.push_back({p.first, p.second});
for (auto p : *hlp_m) hlp.push_back({p.first, p.second, Target::helpers});
}
std::shuffle(inj.begin(), inj.end(), _random_generator);
......@@ -472,6 +511,7 @@ GenericStream Bep5Client::connect( asio::yield_context yield
Cancel spawn_cancel(cancel); // Cancels all spawned coroutines
Target ret_target = Target::none;
asio::ip::udp::endpoint ret_ep;
GenericStream ret_con;
......@@ -488,6 +528,7 @@ GenericStream Bep5Client::connect( asio::yield_context yield
TRACK_SPAWN(exec, ([
=,
&spawn_cancel,
&ret_target,
&ret_con,
&ret_ep,
lock = wc.lock()
......@@ -502,6 +543,7 @@ GenericStream Bep5Client::connect( asio::yield_context yield
auto con = connect_single(*peer.client, tls, spawn_cancel, y[ec]);
assert(!spawn_cancel || ec == asio::error::operation_aborted);
if (spawn_cancel || ec) return;
ret_target = peer.target;
ret_con = move(con);
ret_ep = peer.endpoint;
spawn_cancel();
......@@ -523,11 +565,20 @@ GenericStream Bep5Client::connect( asio::yield_context yield
if (ec) {
_last_working_ep = boost::none;
LOG_DEBUG( "Bep5Client: Did not connect to any peer;"
, " peers:", i
, " ec:", ec.message());
} else {
_last_working_ep = ret_ep;
if (_injector_pinger) {
_injector_pinger->injector_was_seen_now();
}
if (ret_target == Target::injectors)
LOG_DEBUG("Bep5Client: Connected to injector peer directly; rep:", ret_ep);
else if (ret_target == Target::helpers)
LOG_DEBUG("Bep5Client: Connected to injector via helper peer (bridge); rep:", ret_ep);
else
assert(0 && "Invalid peer type");
}
return or_throw(yield, ec, move(ret_con));
......
......@@ -18,6 +18,14 @@ namespace ouiservice {
class Bep5Client : public OuiServiceImplementationClient
{
public:
enum Target : uint8_t { none = 0, helpers = 1, injectors = 2 };
friend Target operator|(Target t1, Target t2) {
return static_cast<Target>( static_cast<uint8_t>(t1)
| static_cast<uint8_t>(t2));
}
private:
using AbstractClient = OuiServiceImplementationClient;
struct Swarm;
......@@ -26,16 +34,9 @@ private:
struct Candidate {
asio::ip::udp::endpoint endpoint;
std::shared_ptr<AbstractClient> client;
Target target;
};
public:
enum Target : uint8_t { helpers = 1, injectors = 2 };
friend Target operator|(Target t1, Target t2) {
return static_cast<Target>( static_cast<uint8_t>(t1)
| static_cast<uint8_t>(t2));
}
public:
Bep5Client( std::shared_ptr<bittorrent::MainlineDht>
, std::string injector_swarm_name
......@@ -59,6 +60,7 @@ public:
asio::executor get_executor();
private:
void status_loop(asio::yield_context);
std::vector<Candidate> get_peers(Target);
GenericStream connect_single(AbstractClient&, bool tls, Cancel&, asio::yield_context);
......
......@@ -51,7 +51,8 @@ void UtpOuiServiceServer::start_listen(asio::yield_context yield)
if (cancel) return;
if (ec) {
assert(ec != asio::error::operation_aborted);
LOG_ERROR("UtpOuiServiceServer: failed to accept, will retry in 5s");
LOG_ERROR("UtpOuiServiceServer: failed to accept, will retry in 5s"
, " lep:", local_ep, " ec:", ec.message());
async_sleep(_ex, 5s, cancel, yield[ec]);
continue;
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment