Skip to content

Commit

Permalink
Merge pull request #512 from rakshasa/fix-dht
Browse files Browse the repository at this point in the history
Fix dht
  • Loading branch information
rakshasa committed Oct 22, 2016
2 parents c3f6db0 + 2aa130e commit 16e1961
Showing 1 changed file with 47 additions and 35 deletions.
82 changes: 47 additions & 35 deletions src/core/dht_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@
#include "download_store.h"
#include "manager.h"

#define LT_LOG_THIS(log_fmt, ...) \
lt_log_print_subsystem(torrent::LOG_DHT_MANAGER, "dht_manager", log_fmt, __VA_ARGS__);

namespace core {

const char* DhtManager::dht_settings[dht_settings_num] = { "disable", "off", "auto", "on" };
Expand All @@ -65,69 +68,77 @@ DhtManager::~DhtManager() {

void
DhtManager::load_dht_cache() {
if (m_start == dht_disable || !control->core()->download_store()->is_enabled())
if (m_start == dht_disable || !control->core()->download_store()->is_enabled()) {
LT_LOG_THIS("ignoring cache file", 0);
return;
}

std::string cache_filename = control->core()->download_store()->path() + "rtorrent.dht_cache";
std::fstream cache_stream(cache_filename.c_str(), std::ios::in | std::ios::binary);

torrent::Object cache = torrent::Object::create_map();
std::fstream cache_file((control->core()->download_store()->path() + "rtorrent.dht_cache").c_str(), std::ios::in | std::ios::binary);

if (cache_file.is_open()) {
cache_file >> cache;
if (cache_stream.is_open()) {
cache_stream >> cache;

// If the cache file is corrupted we will just discard it with an
// error message.
if (cache_file.fail()) {
lt_log_print(torrent::LOG_DHT_WARN, "DHT cache file corrupted, discarding.");
if (cache_stream.fail()) {
LT_LOG_THIS("cache file corrupted, discarding (path:%s)", cache_filename.c_str());
cache = torrent::Object::create_map();
} else {
LT_LOG_THIS("cache file read (path:%s)", cache_filename.c_str());
}
}

try {
torrent::dht_manager()->initialize(cache);
} else {
LT_LOG_THIS("could not open cache file (path:%s)", cache_filename.c_str());
}

if (m_start == dht_on)
start_dht();
torrent::dht_manager()->initialize(cache);

} catch (torrent::local_error& e) {
lt_log_print(torrent::LOG_DHT_WARN, "DHT failed: %s", e.what());
}
if (m_start == dht_on)
start_dht();
}

void
DhtManager::start_dht() {
priority_queue_erase(&taskScheduler, &m_stopTimeout);

if (!torrent::dht_manager()->is_valid() || torrent::dht_manager()->is_active())
if (!torrent::dht_manager()->is_valid()) {
LT_LOG_THIS("server start skipped, manager is uninitialized", 0);
return;
}

if (torrent::dht_manager()->is_active()) {
LT_LOG_THIS("server start skipped, already active", 0);
return;
}

torrent::ThrottlePair throttles = control->core()->get_throttle(m_throttleName);
torrent::dht_manager()->set_upload_throttle(throttles.first);
torrent::dht_manager()->set_download_throttle(throttles.second);

int port = rpc::call_command_value("dht.port");

if (port <= 0)
return;

lt_log_print(torrent::LOG_DHT_INFO, "Starting DHT server on port %d.", port);

try {
torrent::dht_manager()->start(port);
torrent::dht_manager()->reset_statistics();
if (!torrent::dht_manager()->start(port)) {
m_start = dht_off;
return;
}

m_updateTimeout.slot() = std::bind(&DhtManager::update, this);
priority_queue_insert(&taskScheduler, &m_updateTimeout, (cachedTime + rak::timer::from_seconds(60)).round_seconds());
torrent::dht_manager()->reset_statistics();

m_dhtPrevCycle = 0;
m_dhtPrevQueriesSent = 0;
m_dhtPrevRepliesReceived = 0;
m_dhtPrevQueriesReceived = 0;
m_dhtPrevBytesUp = 0;
m_dhtPrevBytesDown = 0;
m_updateTimeout.slot() = std::bind(&DhtManager::update, this);
priority_queue_insert(&taskScheduler, &m_updateTimeout, (cachedTime + rak::timer::from_seconds(60)).round_seconds());

} catch (torrent::local_error& e) {
lt_log_print(torrent::LOG_DHT_ERROR, "DHT start failed: %s", e.what());
m_start = dht_off;
}
m_dhtPrevCycle = 0;
m_dhtPrevQueriesSent = 0;
m_dhtPrevRepliesReceived = 0;
m_dhtPrevQueriesReceived = 0;
m_dhtPrevBytesUp = 0;
m_dhtPrevBytesDown = 0;
}

void
Expand All @@ -136,8 +147,9 @@ DhtManager::stop_dht() {
priority_queue_erase(&taskScheduler, &m_stopTimeout);

if (torrent::dht_manager()->is_active()) {
LT_LOG_THIS("stopping server", 0);

log_statistics(true);
lt_log_print(torrent::LOG_DHT_INFO, "Stopping DHT server.");
torrent::dht_manager()->stop();
}
}
Expand Down Expand Up @@ -219,15 +231,15 @@ DhtManager::log_statistics(bool force) {
// We should have had clients ping us at least but have received
// nothing, that means the UDP port is probably unreachable.
if (torrent::dht_manager()->can_receive_queries())
lt_log_print(torrent::LOG_DHT_WARN, "DHT port appears to be unreachable, no queries received.");
LT_LOG_THIS("listening port appears to be unreachable, no queries received", 0);

torrent::dht_manager()->set_can_receive(false);
}

if (stats.queries_sent - m_dhtPrevQueriesSent > stats.num_nodes * 2 + 20 && stats.replies_received == m_dhtPrevRepliesReceived) {
// No replies to over 20 queries plus two per node we have. Probably firewalled.
if (!m_warned)
lt_log_print(torrent::LOG_DHT_WARN, "DHT port appears to be firewalled, no replies received.");
LT_LOG_THIS("listening port appears to be firewalled, no replies received", 0);

m_warned = true;
return false;
Expand Down

0 comments on commit 16e1961

Please sign in to comment.