diff --git a/include/libtorrent/aux_/session_impl.hpp b/include/libtorrent/aux_/session_impl.hpp index bef6f705f..85af66b56 100644 --- a/include/libtorrent/aux_/session_impl.hpp +++ b/include/libtorrent/aux_/session_impl.hpp @@ -374,9 +374,17 @@ namespace libtorrent static int allocations; static int allocated_bytes; }; - boost::object_pool m_peer_pool; + boost::object_pool< + policy::ipv4_peer, logging_allocator> m_ipv4_peer_pool; +# if TORRENT_USE_IPV6 + boost::object_pool< + policy::ipv6_peer, logging_allocator> m_ipv6_peer_pool; +# endif #else - boost::object_pool m_peer_pool; + boost::object_pool m_ipv4_peer_pool; +# if TORRENT_USE_IPV6 + boost::object_pool m_ipv6_peer_pool; +# endif #endif // this vector is used to store the block_info diff --git a/include/libtorrent/policy.hpp b/include/libtorrent/policy.hpp index e5a3199e5..8a7a76f8a 100644 --- a/include/libtorrent/policy.hpp +++ b/include/libtorrent/policy.hpp @@ -125,25 +125,13 @@ namespace libtorrent // 44 struct peer { - peer(tcp::endpoint const& ip, bool connectable, int src); - - peer(libtorrent::address const& a) { set_ip(tcp::endpoint(a, 0)); } + peer(); + peer(boost::uint16_t port, bool connectable, int src); size_type total_download() const; size_type total_upload() const; - void set_ip(tcp::endpoint const& endp); - -#if TORRENT_USE_IPV6 - libtorrent::address address() const - { - if (is_v6_addr) return address_v6(addr.v6); - else return address_v4(addr.v4); - } -#else - libtorrent::address address() const - { return addr; } -#endif + libtorrent::address address() const; tcp::endpoint ip() const { return tcp::endpoint(address(), port); } @@ -187,16 +175,6 @@ namespace libtorrent // in number of seconds since session was created boost::uint16_t last_connected; - // the ip address this peer is or was connected on -#if TORRENT_USE_IPV6 - union - { - address_v6::bytes_type v6; - address_v4::bytes_type v4; - } addr; -#else - address_v4 addr; -#endif // the port this peer is or was connected on boost::uint16_t port; @@ -278,6 +256,24 @@ namespace libtorrent #endif }; + struct ipv4_peer : peer + { + ipv4_peer(tcp::endpoint const& ip, bool connectable, int src); + ipv4_peer(libtorrent::address const& a); + + address_v4 addr; + }; + +#if TORRENT_USE_IPV6 + struct ipv6_peer : peer + { + ipv6_peer(tcp::endpoint const& ip, bool connectable, int src); + ipv6_peer(libtorrent::address const& a); + + address_v6::bytes_type addr; + }; +#endif + int num_peers() const { return m_peers.size(); } struct peer_ptr_compare @@ -297,16 +293,36 @@ namespace libtorrent std::pair find_peers(address const& a) { - peer tmp(a); peer_ptr_compare cmp; - return std::equal_range(m_peers.begin(), m_peers.end(), &tmp, cmp); +#if TORRENT_USE_IPV6 + if (a.is_v6()) + { + ipv6_peer tmp(a); + return std::equal_range(m_peers.begin(), m_peers.end(), &tmp, cmp); + } + else +#endif + { + ipv4_peer tmp(a); + return std::equal_range(m_peers.begin(), m_peers.end(), &tmp, cmp); + } } std::pair find_peers(address const& a) const { - peer tmp(a); peer_ptr_compare cmp; - return std::equal_range(m_peers.begin(), m_peers.end(), &tmp, cmp); +#if TORRENT_USE_IPV6 + if (a.is_v6()) + { + ipv6_peer tmp(a); + return std::equal_range(m_peers.begin(), m_peers.end(), &tmp, cmp); + } + else +#endif + { + ipv4_peer tmp(a); + return std::equal_range(m_peers.begin(), m_peers.end(), &tmp, cmp); + } } bool connect_one_peer(int session_time); @@ -368,6 +384,46 @@ namespace libtorrent bool m_finished; }; + inline policy::ipv4_peer::ipv4_peer( + tcp::endpoint const& ip, bool connectable, int src + ) + : peer(ip.port(), connectable, src) + , addr(ip.address().to_v4()) + { + is_v6_addr = false; + } + + inline policy::ipv4_peer::ipv4_peer(libtorrent::address const& a) + : addr(a.to_v4()) + { + is_v6_addr = false; + } + + inline policy::ipv6_peer::ipv6_peer( + tcp::endpoint const& ip, bool connectable, int src + ) + : peer(ip.port(), connectable, src) + , addr(ip.address().to_v6().to_bytes()) + { + is_v6_addr = true; + } + + inline policy::ipv6_peer::ipv6_peer(libtorrent::address const& a) + : addr(a.to_v6().to_bytes()) + { + is_v6_addr = true; + } + + inline libtorrent::address policy::peer::address() const + { +#if TORRENT_USE_IPV6 + if (is_v6_addr) + return libtorrent::address_v6( + static_cast(this)->addr); +#endif + return static_cast(this)->addr; + } + } #endif // TORRENT_POLICY_HPP_INCLUDED diff --git a/src/policy.cpp b/src/policy.cpp index 9ea0b63b5..d93d59be2 100644 --- a/src/policy.cpp +++ b/src/policy.cpp @@ -411,7 +411,14 @@ namespace libtorrent --m_num_connect_candidates; if (m_round_robin > i - m_peers.begin()) --m_round_robin; - m_torrent->session().m_peer_pool.destroy(*i); +#if TORRENT_USE_IPV6 + if ((*i)->is_v6_addr) + m_torrent->session().m_ipv6_peer_pool.destroy( + static_cast(*i)); + else +#endif + m_torrent->session().m_ipv4_peer_pool.destroy( + static_cast(*i)); m_peers.erase(i); } @@ -699,10 +706,21 @@ namespace libtorrent } else { - peer tmp(c.remote().address()); peer_ptr_compare cmp; - iter = std::lower_bound(m_peers.begin(), m_peers.end() - , &tmp, cmp); +#if TORRENT_USE_IPV6 + if (c.remote().address().is_v6()) + { + ipv6_peer tmp(c.remote().address()); + iter = std::lower_bound(m_peers.begin(), m_peers.end() + , &tmp, cmp); + } + else +#endif + { + ipv4_peer tmp(c.remote().address()); + iter = std::lower_bound(m_peers.begin(), m_peers.end() + , &tmp, cmp); + } if (iter != m_peers.end() && (*iter)->address() == c.remote().address()) found = true; } @@ -783,10 +801,29 @@ namespace libtorrent } if (m_round_robin > iter - m_peers.begin()) ++m_round_robin; - peer* p = m_torrent->session().m_peer_pool.malloc(); +#if TORRENT_USE_IPV6 + bool is_v6 = c.remote().address().is_v6(); +#endif + peer* p = +#if TORRENT_USE_IPV6 + is_v6 ? (peer*)m_torrent->session().m_ipv6_peer_pool.malloc() : +#endif + (peer*)m_torrent->session().m_ipv4_peer_pool.malloc(); if (p == 0) return false; - m_torrent->session().m_peer_pool.set_next_size(500); - new (p) peer(c.remote(), false, 0); +#if TORRENT_USE_IPV6 + if (is_v6) + m_torrent->session().m_ipv6_peer_pool.set_next_size(500); + else +#endif + m_torrent->session().m_ipv4_peer_pool.set_next_size(500); + +#if TORRENT_USE_IPV6 + if (is_v6) + new (p) ipv6_peer(c.remote(), false, 0); + else +#endif + new (p) ipv4_peer(c.remote(), false, 0); + iter = m_peers.insert(iter, p); i = *iter; @@ -913,10 +950,22 @@ namespace libtorrent } else { - peer tmp(remote.address()); peer_ptr_compare cmp; - iter = std::lower_bound(m_peers.begin(), m_peers.end() - , &tmp, cmp); +#if TORRENT_USE_IPV6 + if (remote.address().is_v6()) + { + ipv6_peer tmp(remote.address()); + iter = std::lower_bound(m_peers.begin(), m_peers.end() + , &tmp, cmp); + } + else +#endif + { + ipv4_peer tmp(remote.address()); + iter = std::lower_bound(m_peers.begin(), m_peers.end() + , &tmp, cmp); + } + if (iter != m_peers.end() && (*iter)->address() == remote.address()) found = true; } @@ -933,20 +982,50 @@ namespace libtorrent // since some peers were removed, we need to // update the iterator to make it valid again - peer tmp(remote.address()); peer_ptr_compare cmp; - iter = std::lower_bound(m_peers.begin(), m_peers.end() - , &tmp, cmp); +#if TORRENT_USE_IPV6 + if (remote.address().is_v6()) + { + ipv6_peer tmp(remote.address()); + iter = std::lower_bound(m_peers.begin(), m_peers.end() + , &tmp, cmp); + } + else +#endif + { + ipv4_peer tmp(remote.address()); + iter = std::lower_bound(m_peers.begin(), m_peers.end() + , &tmp, cmp); + } } if (m_round_robin > iter - m_peers.begin()) ++m_round_robin; // we don't have any info about this peer. // add a new entry - peer* p = m_torrent->session().m_peer_pool.malloc(); +#if TORRENT_USE_IPV6 + bool is_v6 = remote.address().is_v6(); +#endif + peer* p = +#if TORRENT_USE_IPV6 + is_v6 ? (peer*)m_torrent->session().m_ipv6_peer_pool.malloc() : +#endif + (peer*)m_torrent->session().m_ipv4_peer_pool.malloc(); if (p == 0) return 0; - m_torrent->session().m_peer_pool.set_next_size(500); - new (p) peer(remote, true, src); +#if TORRENT_USE_IPV6 + if (is_v6) + m_torrent->session().m_ipv6_peer_pool.set_next_size(500); + else +#endif + m_torrent->session().m_ipv4_peer_pool.set_next_size(500); + +#if TORRENT_USE_IPV6 + if (is_v6) + new (p) ipv6_peer(remote, true, src); + else +#endif + new (p) ipv4_peer(remote, true, src); + iter = m_peers.insert(iter, p); i = *iter; @@ -1395,7 +1474,10 @@ namespace libtorrent } #endif // TORRENT_DEBUG - policy::peer::peer(const tcp::endpoint& ip_, bool conn, int src) + policy::peer::peer() + {} + + policy::peer::peer(boost::uint16_t port, bool conn, int src) : prev_amount_upload(0) , prev_amount_download(0) , connection(0) @@ -1404,10 +1486,7 @@ namespace libtorrent #endif , last_optimistically_unchoked(0) , last_connected(0) -#if !TORRENT_USE_IPV6 - , addr(ip_.address().to_v4()) -#endif - , port(ip_.port()) + , port(port) , hashfails(0) , failcount(0) , connectable(conn) @@ -1428,8 +1507,6 @@ namespace libtorrent , added_to_dht(false) #endif { - set_ip(ip_); - TORRENT_ASSERT((src & 0xff) == src); } @@ -1446,27 +1523,6 @@ namespace libtorrent } } - void policy::peer::set_ip(tcp::endpoint const& endp) - { -#if TORRENT_USE_IPV6 - if (endp.address().is_v6()) - { - is_v6_addr = true; - addr.v6 = endp.address().to_v6().to_bytes(); - } - else - { - is_v6_addr = false; - addr.v4 = endp.address().to_v4().to_bytes(); - } -#else - TORRENT_ASSERT(endp.address().is_v4()); - addr = endp.address().to_v4(); -#endif - - port = endp.port(); - } - size_type policy::peer::total_upload() const { if (connection != 0) diff --git a/src/session_impl.cpp b/src/session_impl.cpp index 894bfd730..d2881672f 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -167,7 +167,10 @@ namespace aux { , fs::path const& logpath #endif ) - : m_peer_pool(500) + : m_ipv4_peer_pool(500) +#if TORRENT_USE_IPV6 + , m_ipv6_peer_pool(500) +#endif #ifndef TORRENT_DISABLE_POOL_ALLOCATOR , m_send_buffers(send_buffer_size) #endif @@ -271,10 +274,14 @@ namespace aux { PRINT_OFFSETOF(policy::peer, connection) PRINT_OFFSETOF(policy::peer, last_optimistically_unchoked) PRINT_OFFSETOF(policy::peer, last_connected) - PRINT_OFFSETOF(policy::peer, addr) PRINT_OFFSETOF(policy::peer, port) PRINT_OFFSETOF(policy::peer, hashfails) + PRINT_SIZEOF(policy::ipv4_peer) +#if TORRENT_USE_IPV6 + PRINT_SIZEOF(policy::ipv6_peer) +#endif + PRINT_SIZEOF(dht::closest_nodes_observer) PRINT_SIZEOF(dht::find_data_observer) PRINT_SIZEOF(dht::announce_observer)