diff --git a/libtorrent/include/libtorrent/session_status.hpp b/libtorrent/include/libtorrent/session_status.hpp index 74bb0efe..e1417763 100644 --- a/libtorrent/include/libtorrent/session_status.hpp +++ b/libtorrent/include/libtorrent/session_status.hpp @@ -35,6 +35,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/config.hpp" #include "libtorrent/size_type.hpp" +#include "libtorrent/union_endpoint.hpp" #include namespace libtorrent @@ -66,6 +67,7 @@ namespace libtorrent int num_replacements; // number of seconds since last activity int last_active; + union_endpoint random_node; }; struct utp_status diff --git a/libtorrent/src/kademlia/routing_table.cpp b/libtorrent/src/kademlia/routing_table.cpp index f9bc312a..5aaaf358 100644 --- a/libtorrent/src/kademlia/routing_table.cpp +++ b/libtorrent/src/kademlia/routing_table.cpp @@ -91,6 +91,10 @@ void routing_table::status(session_status& s) const b.num_nodes = i->live_nodes.size(); b.num_replacements = i->replacements.size(); b.last_active = total_seconds(now - i->last_active); + if( b.num_nodes ) { + int randNode = rand() % b.num_nodes; + b.random_node = i->live_nodes[randNode].endpoint; + } s.dht_routing_table.push_back(b); } } diff --git a/src/twister.cpp b/src/twister.cpp index 2a520b62..d63e1762 100644 --- a/src/twister.cpp +++ b/src/twister.cpp @@ -182,11 +182,6 @@ void ThreadWaitExtIP() MilliSleep(500); } - // delay libtorrent initialization until we have valid blocks - while( getBestHeight() <= 0 ) { - MilliSleep(500); - } - error_code ec; int listen_port = GetListenPort() + LIBTORRENT_PORT_OFFSET; std::string bind_to_interface = ""; @@ -199,6 +194,9 @@ void ThreadWaitExtIP() , ipStr.size() ? ipStr.c_str() : NULL , std::make_pair(listen_port, listen_port)); + // session will be paused until we have an up-to-date blockchain + ses->pause(); + std::vector in; boost::filesystem::path sesStatePath = GetDataDir() / "ses_state"; if (load_file(sesStatePath.string(), in) == 0) @@ -275,6 +273,12 @@ void ThreadWaitExtIP() } } +bool isBlockChainUptodate() { + if( !pindexBest ) + return false; + return (pindexBest->GetBlockTime() > GetTime() - 1 * 60 * 60); +} + void ThreadMaintainDHTNodes() { RenameThread("maintain-dht-nodes"); @@ -284,16 +288,16 @@ void ThreadMaintainDHTNodes() } while(1) { - MilliSleep(5000); - session_status ss = ses->status(); int dht_nodes = ss.dht_nodes; bool nodesAdded = false; + int vNodesSize = 0; if( ses ) { LOCK(cs_vNodes); + vNodesSize = vNodes.size(); vector vAddr = addrman.GetAddr(); - int totalNodesCandidates = (int)(vNodes.size() + vAddr.size()); + int totalNodesCandidates = (int)(vNodesSize + vAddr.size()); if( (!dht_nodes && totalNodesCandidates) || (dht_nodes < 5 && totalNodesCandidates > 10) ) { printf("ThreadMaintainDHTNodes: too few dht_nodes, trying to add some...\n"); @@ -321,8 +325,21 @@ void ThreadMaintainDHTNodes() } } } + + if( ses->is_paused() ) { + if( vNodesSize && isBlockChainUptodate() ) { + printf("BlockChain is now up-to-date: unpausing libtorrent session\n"); + ses->resume(); + } + } else { + if( !vNodesSize || !isBlockChainUptodate() ) { + printf("Outdated BlockChain detected: pausing libtorrent session\n"); + ses->pause(); + } + } + if( nodesAdded ) { - MilliSleep(5000); + MilliSleep(2000); ss = ses->status(); if( ss.dht_nodes > dht_nodes ) { // new nodes were added to dht: force updating peers from dht so torrents may start faster @@ -330,12 +347,27 @@ void ThreadMaintainDHTNodes() BOOST_FOREACH(const PAIRTYPE(std::string, torrent_handle)& item, m_userTorrent) { item.second.force_dht_announce(); } - } else { - // nodes added but dht ignored them, so they are probably duplicated. - // we sleep a bit as a punishment :-) - MilliSleep(30000); } } + + if( !vNodesSize && dht_nodes ) { + printf("ThreadMaintainDHTNodes: registration network is down, trying to add nodes from DHT...\n"); + for( size_t i = 0; i < ss.dht_routing_table.size(); i++ ) { + dht_routing_bucket &bucket = ss.dht_routing_table[i]; + if( bucket.num_nodes ) { + printf("DHT bucket [%zd] random node = %s:%d\n", i, + bucket.random_node.address().to_string().c_str(), + bucket.random_node.port); + char nodeStr[64]; + sprintf(nodeStr,"%s:%d", bucket.random_node.address().to_string().c_str(), + bucket.random_node.port - LIBTORRENT_PORT_OFFSET); + CAddress addr; + ConnectNode(addr, nodeStr); + } + } + } + + MilliSleep(5000); } }