From 72b99059e765b67c6864e7dd4efe4cd582b5aa7c Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Mon, 14 Jul 2008 11:15:35 +0000 Subject: [PATCH] optimized policy::peer --- include/libtorrent/policy.hpp | 59 ++++++++++++++++++++--------------- src/bt_peer_connection.cpp | 2 +- src/policy.cpp | 59 ++++++++++++++++++----------------- src/session_impl.cpp | 5 +++ src/smart_ban.cpp | 6 ++-- src/torrent.cpp | 26 +++++++-------- 6 files changed, 84 insertions(+), 73 deletions(-) diff --git a/include/libtorrent/policy.hpp b/include/libtorrent/policy.hpp index 158163531..1a345f879 100644 --- a/include/libtorrent/policy.hpp +++ b/include/libtorrent/policy.hpp @@ -124,8 +124,36 @@ namespace libtorrent size_type total_download() const; size_type total_upload() const; - // the ip/port pair this peer is or was connected on - tcp::endpoint ip; + tcp::endpoint ip() const { return tcp::endpoint(addr, port); } + void set_ip(tcp::endpoint const& endp) + { addr = endp.address(); port = endp.port(); } + + // this is the accumulated amount of + // uploaded and downloaded data to this + // peer. It only accounts for what was + // shared during the last connection to + // this peer. i.e. These are only updated + // when the connection is closed. For the + // total amount of upload and download + // we'll have to add thes figures with the + // statistics from the peer_connection. + size_type prev_amount_upload; + size_type prev_amount_download; + + // the ip address this peer is or was connected on + address addr; + + // the time when this peer was optimistically unchoked + // the last time. + libtorrent::ptime last_optimistically_unchoked; + + // the time when the peer connected to us + // or disconnected if it isn't connected right now + libtorrent::ptime connected; + + // if the peer is connected now, this + // will refer to a valid peer_connection + peer_connection* connection; #ifndef TORRENT_DISABLE_GEO_IP #ifndef NDEBUG @@ -137,6 +165,9 @@ namespace libtorrent std::pair* inet_as; #endif + // the port this peer is or was connected on + uint16_t port; + // the number of failed connection attempts // this peer has boost::uint8_t failcount; @@ -205,30 +236,6 @@ namespace libtorrent // pinged by the DHT bool added_to_dht:1; #endif - - // if the peer is connected now, this - // will refer to a valid peer_connection - peer_connection* connection; - - // this is the accumulated amount of - // uploaded and downloaded data to this - // peer. It only accounts for what was - // shared during the last connection to - // this peer. i.e. These are only updated - // when the connection is closed. For the - // total amount of upload and download - // we'll have to add thes figures with the - // statistics from the peer_connection. - size_type prev_amount_upload; - size_type prev_amount_download; - - // the time when this peer was optimistically unchoked - // the last time. - libtorrent::ptime last_optimistically_unchoked; - - // the time when the peer connected to us - // or disconnected if it isn't connected right now - libtorrent::ptime connected; }; int num_peers() const { return m_peers.size(); } diff --git a/src/bt_peer_connection.cpp b/src/bt_peer_connection.cpp index dbba0e407..72515ff19 100644 --- a/src/bt_peer_connection.cpp +++ b/src/bt_peer_connection.cpp @@ -1695,7 +1695,7 @@ namespace libtorrent && p.second.connection && p.second.connection->pid() == m_id && !p.second.connection->pid().is_all_zeros() - && p.second.ip.address() == m_pc->remote().address(); + && p.second.addr == m_pc->remote().address(); } peer_id const& m_id; diff --git a/src/policy.cpp b/src/policy.cpp index 33845b860..06990d45a 100644 --- a/src/policy.cpp +++ b/src/policy.cpp @@ -145,7 +145,7 @@ namespace {} bool operator()(std::pair const& p) const - { return p.second.ip == m_ep; } + { return p.second.addr == m_ep.address() && p.second.port == m_ep.port(); } tcp::endpoint const& m_ep; }; @@ -160,7 +160,7 @@ namespace bool operator()(std::pair const& p) const { return p.second.connection == &m_conn - || (p.second.ip == m_conn.remote() + || (p.second.ip() == m_conn.remote() && p.second.type == policy::peer::connectable); } @@ -347,7 +347,7 @@ namespace libtorrent for (iterator i = m_peers.begin() , end(m_peers.end()); i != end;) { - if ((ses.m_ip_filter.access(i->second.ip.address()) & ip_filter::blocked) == 0) + if ((ses.m_ip_filter.access(i->second.addr) & ip_filter::blocked) == 0) { ++i; continue; @@ -357,14 +357,14 @@ namespace libtorrent { i->second.connection->disconnect("peer banned by IP filter"); if (ses.m_alerts.should_post()) - ses.m_alerts.post_alert(peer_blocked_alert(i->second.ip.address())); + ses.m_alerts.post_alert(peer_blocked_alert(i->second.addr)); TORRENT_ASSERT(i->second.connection == 0 || i->second.connection->peer_info_struct() == 0); } else { if (ses.m_alerts.should_post()) - ses.m_alerts.post_alert(peer_blocked_alert(i->second.ip.address())); + ses.m_alerts.post_alert(peer_blocked_alert(i->second.addr)); } erase_peer(i++); } @@ -396,7 +396,7 @@ namespace libtorrent return false; aux::session_impl& ses = m_torrent->session(); - if (ses.m_port_filter.access(p.ip.port()) & port_filter::blocked) + if (ses.m_port_filter.access(p.port) & port_filter::blocked) return false; return true; } @@ -444,7 +444,7 @@ namespace libtorrent // advertise support) if (!pinged && !pe.added_to_dht) { - udp::endpoint node(pe.ip.address(), pe.ip.port()); + udp::endpoint node(pe.addr, pe.port); m_torrent->session().add_dht_node(node); pe.added_to_dht = true; pinged = true; @@ -487,8 +487,8 @@ namespace libtorrent { (*m_torrent->session().m_logger) << time_now_string() << " *** FOUND CONNECTION CANDIDATE [" - " ip: " << candidate->second.ip << - " d: " << cidr_distance(external_ip, candidate->second.ip.address()) << + " ip: " << candidate->second.ip() << + " d: " << cidr_distance(external_ip, candidate->second.addr) << " external: " << external_ip << " t: " << total_seconds(time_now() - candidate->second.connected) << " ]\n"; @@ -683,11 +683,11 @@ namespace libtorrent TORRENT_ASSERT(p != 0); TORRENT_ASSERT(p->connection); - if (p->ip.port() == port) return true; + if (p->port == port) return true; if (m_torrent->settings().allow_multiple_connections_per_ip) { - tcp::endpoint remote(p->ip.address(), port); + tcp::endpoint remote(p->addr, port); std::pair range = m_peers.equal_range(remote.address()); iterator i = std::find_if(range.first, range.second , match_peer_endpoint(remote)); @@ -704,10 +704,10 @@ namespace libtorrent } else { - TORRENT_ASSERT(m_peers.count(p->ip.address()) == 1); + TORRENT_ASSERT(m_peers.count(p->addr) == 1); } bool was_conn_cand = is_connect_candidate(*p, m_torrent->is_finished()); - p->ip.port(port); + p->port = port; p->source |= src; if (was_conn_cand != is_connect_candidate(*p, m_torrent->is_finished())) @@ -806,7 +806,7 @@ namespace libtorrent i->second.type = peer::connectable; - i->second.ip = remote; + i->second.set_ip(remote); i->second.source |= src; // if this peer has failed before, decrease the @@ -1102,14 +1102,14 @@ namespace libtorrent #endif if (!m_torrent->settings().allow_multiple_connections_per_ip) { - TORRENT_ASSERT(m_peers.count(p.ip.address()) == 1); + TORRENT_ASSERT(m_peers.count(p.addr) == 1); } else { - TORRENT_ASSERT(unique_test.count(p.ip) == 0); - unique_test.insert(p.ip); - TORRENT_ASSERT(i->first == p.ip.address()); -// TORRENT_ASSERT(p.connection == 0 || p.ip == p.connection->remote()); + TORRENT_ASSERT(unique_test.count(p.ip()) == 0); + unique_test.insert(p.ip()); + TORRENT_ASSERT(i->first == p.addr); +// TORRENT_ASSERT(p.connection == 0 || p.ip() == p.connection->remote()); } ++total_connections; if (!p.connection) @@ -1186,10 +1186,16 @@ namespace libtorrent #endif policy::peer::peer(const tcp::endpoint& ip_, peer::connection_type t, int src) - : ip(ip_) + : prev_amount_upload(0) + , prev_amount_download(0) + , addr(ip_.address()) + , last_optimistically_unchoked(min_time()) + , connected(min_time()) + , connection(0) #ifndef TORRENT_DISABLE_GEO_IP , inet_as(0) #endif + , port(ip_.port()) , failcount(0) , trust_points(0) , source(src) @@ -1206,11 +1212,6 @@ namespace libtorrent #ifndef TORRENT_DISABLE_DHT , added_to_dht(false) #endif - , connection(0) - , prev_amount_upload(0) - , prev_amount_download(0) - , last_optimistically_unchoked(min_time()) - , connected(min_time()) { TORRENT_ASSERT((src & 0xff) == src); TORRENT_ASSERT(connected < time_now()); @@ -1251,8 +1252,8 @@ namespace libtorrent return lhs.failcount < rhs.failcount; // Local peers should always be tried first - bool lhs_local = is_local(lhs.ip.address()); - bool rhs_local = is_local(rhs.ip.address()); + bool lhs_local = is_local(lhs.addr); + bool rhs_local = is_local(rhs.addr); if (lhs_local != rhs_local) return lhs_local > rhs_local; if (lhs.connected != rhs.connected) @@ -1267,8 +1268,8 @@ namespace libtorrent if (lhs_as != rhs_as) return lhs_as > rhs_as; } #endif - int lhs_distance = cidr_distance(external_ip, lhs.ip.address()); - int rhs_distance = cidr_distance(external_ip, rhs.ip.address()); + int lhs_distance = cidr_distance(external_ip, lhs.addr); + int rhs_distance = cidr_distance(external_ip, rhs.addr); if (lhs_distance < rhs_distance) return true; return false; } diff --git a/src/session_impl.cpp b/src/session_impl.cpp index 774159b66..a16bdc5c1 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -219,6 +219,11 @@ namespace aux { (*m_logger) << "sizeof(peer_connection): " << sizeof(peer_connection) << "\n"; (*m_logger) << "sizeof(bt_peer_connection): " << sizeof(bt_peer_connection) << "\n"; (*m_logger) << "sizeof(policy::peer): " << sizeof(policy::peer) << "\n"; + (*m_logger) << "sizeof(tcp::endpoint): " << sizeof(tcp::endpoint) << "\n"; + (*m_logger) << "sizeof(address): " << sizeof(address) << "\n"; + (*m_logger) << "sizeof(address_v4): " << sizeof(address_v4) << "\n"; + (*m_logger) << "sizeof(address_v6): " << sizeof(address_v6) << "\n"; + (*m_logger) << "sizeof(void*): " << sizeof(void*) << "\n"; #endif #ifdef TORRENT_STATS diff --git a/src/smart_ban.cpp b/src/smart_ban.cpp index a3db95e2b..759377ed8 100644 --- a/src/smart_ban.cpp +++ b/src/smart_ban.cpp @@ -206,7 +206,7 @@ namespace libtorrent { namespace << " | c: " << client << " | crc1: " << i->second.crc << " | crc2: " << e.crc - << " | ip: " << p->ip << " ]\n"; + << " | ip: " << p->ip() << " ]\n"; #endif p->banned = true; if (p->connection) p->connection->disconnect("banning peer for sending bad data"); @@ -230,7 +230,7 @@ namespace libtorrent { namespace << " | b: " << b.block_index << " | c: " << client << " | crc: " << e.crc - << " | ip: " << p->ip << " ]\n"; + << " | ip: " << p->ip() << " ]\n"; #endif } @@ -268,7 +268,7 @@ namespace libtorrent { namespace << " | c: " << client << " | ok_crc: " << ok_crc << " | bad_crc: " << b.second.crc - << " | ip: " << p->ip << " ]\n"; + << " | ip: " << p->ip() << " ]\n"; #endif p->banned = true; if (p->connection) p->connection->disconnect("banning peer for sending bad data"); diff --git a/src/torrent.cpp b/src/torrent.cpp index 0d1f1644e..d0290bf51 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -1476,7 +1476,7 @@ namespace libtorrent peer_id pid; if (p->connection) pid = p->connection->pid(); m_ses.m_alerts.post_alert(peer_ban_alert( - get_handle(), p->ip, pid)); + get_handle(), p->ip(), pid)); } // mark the peer as banned @@ -1485,11 +1485,11 @@ namespace libtorrent if (p->connection) { #ifdef TORRENT_LOGGING - (*m_ses.m_logger) << time_now_string() << " *** BANNING PEER [ " << p->ip + (*m_ses.m_logger) << time_now_string() << " *** BANNING PEER [ " << p->ip() << " ] 'too many corrupt pieces'\n"; #endif #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING - (*p->connection->m_logger) << "*** BANNING PEER [ " << p->ip + (*p->connection->m_logger) << "*** BANNING PEER [ " << p->ip() << " ] 'too many corrupt pieces'\n"; #endif p->connection->disconnect("too many corrupt pieces, banning peer"); @@ -2534,11 +2534,10 @@ namespace libtorrent error_code ec; if (i->second.banned) { - tcp::endpoint ip = i->second.ip; entry peer(entry::dictionary_t); - peer["ip"] = ip.address().to_string(ec); + peer["ip"] = i->second.addr.to_string(ec); if (ec) continue; - peer["port"] = ip.port(); + peer["port"] = i->second.port; banned_peer_list.push_back(peer); continue; } @@ -2554,11 +2553,10 @@ namespace libtorrent // don't save peers that doesn't work if (i->second.failcount >= max_failcount) continue; - tcp::endpoint ip = i->second.ip; entry peer(entry::dictionary_t); - peer["ip"] = ip.address().to_string(ec); + peer["ip"] = i->second.addr.to_string(ec); if (ec) continue; - peer["port"] = ip.port(); + peer["port"] = i->second.port; peer_list.push_back(peer); } } @@ -2571,7 +2569,7 @@ namespace libtorrent i != m_policy.end_peer(); ++i) { peer_list_entry e; - e.ip = i->second.ip; + e.ip = i->second.ip(); e.flags = i->second.banned ? peer_list_entry::banned : 0; e.failcount = i->second.failcount; e.source = i->second.source; @@ -2660,7 +2658,7 @@ namespace libtorrent } else { - bi.peer = p->ip; + bi.peer = p->ip(); bi.bytes_progress = complete ? bi.block_size : 0; } } @@ -2684,7 +2682,7 @@ namespace libtorrent #ifndef NDEBUG // this asserts that we don't have duplicates in the policy's peer list peer_iterator i_ = std::find_if(m_connections.begin(), m_connections.end() - , bind(&peer_connection::remote, _1) == peerinfo->ip); + , bind(&peer_connection::remote, _1) == peerinfo->ip()); TORRENT_ASSERT(i_ == m_connections.end() || dynamic_cast(*i_) == 0); #endif @@ -2692,8 +2690,8 @@ namespace libtorrent TORRENT_ASSERT(want_more_peers()); TORRENT_ASSERT(m_ses.num_connections() < m_ses.max_connections()); - tcp::endpoint const& a(peerinfo->ip); - TORRENT_ASSERT((m_ses.m_ip_filter.access(a.address()) & ip_filter::blocked) == 0); + tcp::endpoint a(peerinfo->ip()); + TORRENT_ASSERT((m_ses.m_ip_filter.access(peerinfo->addr) & ip_filter::blocked) == 0); boost::shared_ptr s(new socket_type(m_ses.m_io_service));