diff --git a/docs/manual.rst b/docs/manual.rst index c036fe671..bfde0aa66 100755 --- a/docs/manual.rst +++ b/docs/manual.rst @@ -1471,7 +1471,8 @@ use_interface() ``use_interface()`` sets the network interface this torrent will use when it opens outgoing connections. By default, it uses the same interface as the session_ uses to listen on. The -parameter can be a string containing an ip-address or a hostname. +parameter must be a string containing an ip-address (either an IPv4 or IPv6 address). If +the string does not conform to this format and exception is thrown. info_hash() diff --git a/include/libtorrent/torrent.hpp b/include/libtorrent/torrent.hpp index 36e7db4d6..405e5d590 100755 --- a/include/libtorrent/torrent.hpp +++ b/include/libtorrent/torrent.hpp @@ -363,9 +363,14 @@ namespace libtorrent // the download. It will post an event, disconnect // all seeds and let the tracker know we're finished. void completed(); - + // this is the asio callback that is called when a name - // lookup for a web seed is completed. + // lookup for a PEER is completed. + void on_peer_name_lookup(asio::error_code const& e, tcp::resolver::iterator i + , peer_id pid); + + // this is the asio callback that is called when a name + // lookup for a WEB SEED is completed. void on_name_lookup(asio::error_code const& e, tcp::resolver::iterator i , std::string url, tcp::endpoint proxy); diff --git a/src/torrent.cpp b/src/torrent.cpp index 47afcfa60..ef93a880d 100755 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -592,17 +592,29 @@ namespace libtorrent if (i->pid == m_ses.get_peer_id()) continue; - tcp::endpoint a(address::from_string(i->ip), i->port); - - if (m_ses.m_ip_filter.access(a.address()) & ip_filter::blocked) + try { + tcp::endpoint a(address::from_string(i->ip), i->port); + + if (m_ses.m_ip_filter.access(a.address()) & ip_filter::blocked) + { #if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) - debug_log("blocked ip from tracker: " + i->ip); + debug_log("blocked ip from tracker: " + i->ip); #endif - continue; - } + continue; + } - m_policy->peer_from_tracker(a, i->pid); + m_policy->peer_from_tracker(a, i->pid); + } + catch (std::exception&) + { + // assume this is because we got a hostname instead of + // an ip address from the tracker + + tcp::resolver::query q(i->ip, boost::lexical_cast(i->port)); + m_host_resolver.async_resolve(q, m_ses.m_strand.wrap( + bind(&torrent::on_peer_name_lookup, shared_from_this(), _1, _2, i->pid))); + } } if (m_ses.m_alerts.should_post(alert::info)) @@ -616,6 +628,29 @@ namespace libtorrent m_got_tracker_response = true; } + void torrent::on_peer_name_lookup(asio::error_code const& e, tcp::resolver::iterator host + , peer_id pid) try + { + session_impl::mutex_t::scoped_lock l(m_ses.m_mutex); + + INVARIANT_CHECK; + + if (e || host == tcp::resolver::iterator() || + m_ses.is_aborted()) return; + + if (m_ses.m_ip_filter.access(host->endpoint().address()) & ip_filter::blocked) + { +#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) + debug_log("blocked ip from tracker: " + host->endpoint().address().to_string()); +#endif + return; + } + + m_policy->peer_from_tracker(*host, pid); + } + catch (std::exception&) + {} + size_type torrent::bytes_left() const { // if we don't have the metadata yet, we