support web seeds that resolve to multiple IPs

This commit is contained in:
Arvid Norberg 2014-09-28 02:20:13 +00:00
parent 9a985d197f
commit 154cbeb5cf
6 changed files with 53 additions and 17 deletions

View File

@ -1,3 +1,4 @@
* support web seeds that resolve to multiple IPs
* added auto-sequential feature. download well-seeded torrents in-order
* removed built-in GeoIP support (this functionality is orthogonal to libtorrent)
* deprecate proxy settings in favor of regular settings

View File

@ -261,8 +261,8 @@ namespace libtorrent
ptime retry;
// if the hostname of the web seed has been resolved,
// this is its IP address
tcp::endpoint endpoint;
// these are its IP addresses
std::vector<tcp::endpoint> endpoints;
// this is the peer_info field used for the
// connection, just to count hash failures

View File

@ -81,8 +81,20 @@ namespace libtorrent
#endif
}
void http_seed_connection::disconnect(error_code const& ec, peer_connection_interface::operation_t op, int error)
void http_seed_connection::disconnect(error_code const& ec
, peer_connection_interface::operation_t op, int error)
{
if (is_disconnecting()) return;
if (op == peer_connection_interface::op_connect
&& m_web
&& !m_web->endpoints.empty())
{
// we failed to connect to this IP. remove it so that the next attempt
// uses the next IP in the list.
m_web->endpoints.erase(m_web->endpoints.begin());
}
boost::shared_ptr<torrent> t = associated_torrent().lock();
peer_connection::disconnect(ec, op, error);
if (t) t->disconnect_web_seed(this);

View File

@ -3117,6 +3117,9 @@ namespace libtorrent
m_need_save_resume_data = true;
}
// TODO: 3 change the tracker_response interface to take a type capturing
// the response. Have multiple peer lists. IPv4, IPv6 and hostnames. That
// way we don't need to render addresses into strings
void torrent::tracker_response(
tracker_request const& r
, address const& tracker_ip // this is the IP we connected to
@ -3464,6 +3467,7 @@ namespace libtorrent
if (e || host_list.empty() || m_ses.is_aborted()) return;
// TODO: add one peer per IP the hostname resolves to
tcp::endpoint host(host_list.front(), port);
if (m_apply_ip_filter
@ -5851,7 +5855,6 @@ namespace libtorrent
peer->set_peer_info(0);
}
if (has_picker()) picker().clear_peer(&web->peer_info);
m_web_seeds.erase(web);
update_want_tick();
@ -5965,9 +5968,9 @@ namespace libtorrent
return;
}
if (web->endpoint.port() != 0)
if (!web->endpoints.empty())
{
connect_web_seed(web, web->endpoint);
connect_web_seed(web, web->endpoints.front());
return;
}
@ -6131,16 +6134,22 @@ namespace libtorrent
return;
}
tcp::endpoint a(host->endpoint());
while (host != tcp::resolver::iterator())
{
// fill in the peer struct's address field
web->endpoints.push_back(host->endpoint());
// fill in the peer struct's address field
web->endpoint = a;
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING
debug_log(" -> %s", print_endpoint(host->endpoint()).c_str());
#endif
++host;
}
if (int(m_connections.size()) >= m_max_connections
|| m_ses.num_connections() >= m_ses.settings().get_int(settings_pack::connections_limit))
return;
connect_web_seed(web, a);
connect_web_seed(web, web->endpoints.front());
}
void torrent::connect_web_seed(std::list<web_seed_entry>::iterator web, tcp::endpoint a)
@ -6162,7 +6171,6 @@ namespace libtorrent
TORRENT_ASSERT(web->resolving == false);
TORRENT_ASSERT(web->peer_info.connection == 0);
web->endpoint = a;
if (a.address().is_v4())
{
web->peer_info.addr = a.address().to_v4();
@ -6245,7 +6253,7 @@ namespace libtorrent
pack.ios = &m_ses.get_io_service();
pack.tor = shared_from_this();
pack.s = s;
pack.endp = &web->endpoint;
pack.endp = &web->endpoints.front();
pack.peerinfo = &web->peer_info;
if (web->type == web_seed_entry::url_seed)
{
@ -6299,7 +6307,8 @@ namespace libtorrent
web->peer_info.prev_amount_download = 0;
web->peer_info.prev_amount_upload = 0;
#if defined TORRENT_VERBOSE_LOGGING
debug_log("web seed connection started: %s", web->url.c_str());
debug_log("web seed connection started: [%s] %s"
, print_endpoint(a).c_str(), web->url.c_str());
#endif
c->start();
@ -10521,8 +10530,11 @@ namespace libtorrent
void torrent::disconnect_web_seed(peer_connection* p)
{
std::list<web_seed_entry>::iterator i = std::find_if(m_web_seeds.begin(), m_web_seeds.end()
, (boost::bind(&torrent_peer::connection, boost::bind(&web_seed_entry::peer_info, _1)) == p));
std::list<web_seed_entry>::iterator i
= std::find_if(m_web_seeds.begin(), m_web_seeds.end()
, (boost::bind(&torrent_peer::connection
, boost::bind(&web_seed_entry::peer_info, _1)) == p));
// this happens if the web server responded with a redirect
// or with something incorrect, so that we removed the web seed
// immediately, before we disconnected

View File

@ -63,7 +63,8 @@ namespace libtorrent
, m_body_start(0)
{
TORRENT_ASSERT(&web.peer_info == pack.peerinfo);
TORRENT_ASSERT(web.endpoint == *pack.endp);
TORRENT_ASSERT(!web.endpoints.empty());
TORRENT_ASSERT(web.endpoints.front() == *pack.endp);
INVARIANT_CHECK;

View File

@ -114,10 +114,20 @@ void web_peer_connection::on_connected()
web_connection_base::on_connected();
}
void web_peer_connection::disconnect(error_code const& ec, peer_connection_interface::operation_t op, int error)
void web_peer_connection::disconnect(error_code const& ec
, peer_connection_interface::operation_t op, int error)
{
if (is_disconnecting()) return;
if (op == peer_connection_interface::op_connect
&& m_web
&& !m_web->endpoints.empty())
{
// we failed to connect to this IP. remove it so that the next attempt
// uses the next IP in the list.
m_web->endpoints.erase(m_web->endpoints.begin());
}
boost::shared_ptr<torrent> t = associated_torrent().lock();
if (!m_requests.empty() && !m_file_requests.empty()