fix leak of torrent_peer objecs (entries in peer_list)

This commit is contained in:
arvidn 2017-10-06 15:03:47 +02:00 committed by Arvid Norberg
parent 4e1c5738a2
commit cdd9f91999
7 changed files with 78 additions and 64 deletions

View File

@ -1,6 +1,7 @@
1.1.5 release 1.1.5 release
* fix leak of torrent_peer objecs (entries in peer_list)
* fix leak of peer_class objects (when setting per-torrent rate limits) * fix leak of peer_class objects (when setting per-torrent rate limits)
* expose peer_class API to python binding * expose peer_class API to python binding
* fix integer overflow in whole_pieces_threshold logic * fix integer overflow in whole_pieces_threshold logic

View File

@ -207,8 +207,8 @@ namespace libtorrent
void open_listen_port(); void open_listen_port();
torrent_peer_allocator_interface* get_peer_allocator() TORRENT_OVERRIDE torrent_peer_allocator_interface& get_peer_allocator() TORRENT_OVERRIDE
{ return &m_peer_allocator; } { return m_peer_allocator; }
io_service& get_io_service() TORRENT_OVERRIDE { return m_io_service; } io_service& get_io_service() TORRENT_OVERRIDE { return m_io_service; }
resolver_interface& get_resolver() TORRENT_OVERRIDE { return m_host_resolver; } resolver_interface& get_resolver() TORRENT_OVERRIDE { return m_host_resolver; }

View File

@ -152,7 +152,7 @@ namespace libtorrent { namespace aux
virtual alert_manager& alerts() = 0; virtual alert_manager& alerts() = 0;
virtual torrent_peer_allocator_interface* get_peer_allocator() = 0; virtual torrent_peer_allocator_interface& get_peer_allocator() = 0;
virtual io_service& get_io_service() = 0; virtual io_service& get_io_service() = 0;
virtual resolver_interface& get_resolver() = 0; virtual resolver_interface& get_resolver() = 0;

View File

@ -70,7 +70,6 @@ namespace libtorrent
, loop_counter(0) , loop_counter(0)
, ip(NULL), port(0) , ip(NULL), port(0)
, max_failcount(3) , max_failcount(3)
, peer_allocator(NULL)
{} {}
bool is_paused; bool is_paused;
bool is_finished; bool is_finished;
@ -97,9 +96,6 @@ namespace libtorrent
// a connect candidate // a connect candidate
int max_failcount; int max_failcount;
// this must be set to a torrent_peer allocator
torrent_peer_allocator_interface* peer_allocator;
// if any peer were removed during this call, they are returned in // if any peer were removed during this call, they are returned in
// this vector. The caller would want to make sure there are no // this vector. The caller would want to make sure there are no
// references to these torrent_peers anywhere // references to these torrent_peers anywhere
@ -110,7 +106,8 @@ namespace libtorrent
{ {
public: public:
peer_list(); peer_list(torrent_peer_allocator_interface& alloc);
~peer_list();
#if TORRENT_USE_I2P #if TORRENT_USE_I2P
torrent_peer* add_i2p_peer(char const* destination, int src, char flags torrent_peer* add_i2p_peer(char const* destination, int src, char flags
@ -211,6 +208,10 @@ namespace libtorrent
private: private:
// not copyable
peer_list(peer_list const&);
peer_list& operator=(peer_list const&);
void recalculate_connect_candidates(torrent_state* state); void recalculate_connect_candidates(torrent_state* state);
void update_connect_candidates(int delta); void update_connect_candidates(int delta);
@ -244,6 +245,10 @@ namespace libtorrent
// if so, don't delete it. // if so, don't delete it.
torrent_peer* m_locked_peer; torrent_peer* m_locked_peer;
// the peer allocator, as stored from the constructor
// this must be available in the destructor to free all peers
torrent_peer_allocator_interface& m_peer_allocator;
// the number of seeds in the torrent_peer list // the number of seeds in the torrent_peer list
boost::uint32_t m_num_seeds:31; boost::uint32_t m_num_seeds:31;

View File

@ -121,8 +121,9 @@ namespace
namespace libtorrent namespace libtorrent
{ {
peer_list::peer_list() peer_list::peer_list(torrent_peer_allocator_interface& alloc)
: m_locked_peer(NULL) : m_locked_peer(NULL)
, m_peer_allocator(alloc)
, m_num_seeds(0) , m_num_seeds(0)
, m_finished(0) , m_finished(0)
, m_round_robin(0) , m_round_robin(0)
@ -132,6 +133,15 @@ namespace libtorrent
thread_started(); thread_started();
} }
peer_list::~peer_list()
{
for (peers_t::iterator i = m_peers.begin()
, end(m_peers.end()); i != end; ++i)
{
m_peer_allocator.free_peer_entry(*i);
}
}
void peer_list::set_max_failcount(torrent_state* state) void peer_list::set_max_failcount(torrent_state* state)
{ {
if (state->max_failcount == m_max_failcount) return; if (state->max_failcount == m_max_failcount) return;
@ -301,7 +311,7 @@ namespace libtorrent
(*i)->in_use = false; (*i)->in_use = false;
#endif #endif
state->peer_allocator->free_peer_entry(*i); m_peer_allocator.free_peer_entry(*i);
m_peers.erase(i); m_peers.erase(i);
} }
@ -745,7 +755,7 @@ namespace libtorrent
#else #else
bool is_v6 = false; bool is_v6 = false;
#endif #endif
torrent_peer* p = state->peer_allocator->allocate_peer_entry( torrent_peer* p = m_peer_allocator.allocate_peer_entry(
is_v6 ? torrent_peer_allocator_interface::ipv6_peer_type is_v6 ? torrent_peer_allocator_interface::ipv6_peer_type
: torrent_peer_allocator_interface::ipv4_peer_type); : torrent_peer_allocator_interface::ipv4_peer_type);
if (p == 0) return false; if (p == 0) return false;
@ -1030,7 +1040,7 @@ 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
p = state->peer_allocator->allocate_peer_entry(torrent_peer_allocator_interface::i2p_peer_type); p = m_peer_allocator.allocate_peer_entry(torrent_peer_allocator_interface::i2p_peer_type);
if (p == NULL) return NULL; if (p == NULL) return NULL;
new (p) i2p_peer(destination, true, src); new (p) i2p_peer(destination, true, src);
@ -1044,7 +1054,7 @@ namespace libtorrent
p->in_use = false; p->in_use = false;
#endif #endif
state->peer_allocator->free_peer_entry(p); m_peer_allocator.free_peer_entry(p);
return 0; return 0;
} }
} }
@ -1106,7 +1116,7 @@ namespace libtorrent
#else #else
bool is_v6 = false; bool is_v6 = false;
#endif #endif
p = state->peer_allocator->allocate_peer_entry( p = m_peer_allocator.allocate_peer_entry(
is_v6 ? torrent_peer_allocator_interface::ipv6_peer_type is_v6 ? torrent_peer_allocator_interface::ipv6_peer_type
: torrent_peer_allocator_interface::ipv4_peer_type); : torrent_peer_allocator_interface::ipv4_peer_type);
if (p == NULL) return NULL; if (p == NULL) return NULL;
@ -1127,7 +1137,8 @@ namespace libtorrent
#if TORRENT_USE_ASSERTS #if TORRENT_USE_ASSERTS
p->in_use = false; p->in_use = false;
#endif #endif
state->peer_allocator->free_peer_entry(p); // TODO: 3 this is not exception safe!
m_peer_allocator.free_peer_entry(p);
return 0; return 0;
} }
state->first_time_seen = true; state->first_time_seen = true;

View File

@ -1172,7 +1172,7 @@ namespace libtorrent
void torrent::need_peer_list() void torrent::need_peer_list()
{ {
if (m_peer_list) return; if (m_peer_list) return;
m_peer_list.reset(new peer_list); m_peer_list.reset(new peer_list(m_ses.get_peer_allocator()));
} }
void torrent::handle_disk_error(disk_io_job const* j, peer_connection* c) void torrent::handle_disk_error(disk_io_job const* j, peer_connection* c)
@ -11503,7 +11503,6 @@ namespace {
: settings().get_int(settings_pack::max_peerlist_size); : settings().get_int(settings_pack::max_peerlist_size);
ret.min_reconnect_time = settings().get_int(settings_pack::min_reconnect_time); ret.min_reconnect_time = settings().get_int(settings_pack::min_reconnect_time);
ret.peer_allocator = m_ses.get_peer_allocator();
ret.ip = &m_ses.external_address(); ret.ip = &m_ses.external_address();
ret.port = m_ses.listen_port(); ret.port = m_ses.listen_port();
ret.max_failcount = settings().get_int(settings_pack::max_failcount); ret.max_failcount = settings().get_int(settings_pack::max_failcount);

View File

@ -162,15 +162,13 @@ bool has_peer(peer_list const& p, tcp::endpoint const& ep)
return its.first != its.second; return its.first != its.second;
} }
torrent_state init_state(torrent_peer_allocator& allocator torrent_state init_state(external_ip& ext_ip)
, external_ip& ext_ip)
{ {
torrent_state st; torrent_state st;
st.is_finished = false; st.is_finished = false;
st.is_paused = false; st.is_paused = false;
st.max_peerlist_size = 1000; st.max_peerlist_size = 1000;
st.allow_multiple_connections_per_ip = false; st.allow_multiple_connections_per_ip = false;
st.peer_allocator = &allocator;
st.ip = &ext_ip; st.ip = &ext_ip;
st.port = 9999; st.port = 9999;
return st; return st;
@ -206,9 +204,9 @@ static external_ip ext_ip;
// when disallowing it // when disallowing it
TORRENT_TEST(multiple_ips_disallowed) TORRENT_TEST(multiple_ips_disallowed)
{ {
torrent_state st = init_state(allocator, ext_ip); torrent_state st = init_state(ext_ip);
mock_torrent t(&st); mock_torrent t(&st);
peer_list p; peer_list p(allocator);
t.m_p = &p; t.m_p = &p;
TEST_EQUAL(p.num_connect_candidates(), 0); TEST_EQUAL(p.num_connect_candidates(), 0);
torrent_peer* peer1 = p.add_peer(ep("10.0.0.2", 3000), 0, 0, &st); torrent_peer* peer1 = p.add_peer(ep("10.0.0.2", 3000), 0, 0, &st);
@ -228,10 +226,10 @@ TORRENT_TEST(multiple_ips_disallowed)
// when allowing it // when allowing it
TORRENT_TEST(multiple_ips_allowed) TORRENT_TEST(multiple_ips_allowed)
{ {
torrent_state st = init_state(allocator, ext_ip); torrent_state st = init_state(ext_ip);
mock_torrent t(&st); mock_torrent t(&st);
st.allow_multiple_connections_per_ip = true; st.allow_multiple_connections_per_ip = true;
peer_list p; peer_list p(allocator);
t.m_p = &p; t.m_p = &p;
torrent_peer* peer1 = p.add_peer(ep("10.0.0.2", 3000), 0, 0, &st); torrent_peer* peer1 = p.add_peer(ep("10.0.0.2", 3000), 0, 0, &st);
TEST_EQUAL(p.num_connect_candidates(), 1); TEST_EQUAL(p.num_connect_candidates(), 1);
@ -250,10 +248,10 @@ TORRENT_TEST(multiple_ips_allowed)
// with allow_multiple_connections_per_ip enabled // with allow_multiple_connections_per_ip enabled
TORRENT_TEST(multiple_ips_allowed2) TORRENT_TEST(multiple_ips_allowed2)
{ {
torrent_state st = init_state(allocator, ext_ip); torrent_state st = init_state(ext_ip);
mock_torrent t(&st); mock_torrent t(&st);
st.allow_multiple_connections_per_ip = true; st.allow_multiple_connections_per_ip = true;
peer_list p; peer_list p(allocator);
t.m_p = &p; t.m_p = &p;
torrent_peer* peer1 = p.add_peer(ep("10.0.0.2", 3000), 0, 0, &st); torrent_peer* peer1 = p.add_peer(ep("10.0.0.2", 3000), 0, 0, &st);
TEST_EQUAL(p.num_connect_candidates(), 1); TEST_EQUAL(p.num_connect_candidates(), 1);
@ -289,10 +287,10 @@ TORRENT_TEST(multiple_ips_allowed2)
// with allow_multiple_connections_per_ip disabled // with allow_multiple_connections_per_ip disabled
TORRENT_TEST(multiple_ips_disallowed2) TORRENT_TEST(multiple_ips_disallowed2)
{ {
torrent_state st = init_state(allocator, ext_ip); torrent_state st = init_state(ext_ip);
mock_torrent t(&st); mock_torrent t(&st);
st.allow_multiple_connections_per_ip = false; st.allow_multiple_connections_per_ip = false;
peer_list p; peer_list p(allocator);
t.m_p = &p; t.m_p = &p;
torrent_peer* peer1 = p.add_peer(ep("10.0.0.2", 3000), 0, 0, &st); torrent_peer* peer1 = p.add_peer(ep("10.0.0.2", 3000), 0, 0, &st);
TEST_EQUAL(p.num_connect_candidates(), 1); TEST_EQUAL(p.num_connect_candidates(), 1);
@ -323,10 +321,10 @@ TORRENT_TEST(multiple_ips_disallowed2)
// and update_peer_port // and update_peer_port
TORRENT_TEST(update_peer_port) TORRENT_TEST(update_peer_port)
{ {
torrent_state st = init_state(allocator, ext_ip); torrent_state st = init_state(ext_ip);
mock_torrent t(&st); mock_torrent t(&st);
st.allow_multiple_connections_per_ip = false; st.allow_multiple_connections_per_ip = false;
peer_list p; peer_list p(allocator);
t.m_p = &p; t.m_p = &p;
TEST_EQUAL(p.num_connect_candidates(), 0); TEST_EQUAL(p.num_connect_candidates(), 0);
boost::shared_ptr<mock_peer_connection> c boost::shared_ptr<mock_peer_connection> c
@ -347,10 +345,10 @@ TORRENT_TEST(update_peer_port)
// and update_peer_port, causing collission // and update_peer_port, causing collission
TORRENT_TEST(update_peer_port_collide) TORRENT_TEST(update_peer_port_collide)
{ {
torrent_state st = init_state(allocator, ext_ip); torrent_state st = init_state(ext_ip);
mock_torrent t(&st); mock_torrent t(&st);
st.allow_multiple_connections_per_ip = true; st.allow_multiple_connections_per_ip = true;
peer_list p; peer_list p(allocator);
t.m_p = &p; t.m_p = &p;
torrent_peer* peer2 = p.add_peer(ep("10.0.0.1", 4000), 0, 0, &st); torrent_peer* peer2 = p.add_peer(ep("10.0.0.1", 4000), 0, 0, &st);
@ -378,10 +376,10 @@ TORRENT_TEST(update_peer_port_collide)
// test ip filter // test ip filter
TORRENT_TEST(ip_filter) TORRENT_TEST(ip_filter)
{ {
torrent_state st = init_state(allocator, ext_ip); torrent_state st = init_state(ext_ip);
mock_torrent t(&st); mock_torrent t(&st);
st.allow_multiple_connections_per_ip = false; st.allow_multiple_connections_per_ip = false;
peer_list p; peer_list p(allocator);
t.m_p = &p; t.m_p = &p;
// add peer 1 // add peer 1
@ -418,10 +416,10 @@ TORRENT_TEST(ip_filter)
// test port filter // test port filter
TORRENT_TEST(port_filter) TORRENT_TEST(port_filter)
{ {
torrent_state st = init_state(allocator, ext_ip); torrent_state st = init_state(ext_ip);
mock_torrent t(&st); mock_torrent t(&st);
st.allow_multiple_connections_per_ip = false; st.allow_multiple_connections_per_ip = false;
peer_list p; peer_list p(allocator);
t.m_p = &p; t.m_p = &p;
// add peer 1 // add peer 1
@ -458,10 +456,10 @@ TORRENT_TEST(port_filter)
// test banning peers // test banning peers
TORRENT_TEST(ban_peers) TORRENT_TEST(ban_peers)
{ {
torrent_state st = init_state(allocator, ext_ip); torrent_state st = init_state(ext_ip);
mock_torrent t(&st); mock_torrent t(&st);
st.allow_multiple_connections_per_ip = false; st.allow_multiple_connections_per_ip = false;
peer_list p; peer_list p(allocator);
t.m_p = &p; t.m_p = &p;
torrent_peer* peer1 = add_peer(p, st, ep("10.0.0.1", 4000)); torrent_peer* peer1 = add_peer(p, st, ep("10.0.0.1", 4000));
@ -499,11 +497,11 @@ TORRENT_TEST(ban_peers)
// test erase_peers when we fill up the peer list // test erase_peers when we fill up the peer list
TORRENT_TEST(erase_peers) TORRENT_TEST(erase_peers)
{ {
torrent_state st = init_state(allocator, ext_ip); torrent_state st = init_state(ext_ip);
mock_torrent t(&st); mock_torrent t(&st);
st.max_peerlist_size = 100; st.max_peerlist_size = 100;
st.allow_multiple_connections_per_ip = true; st.allow_multiple_connections_per_ip = true;
peer_list p; peer_list p(allocator);
t.m_p = &p; t.m_p = &p;
for (int i = 0; i < 100; ++i) for (int i = 0; i < 100; ++i)
@ -532,11 +530,11 @@ TORRENT_TEST(erase_peers)
// test set_ip_filter // test set_ip_filter
TORRENT_TEST(set_ip_filter) TORRENT_TEST(set_ip_filter)
{ {
torrent_state st = init_state(allocator, ext_ip); torrent_state st = init_state(ext_ip);
std::vector<address> banned; std::vector<address> banned;
mock_torrent t(&st); mock_torrent t(&st);
peer_list p; peer_list p(allocator);
t.m_p = &p; t.m_p = &p;
for (int i = 0; i < 100; ++i) for (int i = 0; i < 100; ++i)
@ -563,11 +561,11 @@ TORRENT_TEST(set_ip_filter)
// test set_port_filter // test set_port_filter
TORRENT_TEST(set_port_filter) TORRENT_TEST(set_port_filter)
{ {
torrent_state st = init_state(allocator, ext_ip); torrent_state st = init_state(ext_ip);
std::vector<address> banned; std::vector<address> banned;
mock_torrent t(&st); mock_torrent t(&st);
peer_list p; peer_list p(allocator);
t.m_p = &p; t.m_p = &p;
for (int i = 0; i < 100; ++i) for (int i = 0; i < 100; ++i)
@ -594,10 +592,10 @@ TORRENT_TEST(set_port_filter)
// test set_max_failcount // test set_max_failcount
TORRENT_TEST(set_max_failcount) TORRENT_TEST(set_max_failcount)
{ {
torrent_state st = init_state(allocator, ext_ip); torrent_state st = init_state(ext_ip);
mock_torrent t(&st); mock_torrent t(&st);
peer_list p; peer_list p(allocator);
t.m_p = &p; t.m_p = &p;
for (int i = 0; i < 100; ++i) for (int i = 0; i < 100; ++i)
@ -624,10 +622,10 @@ TORRENT_TEST(set_max_failcount)
// test set_seed // test set_seed
TORRENT_TEST(set_seed) TORRENT_TEST(set_seed)
{ {
torrent_state st = init_state(allocator, ext_ip); torrent_state st = init_state(ext_ip);
mock_torrent t(&st); mock_torrent t(&st);
peer_list p; peer_list p(allocator);
t.m_p = &p; t.m_p = &p;
for (int i = 0; i < 100; ++i) for (int i = 0; i < 100; ++i)
@ -658,11 +656,11 @@ TORRENT_TEST(set_seed)
// test has_peer // test has_peer
TORRENT_TEST(has_peer) TORRENT_TEST(has_peer)
{ {
torrent_state st = init_state(allocator, ext_ip); torrent_state st = init_state(ext_ip);
std::vector<address> banned; std::vector<address> banned;
mock_torrent t(&st); mock_torrent t(&st);
peer_list p; peer_list p(allocator);
t.m_p = &p; t.m_p = &p;
torrent_peer* peer1 = add_peer(p, st, ep("10.10.0.1", 10)); torrent_peer* peer1 = add_peer(p, st, ep("10.10.0.1", 10));
@ -691,11 +689,11 @@ TORRENT_TEST(has_peer)
// test connect_candidates torrent_finish // test connect_candidates torrent_finish
TORRENT_TEST(connect_candidates_finish) TORRENT_TEST(connect_candidates_finish)
{ {
torrent_state st = init_state(allocator, ext_ip); torrent_state st = init_state(ext_ip);
std::vector<address> banned; std::vector<address> banned;
mock_torrent t(&st); mock_torrent t(&st);
peer_list p; peer_list p(allocator);
t.m_p = &p; t.m_p = &p;
torrent_peer* peer1 = add_peer(p, st, ep("10.10.0.1", 10)); torrent_peer* peer1 = add_peer(p, st, ep("10.10.0.1", 10));
@ -730,10 +728,10 @@ TORRENT_TEST(connect_candidates_finish)
// test self-connection // test self-connection
TORRENT_TEST(self_connection) TORRENT_TEST(self_connection)
{ {
torrent_state st = init_state(allocator, ext_ip); torrent_state st = init_state(ext_ip);
mock_torrent t(&st); mock_torrent t(&st);
st.allow_multiple_connections_per_ip = false; st.allow_multiple_connections_per_ip = false;
peer_list p; peer_list p(allocator);
t.m_p = &p; t.m_p = &p;
// add and connect peer // add and connect peer
@ -762,10 +760,10 @@ TORRENT_TEST(self_connection)
// test double connection (both incoming) // test double connection (both incoming)
TORRENT_TEST(double_connection) TORRENT_TEST(double_connection)
{ {
torrent_state st = init_state(allocator, ext_ip); torrent_state st = init_state(ext_ip);
mock_torrent t(&st); mock_torrent t(&st);
st.allow_multiple_connections_per_ip = false; st.allow_multiple_connections_per_ip = false;
peer_list p; peer_list p(allocator);
t.m_p = &p; t.m_p = &p;
// we are 10.0.0.1 and the other peer is 10.0.0.2 // we are 10.0.0.1 and the other peer is 10.0.0.2
@ -792,10 +790,10 @@ TORRENT_TEST(double_connection)
// test double connection (we loose) // test double connection (we loose)
TORRENT_TEST(double_connection_loose) TORRENT_TEST(double_connection_loose)
{ {
torrent_state st = init_state(allocator, ext_ip); torrent_state st = init_state(ext_ip);
mock_torrent t(&st); mock_torrent t(&st);
st.allow_multiple_connections_per_ip = false; st.allow_multiple_connections_per_ip = false;
peer_list p; peer_list p(allocator);
t.m_p = &p; t.m_p = &p;
// we are 10.0.0.1 and the other peer is 10.0.0.2 // we are 10.0.0.1 and the other peer is 10.0.0.2
@ -823,10 +821,10 @@ TORRENT_TEST(double_connection_loose)
// test double connection (we win) // test double connection (we win)
TORRENT_TEST(double_connection_win) TORRENT_TEST(double_connection_win)
{ {
torrent_state st = init_state(allocator, ext_ip); torrent_state st = init_state(ext_ip);
mock_torrent t(&st); mock_torrent t(&st);
st.allow_multiple_connections_per_ip = false; st.allow_multiple_connections_per_ip = false;
peer_list p; peer_list p(allocator);
t.m_p = &p; t.m_p = &p;
// we are 10.0.0.1 and the other peer is 10.0.0.2 // we are 10.0.0.1 and the other peer is 10.0.0.2
@ -854,11 +852,11 @@ TORRENT_TEST(double_connection_win)
// test incoming connection when we are at the list size limit // test incoming connection when we are at the list size limit
TORRENT_TEST(incoming_size_limit) TORRENT_TEST(incoming_size_limit)
{ {
torrent_state st = init_state(allocator, ext_ip); torrent_state st = init_state(ext_ip);
st.max_peerlist_size = 5; st.max_peerlist_size = 5;
mock_torrent t(&st); mock_torrent t(&st);
st.allow_multiple_connections_per_ip = false; st.allow_multiple_connections_per_ip = false;
peer_list p; peer_list p(allocator);
t.m_p = &p; t.m_p = &p;
torrent_peer* peer1 = add_peer(p, st, ep("10.0.0.1", 8080)); torrent_peer* peer1 = add_peer(p, st, ep("10.0.0.1", 8080));
@ -900,11 +898,11 @@ TORRENT_TEST(incoming_size_limit)
// test new peer when we are at the list size limit // test new peer when we are at the list size limit
TORRENT_TEST(new_peer_size_limit) TORRENT_TEST(new_peer_size_limit)
{ {
torrent_state st = init_state(allocator, ext_ip); torrent_state st = init_state(ext_ip);
st.max_peerlist_size = 5; st.max_peerlist_size = 5;
mock_torrent t(&st); mock_torrent t(&st);
st.allow_multiple_connections_per_ip = false; st.allow_multiple_connections_per_ip = false;
peer_list p; peer_list p(allocator);
t.m_p = &p; t.m_p = &p;
torrent_peer* peer1 = add_peer(p, st, ep("10.0.0.1", 8080)); torrent_peer* peer1 = add_peer(p, st, ep("10.0.0.1", 8080));