policy now has a map of peers instead of a flat list, makes it more efficient to do lookups
This commit is contained in:
parent
13a0630875
commit
a101b4c1c9
|
@ -212,8 +212,8 @@ namespace libtorrent
|
||||||
|
|
||||||
int num_peers() const { return m_peers.size(); }
|
int num_peers() const { return m_peers.size(); }
|
||||||
|
|
||||||
typedef std::list<peer>::iterator iterator;
|
typedef std::multimap<address, peer>::iterator iterator;
|
||||||
typedef std::list<peer>::const_iterator const_iterator;
|
typedef std::multimap<address, peer>::const_iterator const_iterator;
|
||||||
iterator begin_peer() { return m_peers.begin(); }
|
iterator begin_peer() { return m_peers.begin(); }
|
||||||
iterator end_peer() { return m_peers.end(); }
|
iterator end_peer() { return m_peers.end(); }
|
||||||
|
|
||||||
|
@ -237,7 +237,7 @@ namespace libtorrent
|
||||||
iterator find_disconnect_candidate();
|
iterator find_disconnect_candidate();
|
||||||
iterator find_connect_candidate();
|
iterator find_connect_candidate();
|
||||||
|
|
||||||
std::list<peer> m_peers;
|
std::multimap<address, peer> m_peers;
|
||||||
|
|
||||||
torrent* m_torrent;
|
torrent* m_torrent;
|
||||||
|
|
||||||
|
|
|
@ -551,6 +551,7 @@ namespace libtorrent
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void on_files_released(int ret, disk_io_job const& j);
|
void on_files_released(int ret, disk_io_job const& j);
|
||||||
|
void on_torrent_paused(int ret, disk_io_job const& j);
|
||||||
void on_storage_moved(int ret, disk_io_job const& j);
|
void on_storage_moved(int ret, disk_io_job const& j);
|
||||||
|
|
||||||
void on_piece_verified(int ret, disk_io_job const& j
|
void on_piece_verified(int ret, disk_io_job const& j
|
||||||
|
|
|
@ -1580,13 +1580,13 @@ namespace libtorrent
|
||||||
: m_id(id), m_pc(pc)
|
: m_id(id), m_pc(pc)
|
||||||
{ assert(pc); }
|
{ assert(pc); }
|
||||||
|
|
||||||
bool operator()(policy::peer const& p) const
|
bool operator()(std::pair<const address, policy::peer> const& p) const
|
||||||
{
|
{
|
||||||
return p.connection != m_pc
|
return p.second.connection != m_pc
|
||||||
&& p.connection
|
&& p.second.connection
|
||||||
&& p.connection->pid() == m_id
|
&& p.second.connection->pid() == m_id
|
||||||
&& !p.connection->pid().is_all_zeros()
|
&& !p.second.connection->pid().is_all_zeros()
|
||||||
&& p.ip.address() == m_pc->remote().address();
|
&& p.second.ip.address() == m_pc->remote().address();
|
||||||
}
|
}
|
||||||
|
|
||||||
peer_id const& m_id;
|
peer_id const& m_id;
|
||||||
|
@ -2281,7 +2281,7 @@ namespace libtorrent
|
||||||
, match_peer_id(pid, this));
|
, match_peer_id(pid, this));
|
||||||
if (i != p.end_peer())
|
if (i != p.end_peer())
|
||||||
{
|
{
|
||||||
assert(i->connection->pid() == pid);
|
assert(i->second.connection->pid() == pid);
|
||||||
// we found another connection with the same peer-id
|
// we found another connection with the same peer-id
|
||||||
// which connection should be closed in order to be
|
// which connection should be closed in order to be
|
||||||
// sure that the other end closes the same connection?
|
// sure that the other end closes the same connection?
|
||||||
|
@ -2291,7 +2291,7 @@ namespace libtorrent
|
||||||
// if not, we should close the outgoing one.
|
// if not, we should close the outgoing one.
|
||||||
if (pid < m_ses.get_peer_id() && is_local())
|
if (pid < m_ses.get_peer_id() && is_local())
|
||||||
{
|
{
|
||||||
i->connection->disconnect();
|
i->second.connection->disconnect();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -138,26 +138,14 @@ namespace
|
||||||
return free_upload;
|
return free_upload;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct match_peer_address
|
|
||||||
{
|
|
||||||
match_peer_address(address const& addr)
|
|
||||||
: m_addr(addr)
|
|
||||||
{}
|
|
||||||
|
|
||||||
bool operator()(policy::peer const& p) const
|
|
||||||
{ return p.ip.address() == m_addr; }
|
|
||||||
|
|
||||||
address const& m_addr;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct match_peer_endpoint
|
struct match_peer_endpoint
|
||||||
{
|
{
|
||||||
match_peer_endpoint(tcp::endpoint const& ep)
|
match_peer_endpoint(tcp::endpoint const& ep)
|
||||||
: m_ep(ep)
|
: m_ep(ep)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool operator()(policy::peer const& p) const
|
bool operator()(std::pair<const address, policy::peer> const& p) const
|
||||||
{ return p.ip == m_ep; }
|
{ return p.second.ip == m_ep; }
|
||||||
|
|
||||||
tcp::endpoint const& m_ep;
|
tcp::endpoint const& m_ep;
|
||||||
};
|
};
|
||||||
|
@ -168,8 +156,8 @@ namespace
|
||||||
: m_id(id_)
|
: m_id(id_)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool operator()(policy::peer const& p) const
|
bool operator()(std::pair<const address, policy::peer> const& p) const
|
||||||
{ return p.connection && p.connection->pid() == m_id; }
|
{ return p.second.connection && p.second.connection->pid() == m_id; }
|
||||||
|
|
||||||
peer_id const& m_id;
|
peer_id const& m_id;
|
||||||
};
|
};
|
||||||
|
@ -180,11 +168,11 @@ namespace
|
||||||
: m_conn(c)
|
: m_conn(c)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool operator()(policy::peer const& p) const
|
bool operator()(std::pair<const address, policy::peer> const& p) const
|
||||||
{
|
{
|
||||||
return p.connection == &m_conn
|
return p.second.connection == &m_conn
|
||||||
|| (p.ip == m_conn.remote()
|
|| (p.second.ip == m_conn.remote()
|
||||||
&& p.type == policy::peer::connectable);
|
&& p.second.type == policy::peer::connectable);
|
||||||
}
|
}
|
||||||
|
|
||||||
peer_connection const& m_conn;
|
peer_connection const& m_conn;
|
||||||
|
@ -362,35 +350,35 @@ namespace libtorrent
|
||||||
piece_picker* p = 0;
|
piece_picker* p = 0;
|
||||||
if (m_torrent->has_picker())
|
if (m_torrent->has_picker())
|
||||||
p = &m_torrent->picker();
|
p = &m_torrent->picker();
|
||||||
for (std::list<peer>::iterator i = m_peers.begin()
|
for (iterator i = m_peers.begin()
|
||||||
, end(m_peers.end()); i != end;)
|
, end(m_peers.end()); i != end;)
|
||||||
{
|
{
|
||||||
if ((ses.m_ip_filter.access(i->ip.address()) & ip_filter::blocked) == 0)
|
if ((ses.m_ip_filter.access(i->second.ip.address()) & ip_filter::blocked) == 0)
|
||||||
{
|
{
|
||||||
++i;
|
++i;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i->connection)
|
if (i->second.connection)
|
||||||
{
|
{
|
||||||
i->connection->disconnect();
|
i->second.connection->disconnect();
|
||||||
if (ses.m_alerts.should_post(alert::info))
|
if (ses.m_alerts.should_post(alert::info))
|
||||||
{
|
{
|
||||||
ses.m_alerts.post_alert(peer_blocked_alert(i->ip.address()
|
ses.m_alerts.post_alert(peer_blocked_alert(i->second.ip.address()
|
||||||
, "disconnected blocked peer"));
|
, "disconnected blocked peer"));
|
||||||
}
|
}
|
||||||
assert(i->connection == 0
|
assert(i->second.connection == 0
|
||||||
|| i->connection->peer_info_struct() == 0);
|
|| i->second.connection->peer_info_struct() == 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (ses.m_alerts.should_post(alert::info))
|
if (ses.m_alerts.should_post(alert::info))
|
||||||
{
|
{
|
||||||
ses.m_alerts.post_alert(peer_blocked_alert(i->ip.address()
|
ses.m_alerts.post_alert(peer_blocked_alert(i->second.ip.address()
|
||||||
, "blocked peer removed from peer list"));
|
, "blocked peer removed from peer list"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (p) p->clear_peer(&(*i));
|
if (p) p->clear_peer(&i->second);
|
||||||
m_peers.erase(i++);
|
m_peers.erase(i++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -489,7 +477,7 @@ namespace libtorrent
|
||||||
for (iterator i = m_peers.begin();
|
for (iterator i = m_peers.begin();
|
||||||
i != m_peers.end(); ++i)
|
i != m_peers.end(); ++i)
|
||||||
{
|
{
|
||||||
peer_connection* c = i->connection;
|
peer_connection* c = i->second.connection;
|
||||||
if (c == 0) continue;
|
if (c == 0) continue;
|
||||||
if (c->is_disconnecting()) continue;
|
if (c->is_disconnecting()) continue;
|
||||||
|
|
||||||
|
@ -497,13 +485,13 @@ namespace libtorrent
|
||||||
// isn't interesting
|
// isn't interesting
|
||||||
if (disconnect_peer != m_peers.end()
|
if (disconnect_peer != m_peers.end()
|
||||||
&& c->is_interesting()
|
&& c->is_interesting()
|
||||||
&& !disconnect_peer->connection->is_interesting())
|
&& !disconnect_peer->second.connection->is_interesting())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
double transferred_amount
|
double transferred_amount
|
||||||
= (double)c->statistics().total_payload_download();
|
= (double)c->statistics().total_payload_download();
|
||||||
|
|
||||||
time_duration connected_time = now - i->connected;
|
time_duration connected_time = now - i->second.connected;
|
||||||
|
|
||||||
double connected_time_in_seconds = total_seconds(connected_time);
|
double connected_time_in_seconds = total_seconds(connected_time);
|
||||||
|
|
||||||
|
@ -513,7 +501,7 @@ namespace libtorrent
|
||||||
// prefer to disconnect uninteresting peers, and secondly slow peers
|
// prefer to disconnect uninteresting peers, and secondly slow peers
|
||||||
if (transfer_rate <= slowest_transfer_rate
|
if (transfer_rate <= slowest_transfer_rate
|
||||||
|| (disconnect_peer != m_peers.end()
|
|| (disconnect_peer != m_peers.end()
|
||||||
&& disconnect_peer->connection->is_interesting()
|
&& disconnect_peer->second.connection->is_interesting()
|
||||||
&& !c->is_interesting()))
|
&& !c->is_interesting()))
|
||||||
{
|
{
|
||||||
slowest_transfer_rate = transfer_rate;
|
slowest_transfer_rate = transfer_rate;
|
||||||
|
@ -540,21 +528,21 @@ namespace libtorrent
|
||||||
|
|
||||||
for (iterator i = m_peers.begin(); i != m_peers.end(); ++i)
|
for (iterator i = m_peers.begin(); i != m_peers.end(); ++i)
|
||||||
{
|
{
|
||||||
if (i->connection) continue;
|
if (i->second.connection) continue;
|
||||||
if (i->banned) continue;
|
if (i->second.banned) continue;
|
||||||
if (i->type == peer::not_connectable) continue;
|
if (i->second.type == peer::not_connectable) continue;
|
||||||
if (i->seed && finished) continue;
|
if (i->second.seed && finished) continue;
|
||||||
if (i->failcount >= max_failcount) continue;
|
if (i->second.failcount >= max_failcount) continue;
|
||||||
if (now - i->connected < seconds(i->failcount * min_reconnect_time))
|
if (now - i->second.connected < seconds(i->second.failcount * min_reconnect_time))
|
||||||
continue;
|
continue;
|
||||||
if (ses.m_port_filter.access(i->ip.port()) & port_filter::blocked)
|
if (ses.m_port_filter.access(i->second.ip.port()) & port_filter::blocked)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
assert(i->connected <= now);
|
assert(i->second.connected <= now);
|
||||||
|
|
||||||
if (i->connected <= min_connect_time)
|
if (i->second.connected <= min_connect_time)
|
||||||
{
|
{
|
||||||
min_connect_time = i->connected;
|
min_connect_time = i->second.connected;
|
||||||
candidate = i;
|
candidate = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -685,11 +673,11 @@ namespace libtorrent
|
||||||
for (iterator i = m_peers.begin(); i != m_peers.end();)
|
for (iterator i = m_peers.begin(); i != m_peers.end();)
|
||||||
{
|
{
|
||||||
// this timeout has to be customizable!
|
// this timeout has to be customizable!
|
||||||
if (i->connection == 0
|
if (i->second.connection == 0
|
||||||
&& i->connected != min_time()
|
&& i->second.connected != min_time()
|
||||||
&& now - i->connected > minutes(120))
|
&& now - i->second.connected > minutes(120))
|
||||||
{
|
{
|
||||||
if (p) p->clear_peer(&(*i));
|
if (p) p->clear_peer(&i->second);
|
||||||
m_peers.erase(i++);
|
m_peers.erase(i++);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -899,12 +887,12 @@ namespace libtorrent
|
||||||
for (const_iterator i = m_peers.begin();
|
for (const_iterator i = m_peers.begin();
|
||||||
i != m_peers.end(); ++i)
|
i != m_peers.end(); ++i)
|
||||||
{
|
{
|
||||||
if (!i->connection
|
if (!i->second.connection
|
||||||
|| i->connection->is_connecting()
|
|| i->second.connection->is_connecting()
|
||||||
|| i->connection->is_disconnecting()
|
|| i->second.connection->is_disconnecting()
|
||||||
|| !i->connection->is_peer_interested())
|
|| !i->second.connection->is_peer_interested())
|
||||||
continue;
|
continue;
|
||||||
if (i->connection->is_choked()) ++ret;
|
if (i->second.connection->is_choked()) ++ret;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -948,23 +936,20 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
i = std::find_if(
|
i = m_peers.find(c.remote().address());
|
||||||
m_peers.begin()
|
|
||||||
, m_peers.end()
|
|
||||||
, match_peer_address(c.remote().address()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i != m_peers.end())
|
if (i != m_peers.end())
|
||||||
{
|
{
|
||||||
if (i->banned)
|
if (i->second.banned)
|
||||||
throw protocol_error("ip address banned, closing");
|
throw protocol_error("ip address banned, closing");
|
||||||
|
|
||||||
if (i->connection != 0)
|
if (i->second.connection != 0)
|
||||||
{
|
{
|
||||||
assert(i->connection != &c);
|
assert(i->second.connection != &c);
|
||||||
// the new connection is a local (outgoing) connection
|
// the new connection is a local (outgoing) connection
|
||||||
// or the current one is already connected
|
// or the current one is already connected
|
||||||
if (!i->connection->is_connecting() || c.is_local())
|
if (!i->second.connection->is_connecting() || c.is_local())
|
||||||
{
|
{
|
||||||
throw protocol_error("duplicate connection, closing");
|
throw protocol_error("duplicate connection, closing");
|
||||||
}
|
}
|
||||||
|
@ -975,10 +960,7 @@ namespace libtorrent
|
||||||
" is connecting and this connection is incoming. closing existing "
|
" is connecting and this connection is incoming. closing existing "
|
||||||
"connection in favour of this one");
|
"connection in favour of this one");
|
||||||
#endif
|
#endif
|
||||||
i->connection->disconnect();
|
i->second.connection->disconnect();
|
||||||
#ifndef NDEBUG
|
|
||||||
check_invariant();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -989,23 +971,20 @@ namespace libtorrent
|
||||||
assert(c.remote() == c.get_socket()->remote_endpoint());
|
assert(c.remote() == c.get_socket()->remote_endpoint());
|
||||||
|
|
||||||
peer p(c.remote(), peer::not_connectable, 0);
|
peer p(c.remote(), peer::not_connectable, 0);
|
||||||
m_peers.push_back(p);
|
m_peers.insert(std::make_pair(c.remote().address(), p));
|
||||||
i = boost::prior(m_peers.end());
|
i = boost::prior(m_peers.end());
|
||||||
#ifndef NDEBUG
|
|
||||||
check_invariant();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(m_torrent->connection_for(c.remote()) == &c);
|
assert(m_torrent->connection_for(c.remote()) == &c);
|
||||||
|
|
||||||
c.set_peer_info(&*i);
|
c.set_peer_info(&i->second);
|
||||||
assert(i->connection == 0);
|
assert(i->second.connection == 0);
|
||||||
c.add_stat(i->prev_amount_download, i->prev_amount_upload);
|
c.add_stat(i->second.prev_amount_download, i->second.prev_amount_upload);
|
||||||
i->prev_amount_download = 0;
|
i->second.prev_amount_download = 0;
|
||||||
i->prev_amount_upload = 0;
|
i->second.prev_amount_upload = 0;
|
||||||
i->connection = &c;
|
i->second.connection = &c;
|
||||||
assert(i->connection);
|
assert(i->second.connection);
|
||||||
i->connected = time_now();
|
i->second.connected = time_now();
|
||||||
// m_last_optimistic_disconnect = time_now();
|
// m_last_optimistic_disconnect = time_now();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1038,23 +1017,15 @@ namespace libtorrent
|
||||||
|
|
||||||
if (m_torrent->settings().allow_multiple_connections_per_ip)
|
if (m_torrent->settings().allow_multiple_connections_per_ip)
|
||||||
{
|
{
|
||||||
i = std::find_if(
|
std::pair<iterator, iterator> range = m_peers.equal_range(remote.address());
|
||||||
m_peers.begin()
|
i = std::find_if(range.first, range.second, match_peer_endpoint(remote));
|
||||||
, m_peers.end()
|
|
||||||
, match_peer_endpoint(remote));
|
|
||||||
|
|
||||||
if (i == m_peers.end())
|
if (i == range.second)
|
||||||
i = std::find_if(
|
i = std::find_if(m_peers.begin(), m_peers.end(), match_peer_id(pid));
|
||||||
m_peers.begin()
|
|
||||||
, m_peers.end()
|
|
||||||
, match_peer_id(pid));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
i = std::find_if(
|
i = m_peers.find(remote.address());
|
||||||
m_peers.begin()
|
|
||||||
, m_peers.end()
|
|
||||||
, match_peer_address(remote.address()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == m_peers.end())
|
if (i == m_peers.end())
|
||||||
|
@ -1073,14 +1044,14 @@ namespace libtorrent
|
||||||
// we don't have any info about this peer.
|
// we don't have any info about this peer.
|
||||||
// add a new entry
|
// add a new entry
|
||||||
peer p(remote, peer::connectable, src);
|
peer p(remote, peer::connectable, src);
|
||||||
m_peers.push_back(p);
|
m_peers.insert(std::make_pair(remote.address(), p));
|
||||||
// the iterator is invalid
|
// the iterator is invalid
|
||||||
// because of the push_back()
|
// because of the push_back()
|
||||||
i = boost::prior(m_peers.end());
|
i = boost::prior(m_peers.end());
|
||||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||||
if (flags & 0x01) p.pe_support = true;
|
if (flags & 0x01) p.pe_support = true;
|
||||||
#endif
|
#endif
|
||||||
if (flags & 0x02) i->seed = true;
|
if (flags & 0x02) i->second.seed = true;
|
||||||
|
|
||||||
// try to send a DHT ping to this peer
|
// try to send a DHT ping to this peer
|
||||||
// as well, to figure out if it supports
|
// as well, to figure out if it supports
|
||||||
|
@ -1093,27 +1064,27 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
i->type = peer::connectable;
|
i->second.type = peer::connectable;
|
||||||
|
|
||||||
// in case we got the ip from a remote connection, port is
|
// in case we got the ip from a remote connection, port is
|
||||||
// not known, so save it. Client may also have changed port
|
// not known, so save it. Client may also have changed port
|
||||||
// for some reason.
|
// for some reason.
|
||||||
i->ip = remote;
|
i->second.ip = remote;
|
||||||
i->source |= src;
|
i->second.source |= src;
|
||||||
|
|
||||||
// if this peer has failed before, decrease the
|
// if this peer has failed before, decrease the
|
||||||
// counter to allow it another try, since somebody
|
// counter to allow it another try, since somebody
|
||||||
// else is appearantly able to connect to it
|
// else is appearantly able to connect to it
|
||||||
// if it comes from the DHT it might be stale though
|
// if it comes from the DHT it might be stale though
|
||||||
if (i->failcount > 0 && src != peer_info::dht)
|
if (i->second.failcount > 0 && src != peer_info::dht)
|
||||||
--i->failcount;
|
--i->second.failcount;
|
||||||
|
|
||||||
// if we're connected to this peer
|
// if we're connected to this peer
|
||||||
// we already know if it's a seed or not
|
// we already know if it's a seed or not
|
||||||
// so we don't have to trust this source
|
// so we don't have to trust this source
|
||||||
if ((flags & 0x02) && !i->connection) i->seed = true;
|
if ((flags & 0x02) && !i->second.connection) i->second.seed = true;
|
||||||
|
|
||||||
if (i->connection)
|
if (i->second.connection)
|
||||||
{
|
{
|
||||||
// this means we're already connected
|
// this means we're already connected
|
||||||
// to this peer. don't connect to
|
// to this peer. don't connect to
|
||||||
|
@ -1122,10 +1093,10 @@ namespace libtorrent
|
||||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||||
m_torrent->debug_log("already connected to peer: " + remote.address().to_string() + ":"
|
m_torrent->debug_log("already connected to peer: " + remote.address().to_string() + ":"
|
||||||
+ boost::lexical_cast<std::string>(remote.port()) + " "
|
+ boost::lexical_cast<std::string>(remote.port()) + " "
|
||||||
+ boost::lexical_cast<std::string>(i->connection->pid()));
|
+ boost::lexical_cast<std::string>(i->second.connection->pid()));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
assert(i->connection->associated_torrent().lock().get() == m_torrent);
|
assert(i->second.connection->associated_torrent().lock().get() == m_torrent);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1159,12 +1130,12 @@ namespace libtorrent
|
||||||
for (iterator i = m_peers.begin();
|
for (iterator i = m_peers.begin();
|
||||||
i != m_peers.end(); ++i)
|
i != m_peers.end(); ++i)
|
||||||
{
|
{
|
||||||
if (i->connection == 0) continue;
|
if (i->second.connection == 0) continue;
|
||||||
// if we're not interested, we will not become interested
|
// if we're not interested, we will not become interested
|
||||||
if (!i->connection->is_interesting()) continue;
|
if (!i->second.connection->is_interesting()) continue;
|
||||||
if (!i->connection->has_piece(index)) continue;
|
if (!i->second.connection->has_piece(index)) continue;
|
||||||
|
|
||||||
i->connection->update_interest();
|
i->second.connection->update_interest();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1187,8 +1158,8 @@ namespace libtorrent
|
||||||
// INVARIANT_CHECK;
|
// INVARIANT_CHECK;
|
||||||
|
|
||||||
assert(std::find_if(m_peers.begin(), m_peers.end()
|
assert(std::find_if(m_peers.begin(), m_peers.end()
|
||||||
, boost::bind<bool>(std::equal_to<peer_connection*>(), bind(&peer::connection, _1)
|
, boost::bind<bool>(std::equal_to<peer_connection*>(), bind(&peer::connection
|
||||||
, &c)) != m_peers.end());
|
, bind(&iterator::value_type::second, _1)), &c)) != m_peers.end());
|
||||||
|
|
||||||
// if the peer is choked and we have upload slots left,
|
// if the peer is choked and we have upload slots left,
|
||||||
// then unchoke it. Another condition that has to be met
|
// then unchoke it. Another condition that has to be met
|
||||||
|
@ -1303,23 +1274,23 @@ namespace libtorrent
|
||||||
iterator p = find_connect_candidate();
|
iterator p = find_connect_candidate();
|
||||||
if (p == m_peers.end()) return false;
|
if (p == m_peers.end()) return false;
|
||||||
|
|
||||||
assert(!p->banned);
|
assert(!p->second.banned);
|
||||||
assert(!p->connection);
|
assert(!p->second.connection);
|
||||||
assert(p->type == peer::connectable);
|
assert(p->second.type == peer::connectable);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
p->connected = time_now();
|
p->second.connected = time_now();
|
||||||
p->connection = m_torrent->connect_to_peer(&*p);
|
p->second.connection = m_torrent->connect_to_peer(&p->second);
|
||||||
assert(p->connection == m_torrent->connection_for(p->ip));
|
assert(p->second.connection == m_torrent->connection_for(p->second.ip));
|
||||||
if (p->connection == 0)
|
if (p->second.connection == 0)
|
||||||
{
|
{
|
||||||
++p->failcount;
|
++p->second.failcount;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
p->connection->add_stat(p->prev_amount_download, p->prev_amount_upload);
|
p->second.connection->add_stat(p->second.prev_amount_download, p->second.prev_amount_upload);
|
||||||
p->prev_amount_download = 0;
|
p->second.prev_amount_download = 0;
|
||||||
p->prev_amount_upload = 0;
|
p->second.prev_amount_upload = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
|
@ -1329,7 +1300,7 @@ namespace libtorrent
|
||||||
<< e.what() << "'\n";
|
<< e.what() << "'\n";
|
||||||
#endif
|
#endif
|
||||||
std::cerr << e.what() << std::endl;
|
std::cerr << e.what() << std::endl;
|
||||||
++p->failcount;
|
++p->second.failcount;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1340,10 +1311,10 @@ namespace libtorrent
|
||||||
if (p == m_peers.end())
|
if (p == m_peers.end())
|
||||||
return false;
|
return false;
|
||||||
#if defined(TORRENT_VERBOSE_LOGGING)
|
#if defined(TORRENT_VERBOSE_LOGGING)
|
||||||
(*p->connection->m_logger) << "*** CLOSING CONNECTION 'too many connections'\n";
|
(*p->second.connection->m_logger) << "*** CLOSING CONNECTION 'too many connections'\n";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
p->connection->disconnect();
|
p->second.connection->disconnect();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1425,21 +1396,23 @@ namespace libtorrent
|
||||||
int total_connections = 0;
|
int total_connections = 0;
|
||||||
int nonempty_connections = 0;
|
int nonempty_connections = 0;
|
||||||
|
|
||||||
std::set<address> unique_test;
|
std::set<tcp::endpoint> unique_test;
|
||||||
// std::set<tcp::endpoint> unique_test2;
|
|
||||||
for (const_iterator i = m_peers.begin();
|
for (const_iterator i = m_peers.begin();
|
||||||
i != m_peers.end(); ++i)
|
i != m_peers.end(); ++i)
|
||||||
{
|
{
|
||||||
peer const& p = *i;
|
peer const& p = i->second;
|
||||||
// if (!m_torrent->settings().allow_multiple_connections_per_ip)
|
if (!m_torrent->settings().allow_multiple_connections_per_ip)
|
||||||
// assert(unique_test.find(p.ip.address()) == unique_test.end());
|
{
|
||||||
// assert(unique_test2.find(p.ip) == unique_test2.end());
|
assert(m_peers.count(p.ip.address()) == 1);
|
||||||
// unique_test.insert(p.ip.address());
|
}
|
||||||
// unique_test2.insert(p.ip);
|
else
|
||||||
|
{
|
||||||
|
assert(unique_test.count(p.ip) == 0);
|
||||||
|
unique_test.insert(p.ip);
|
||||||
|
}
|
||||||
++total_connections;
|
++total_connections;
|
||||||
if (!p.connection)
|
if (!p.connection)
|
||||||
{
|
{
|
||||||
// assert(m_torrent->connection_for(p.ip) == 0);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!m_torrent->settings().allow_multiple_connections_per_ip)
|
if (!m_torrent->settings().allow_multiple_connections_per_ip)
|
||||||
|
@ -1493,10 +1466,8 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
policy::peer* p = static_cast<policy::peer*>(*i);
|
policy::peer* p = static_cast<policy::peer*>(*i);
|
||||||
if (p == 0) continue;
|
if (p == 0) continue;
|
||||||
std::list<peer>::const_iterator k = m_peers.begin();
|
assert(std::find_if(m_peers.begin(), m_peers.end()
|
||||||
for (; k != m_peers.end(); ++k)
|
, match_peer_connection(*p->connection)) != m_peers.end());
|
||||||
if (&(*k) == p) break;
|
|
||||||
assert(k != m_peers.end());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1024,11 +1024,26 @@ namespace libtorrent
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
disconnect_all();
|
disconnect_all();
|
||||||
if (m_owning_storage.get()) m_storage->async_release_files();
|
if (m_owning_storage.get())
|
||||||
|
m_storage->async_release_files(
|
||||||
|
bind(&torrent::on_files_released, shared_from_this(), _1, _2));
|
||||||
|
|
||||||
m_owning_storage = 0;
|
m_owning_storage = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void torrent::on_files_released(int ret, disk_io_job const& j)
|
void torrent::on_files_released(int ret, disk_io_job const& j)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
|
||||||
|
|
||||||
|
if (alerts().should_post(alert::warning))
|
||||||
|
{
|
||||||
|
alerts().post_alert(torrent_paused_alert(get_handle(), "torrent paused"));
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void torrent::on_torrent_paused(int ret, disk_io_job const& j)
|
||||||
{
|
{
|
||||||
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
|
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
|
||||||
|
|
||||||
|
@ -2117,7 +2132,9 @@ namespace libtorrent
|
||||||
, bind(&peer_connection::disconnect, _1));
|
, bind(&peer_connection::disconnect, _1));
|
||||||
|
|
||||||
assert(m_storage);
|
assert(m_storage);
|
||||||
m_storage->async_release_files();
|
// we need to keep the object alive during this operation
|
||||||
|
m_storage->async_release_files(
|
||||||
|
bind(&torrent::on_files_released, shared_from_this(), _1, _2));
|
||||||
}
|
}
|
||||||
|
|
||||||
// called when torrent is complete (all pieces downloaded)
|
// called when torrent is complete (all pieces downloaded)
|
||||||
|
@ -2549,10 +2566,8 @@ namespace libtorrent
|
||||||
if (m_owning_storage.get())
|
if (m_owning_storage.get())
|
||||||
{
|
{
|
||||||
assert(m_storage);
|
assert(m_storage);
|
||||||
// TOOD: add a callback which posts
|
|
||||||
// an alert for the client to sync. with
|
|
||||||
m_storage->async_release_files(
|
m_storage->async_release_files(
|
||||||
bind(&torrent::on_files_released, shared_from_this(), _1, _2));
|
bind(&torrent::on_torrent_paused, shared_from_this(), _1, _2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -752,10 +752,10 @@ namespace libtorrent
|
||||||
// so, if the peer is not connectable (i.e. we
|
// so, if the peer is not connectable (i.e. we
|
||||||
// don't know its listen port) or if it has
|
// don't know its listen port) or if it has
|
||||||
// been banned, don't save it.
|
// been banned, don't save it.
|
||||||
if (i->type == policy::peer::not_connectable
|
if (i->second.type == policy::peer::not_connectable
|
||||||
|| i->banned) continue;
|
|| i->second.banned) continue;
|
||||||
|
|
||||||
tcp::endpoint ip = i->ip;
|
tcp::endpoint ip = i->second.ip;
|
||||||
entry peer(entry::dictionary_t);
|
entry peer(entry::dictionary_t);
|
||||||
peer["ip"] = ip.address().to_string();
|
peer["ip"] = ip.address().to_string();
|
||||||
peer["port"] = ip.port();
|
peer["port"] = ip.port();
|
||||||
|
|
Loading…
Reference in New Issue