@@ -274,7 +275,8 @@ class session: public boost::noncopyable
entry dht_state() const;
void add_dht_node(std::pair<std::string
, int> const& node);
-
+ void add_dht_router(std::pair<std::string
+ , int> const& node);
};
Once it's created, the session object will spawn the main thread that will do all the work.
@@ -547,7 +549,6 @@ void start_dht(entry const& startup_state);
void stop_dht();
void set_dht_settings(dht_settings const& settings);
entry dht_state() const;
-void add_dht_node(std::pair<std::string, int> const& node);
These functions are not available in case TORRENT_DISABLE_DHT is
@@ -595,6 +596,25 @@ that are ready to replace a failing node, it will be replaced immediately,
this limit is only used to clear out nodes that don't have any node that can
replace them.
+
+
+
+
+void add_dht_node(std::pair<std::string, int> const& node);
+void add_dht_router(std::pair<std::string, int> const& node);
+
+
+
add_dht_node takes a host name and port pair. That endpoint will be
+pinged, and if a valid DHT reply is received, the node will be added to
+the routing table.
+
add_dht_router adds the given endpoint to a list of DHT router nodes.
+If a search is ever made while the routing table is empty, those nodes will
+be used as backups. Nodes in the router node list will also never be added
+to the regular routing table, which effectively means they are only used
+for bootstrapping, to keep the load off them.
+
An example routing node that you could typically add is
+router.bittorrent.com.
+
@@ -2458,7 +2478,7 @@ struct peer_error_alert: alert
This is a debug alert that is generated by an incoming invalid piece request. The handle
-is a handle to the torrent the peer is a member of. ìp is the address of the peer and the
+is a handle to the torrent the peer is a member of. Ïp is the address of the peer and the
request is the actual incoming request from the peer. The alert is generated as severity level
debug.
@@ -3051,7 +3071,7 @@ boost::filesystem::path::default_name_check(boost::filesystem::native);
Big thanks to Michael Wojciechowski and Peter Koeleman for making the autotools
scripts.
Thanks to Reimond Retz for bugfixes, suggestions and testing
-Thanks to University of Umeå for providing development and test hardware.
+Thanks to University of Ume for providing development and test hardware.
Project is hosted by sourceforge.
diff --git a/docs/manual.rst b/docs/manual.rst
index 971053a31..0347d0cdb 100755
--- a/docs/manual.rst
+++ b/docs/manual.rst
@@ -120,7 +120,8 @@ The ``session`` class has the following synopsis::
entry dht_state() const;
void add_dht_node(std::pair
const& node);
-
+ void add_dht_router(std::pair const& node);
};
Once it's created, the session object will spawn the main thread that will do all the work.
@@ -420,7 +421,6 @@ start_dht() stop_dht() set_dht_settings() dht_state()
void stop_dht();
void set_dht_settings(dht_settings const& settings);
entry dht_state() const;
- void add_dht_node(std::pair const& node);
These functions are not available in case ``TORRENT_DISABLE_DHT`` is
defined. ``start_dht`` starts the dht node and makes the trackerless service
@@ -474,6 +474,26 @@ that are ready to replace a failing node, it will be replaced immediately,
this limit is only used to clear out nodes that don't have any node that can
replace them.
+add_dht_node() add_dht_router()
+-------------------------------
+
+ ::
+
+ void add_dht_node(std::pair const& node);
+ void add_dht_router(std::pair const& node);
+
+``add_dht_node`` takes a host name and port pair. That endpoint will be
+pinged, and if a valid DHT reply is received, the node will be added to
+the routing table.
+
+``add_dht_router`` adds the given endpoint to a list of DHT router nodes.
+If a search is ever made while the routing table is empty, those nodes will
+be used as backups. Nodes in the router node list will also never be added
+to the regular routing table, which effectively means they are only used
+for bootstrapping, to keep the load off them.
+
+An example routing node that you could typically add is
+``router.bittorrent.com``.
entry
diff --git a/examples/client_test.cpp b/examples/client_test.cpp
index e5ab6543f..7ea5e7b35 100755
--- a/examples/client_test.cpp
+++ b/examples/client_test.cpp
@@ -575,14 +575,15 @@ int main(int ac, char* av[])
entry dht_state = bdecode(
std::istream_iterator(dht_state_file)
, std::istream_iterator());
- ses.start_dht(dht_state);
- }
- catch (std::exception&)
- {
- ses.start_dht();
- ses.add_dht_node(std::make_pair(std::string("router.bittorrent.com")
- , 6881));
}
+ catch (std::exception&) {}
+ ses.start_dht();
+ ses.add_dht_router(std::make_pair(std::string("router.bittorrent.com")
+ , 6881));
+ ses.add_dht_router(std::make_pair(std::string("router.utorrent.com")
+ , 6881));
+ ses.add_dht_router(std::make_pair(std::string("router.bitcomet.com")
+ , 6881));
#endif
ses.set_max_half_open_connections(half_open_limit);
diff --git a/include/libtorrent/kademlia/dht_tracker.hpp b/include/libtorrent/kademlia/dht_tracker.hpp
index 2c35a5105..d447d4b23 100644
--- a/include/libtorrent/kademlia/dht_tracker.hpp
+++ b/include/libtorrent/kademlia/dht_tracker.hpp
@@ -67,7 +67,8 @@ namespace libtorrent { namespace dht
void add_node(udp::endpoint node);
void add_node(std::pair const& node);
-
+ void add_router_node(std::pair const& node);
+
void rebind(asio::ip::address listen_interface, int listen_port);
entry state() const;
@@ -82,6 +83,8 @@ namespace libtorrent { namespace dht
void on_name_lookup(asio::error const& e
, udp::resolver::iterator host);
+ void on_router_name_lookup(asio::error const& e
+ , udp::resolver::iterator host);
void connection_timeout(asio::error const& e);
void refresh_timeout(asio::error const& e);
void tick(asio::error const& e);
diff --git a/include/libtorrent/kademlia/node.hpp b/include/libtorrent/kademlia/node.hpp
index e5660c03d..c44a21f33 100644
--- a/include/libtorrent/kademlia/node.hpp
+++ b/include/libtorrent/kademlia/node.hpp
@@ -99,6 +99,7 @@ public:
, boost::function0 f);
void find_node(node_id const& id, boost::function<
void(std::vector const&)> f);
+ void add_router_node(udp::endpoint router);
void incoming(msg const& m);
diff --git a/include/libtorrent/kademlia/routing_table.hpp b/include/libtorrent/kademlia/routing_table.hpp
index 96449bda1..1b4abbf37 100644
--- a/include/libtorrent/kademlia/routing_table.hpp
+++ b/include/libtorrent/kademlia/routing_table.hpp
@@ -156,6 +156,15 @@ public:
, dht_settings const& settings);
void node_failed(node_id const& id);
+
+ // adds an endpoint that will never be added to
+ // the routing table
+ void add_router_node(udp::endpoint router);
+
+ // iterates over the router nodes added
+ typedef std::set::const_iterator router_iterator;
+ router_iterator router_begin() const { return m_router_nodes.begin(); }
+ router_iterator router_end() const { return m_router_nodes.end(); }
// this function is called every time the node sees
// a sign of a node being alive. This node will either
@@ -220,6 +229,12 @@ private:
table_activity_t m_bucket_activity;
node_id m_id; // our own node id
+ // this is a set of all the endpoints that have
+ // been identified as router nodes. They will
+ // be used in searches, but they will never
+ // be added to the routing table.
+ std::set m_router_nodes;
+
// this is the lowest bucket index with nodes in it
int m_lowest_active_bucket;
};
diff --git a/include/libtorrent/kademlia/traversal_algorithm.hpp b/include/libtorrent/kademlia/traversal_algorithm.hpp
index ce6176f56..a99a9c6ea 100644
--- a/include/libtorrent/kademlia/traversal_algorithm.hpp
+++ b/include/libtorrent/kademlia/traversal_algorithm.hpp
@@ -141,6 +141,17 @@ traversal_algorithm::traversal_algorithm(
{
add_entry(i->id, i->addr, result::initial);
}
+
+ // in case the routing table is empty, use the
+ // router nodes in the table
+ if (start == end)
+ {
+ for (routing_table::router_iterator i = table.router_begin()
+ , end(table.router_end()); i != end; ++i)
+ {
+ add_entry(node_id(0), *i, result::initial);
+ }
+ }
}
diff --git a/include/libtorrent/peer_connection.hpp b/include/libtorrent/peer_connection.hpp
index 77fed37ff..9201551d3 100755
--- a/include/libtorrent/peer_connection.hpp
+++ b/include/libtorrent/peer_connection.hpp
@@ -413,7 +413,7 @@ namespace libtorrent
boost::shared_ptr m_socket;
tcp::endpoint m_remote;
-
+
// this is the torrent this connection is
// associated with. If the connection is an
// incoming conncetion, this is set to zero
diff --git a/include/libtorrent/session.hpp b/include/libtorrent/session.hpp
index 27a0da2f8..5f13f6d21 100755
--- a/include/libtorrent/session.hpp
+++ b/include/libtorrent/session.hpp
@@ -382,6 +382,7 @@ namespace libtorrent
void set_dht_settings(dht_settings const& settings);
entry dht_state() const;
void add_dht_node(std::pair const& node);
+ void add_dht_router(std::pair const& node);
#endif
void enable_extension(extension_index i);
diff --git a/src/kademlia/dht_tracker.cpp b/src/kademlia/dht_tracker.cpp
index 57d2f6212..131d1cdfc 100644
--- a/src/kademlia/dht_tracker.cpp
+++ b/src/kademlia/dht_tracker.cpp
@@ -649,9 +649,9 @@ namespace libtorrent { namespace dht
m_host_resolver.async_resolve(q, bind(&dht_tracker::on_name_lookup
, this, _1, _2));
}
-
- void dht_tracker::on_name_lookup(asio::error const& e, udp::resolver::iterator host)
- try
+
+ void dht_tracker::on_name_lookup(asio::error const& e
+ , udp::resolver::iterator host) try
{
if (e || host == udp::resolver::iterator()) return;
add_node(host->endpoint());
@@ -661,6 +661,24 @@ namespace libtorrent { namespace dht
assert(false);
};
+ void dht_tracker::add_router_node(std::pair const& node)
+ {
+ udp::resolver::query q(node.first, lexical_cast(node.second));
+ m_host_resolver.async_resolve(q, bind(&dht_tracker::on_router_name_lookup
+ , this, _1, _2));
+ }
+
+ void dht_tracker::on_router_name_lookup(asio::error const& e
+ , udp::resolver::iterator host) try
+ {
+ if (e || host == udp::resolver::iterator()) return;
+ m_dht.add_router_node(host->endpoint());
+ }
+ catch (std::exception&)
+ {
+ assert(false);
+ };
+
void dht_tracker::on_bootstrap()
{}
diff --git a/src/kademlia/node.cpp b/src/kademlia/node.cpp
index 46e5708ec..8a9d17818 100644
--- a/src/kademlia/node.cpp
+++ b/src/kademlia/node.cpp
@@ -347,6 +347,11 @@ namespace
};
}
+void node_impl::add_router_node(udp::endpoint router)
+{
+ m_table.add_router_node(router);
+}
+
void node_impl::add_node(udp::endpoint node)
{
// ping the node, and if we get a reply, it
diff --git a/src/kademlia/routing_table.cpp b/src/kademlia/routing_table.cpp
index 2d85849d3..66900cc42 100644
--- a/src/kademlia/routing_table.cpp
+++ b/src/kademlia/routing_table.cpp
@@ -221,6 +221,11 @@ void routing_table::node_failed(node_id const& id)
rb.erase(rb.end() - 1);
}
+void routing_table::add_router_node(udp::endpoint router)
+{
+ m_router_nodes.insert(router);
+}
+
// this function is called every time the node sees
// a sign of a node being alive. This node will either
// be inserted in the k-buckets or be moved to the top
@@ -230,6 +235,7 @@ void routing_table::node_failed(node_id const& id)
// on its own id)
bool routing_table::node_seen(node_id const& id, udp::endpoint addr)
{
+ if (m_router_nodes.find(addr) != m_router_nodes.end()) return false;
int bucket_index = distance_exp(m_id, id);
assert(bucket_index < (int)m_buckets.size());
assert(bucket_index >= 0);
@@ -266,7 +272,10 @@ bool routing_table::node_seen(node_id const& id, udp::endpoint addr)
if ((int)b.size() < m_bucket_size)
{
b.push_back(node_entry(id, addr));
- if (bucket_index < m_lowest_active_bucket)
+ // if bucket index is 0, the node is ourselves
+ // don't updated m_lowest_active_bucket
+ if (bucket_index < m_lowest_active_bucket
+ && bucket_index > 0)
m_lowest_active_bucket = bucket_index;
// TORRENT_LOG(table) << "inserting node: " << id << " " << addr;
return ret;
diff --git a/src/session.cpp b/src/session.cpp
index 942947959..56e2218f7 100755
--- a/src/session.cpp
+++ b/src/session.cpp
@@ -672,8 +672,7 @@ namespace libtorrent { namespace detail
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
(*m_logger) << endp << " <== INCOMING CONNECTION\n";
#endif
- if (endp.address().is_v4()
- && (m_ip_filter.access(endp.address().to_v4()) & ip_filter::blocked))
+ if (m_ip_filter.access(endp.address().to_v4()) & ip_filter::blocked)
{
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
(*m_logger) << "filtered blocked ip\n";
@@ -1175,9 +1174,7 @@ namespace libtorrent
= m_impl.m_connections.begin(); i != m_impl.m_connections.end();)
{
tcp::endpoint sender = i->first->remote_endpoint();
- if (sender.address().is_v4()
- && (m_impl.m_ip_filter.access(sender.address().to_v4())
- & ip_filter::blocked))
+ if (m_impl.m_ip_filter.access(sender.address()) & ip_filter::blocked)
{
#if defined(TORRENT_VERBOSE_LOGGING)
(*i->second->m_logger) << "*** CONNECTION FILTERED'\n";
@@ -1541,6 +1538,12 @@ namespace libtorrent
m_impl.m_dht->add_node(node);
}
+ void session::add_dht_router(std::pair const& node)
+ {
+ assert(m_impl.m_dht);
+ m_impl.m_dht->add_router_node(node);
+ }
+
#endif
bool session::is_listening() const