support web seeds that resolve to multiple IPs
This commit is contained in:
parent
9a985d197f
commit
154cbeb5cf
|
@ -1,3 +1,4 @@
|
||||||
|
* support web seeds that resolve to multiple IPs
|
||||||
* added auto-sequential feature. download well-seeded torrents in-order
|
* added auto-sequential feature. download well-seeded torrents in-order
|
||||||
* removed built-in GeoIP support (this functionality is orthogonal to libtorrent)
|
* removed built-in GeoIP support (this functionality is orthogonal to libtorrent)
|
||||||
* deprecate proxy settings in favor of regular settings
|
* deprecate proxy settings in favor of regular settings
|
||||||
|
|
|
@ -261,8 +261,8 @@ namespace libtorrent
|
||||||
ptime retry;
|
ptime retry;
|
||||||
|
|
||||||
// if the hostname of the web seed has been resolved,
|
// if the hostname of the web seed has been resolved,
|
||||||
// this is its IP address
|
// these are its IP addresses
|
||||||
tcp::endpoint endpoint;
|
std::vector<tcp::endpoint> endpoints;
|
||||||
|
|
||||||
// this is the peer_info field used for the
|
// this is the peer_info field used for the
|
||||||
// connection, just to count hash failures
|
// connection, just to count hash failures
|
||||||
|
|
|
@ -81,8 +81,20 @@ namespace libtorrent
|
||||||
#endif
|
#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();
|
boost::shared_ptr<torrent> t = associated_torrent().lock();
|
||||||
peer_connection::disconnect(ec, op, error);
|
peer_connection::disconnect(ec, op, error);
|
||||||
if (t) t->disconnect_web_seed(this);
|
if (t) t->disconnect_web_seed(this);
|
||||||
|
|
|
@ -3117,6 +3117,9 @@ namespace libtorrent
|
||||||
m_need_save_resume_data = true;
|
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(
|
void torrent::tracker_response(
|
||||||
tracker_request const& r
|
tracker_request const& r
|
||||||
, address const& tracker_ip // this is the IP we connected to
|
, 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;
|
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);
|
tcp::endpoint host(host_list.front(), port);
|
||||||
|
|
||||||
if (m_apply_ip_filter
|
if (m_apply_ip_filter
|
||||||
|
@ -5851,7 +5855,6 @@ namespace libtorrent
|
||||||
peer->set_peer_info(0);
|
peer->set_peer_info(0);
|
||||||
}
|
}
|
||||||
if (has_picker()) picker().clear_peer(&web->peer_info);
|
if (has_picker()) picker().clear_peer(&web->peer_info);
|
||||||
|
|
||||||
|
|
||||||
m_web_seeds.erase(web);
|
m_web_seeds.erase(web);
|
||||||
update_want_tick();
|
update_want_tick();
|
||||||
|
@ -5965,9 +5968,9 @@ namespace libtorrent
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (web->endpoint.port() != 0)
|
if (!web->endpoints.empty())
|
||||||
{
|
{
|
||||||
connect_web_seed(web, web->endpoint);
|
connect_web_seed(web, web->endpoints.front());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6131,16 +6134,22 @@ namespace libtorrent
|
||||||
return;
|
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
|
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING
|
||||||
web->endpoint = a;
|
debug_log(" -> %s", print_endpoint(host->endpoint()).c_str());
|
||||||
|
#endif
|
||||||
|
++host;
|
||||||
|
}
|
||||||
|
|
||||||
if (int(m_connections.size()) >= m_max_connections
|
if (int(m_connections.size()) >= m_max_connections
|
||||||
|| m_ses.num_connections() >= m_ses.settings().get_int(settings_pack::connections_limit))
|
|| m_ses.num_connections() >= m_ses.settings().get_int(settings_pack::connections_limit))
|
||||||
return;
|
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)
|
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->resolving == false);
|
||||||
TORRENT_ASSERT(web->peer_info.connection == 0);
|
TORRENT_ASSERT(web->peer_info.connection == 0);
|
||||||
|
|
||||||
web->endpoint = a;
|
|
||||||
if (a.address().is_v4())
|
if (a.address().is_v4())
|
||||||
{
|
{
|
||||||
web->peer_info.addr = a.address().to_v4();
|
web->peer_info.addr = a.address().to_v4();
|
||||||
|
@ -6245,7 +6253,7 @@ namespace libtorrent
|
||||||
pack.ios = &m_ses.get_io_service();
|
pack.ios = &m_ses.get_io_service();
|
||||||
pack.tor = shared_from_this();
|
pack.tor = shared_from_this();
|
||||||
pack.s = s;
|
pack.s = s;
|
||||||
pack.endp = &web->endpoint;
|
pack.endp = &web->endpoints.front();
|
||||||
pack.peerinfo = &web->peer_info;
|
pack.peerinfo = &web->peer_info;
|
||||||
if (web->type == web_seed_entry::url_seed)
|
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_download = 0;
|
||||||
web->peer_info.prev_amount_upload = 0;
|
web->peer_info.prev_amount_upload = 0;
|
||||||
#if defined TORRENT_VERBOSE_LOGGING
|
#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
|
#endif
|
||||||
|
|
||||||
c->start();
|
c->start();
|
||||||
|
@ -10521,8 +10530,11 @@ namespace libtorrent
|
||||||
|
|
||||||
void torrent::disconnect_web_seed(peer_connection* p)
|
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()
|
std::list<web_seed_entry>::iterator i
|
||||||
, (boost::bind(&torrent_peer::connection, boost::bind(&web_seed_entry::peer_info, _1)) == p));
|
= 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
|
// this happens if the web server responded with a redirect
|
||||||
// or with something incorrect, so that we removed the web seed
|
// or with something incorrect, so that we removed the web seed
|
||||||
// immediately, before we disconnected
|
// immediately, before we disconnected
|
||||||
|
|
|
@ -63,7 +63,8 @@ namespace libtorrent
|
||||||
, m_body_start(0)
|
, m_body_start(0)
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(&web.peer_info == pack.peerinfo);
|
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;
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
|
|
|
@ -114,10 +114,20 @@ void web_peer_connection::on_connected()
|
||||||
web_connection_base::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 (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();
|
boost::shared_ptr<torrent> t = associated_torrent().lock();
|
||||||
|
|
||||||
if (!m_requests.empty() && !m_file_requests.empty()
|
if (!m_requests.empty() && !m_file_requests.empty()
|
||||||
|
|
Loading…
Reference in New Issue