From efd096d8792c63f28bb56f0d328d3085ffb487ca Mon Sep 17 00:00:00 2001 From: arvidn Date: Sun, 21 Jan 2018 20:59:08 +0100 Subject: [PATCH] use unique peer_ids per connection --- ChangeLog | 1 + bindings/python/src/session.cpp | 2 +- include/libtorrent/aux_/session_impl.hpp | 8 +----- include/libtorrent/aux_/session_interface.hpp | 3 --- include/libtorrent/bt_peer_connection.hpp | 3 +-- include/libtorrent/session_handle.hpp | 6 ++--- include/libtorrent/settings_pack.hpp | 2 +- include/libtorrent/torrent.hpp | 9 ++++++- src/bt_peer_connection.cpp | 25 ++---------------- src/session_handle.cpp | 4 +-- src/session_impl.cpp | 26 ++++--------------- src/settings_pack.cpp | 2 +- src/torrent.cpp | 25 +++++++++++++++--- test/setup_transfer.cpp | 17 ------------ test/test_session.cpp | 22 +++------------- 15 files changed, 50 insertions(+), 105 deletions(-) diff --git a/ChangeLog b/ChangeLog index a902b9ff0..b50156139 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,5 @@ + * use unique peer_ids per connection * fix iOS build on recent SDK * fix tracker connection bind issue for IPv6 trackers * fix error handling of some merkle torrents diff --git a/bindings/python/src/session.cpp b/bindings/python/src/session.cpp index a54ddeb69..513e0c1e3 100644 --- a/bindings/python/src/session.cpp +++ b/bindings/python/src/session.cpp @@ -973,7 +973,6 @@ void bind_session() .def("pause", allow_threads(<::session::pause)) .def("resume", allow_threads(<::session::resume)) .def("is_paused", allow_threads(<::session::is_paused)) - .def("id", allow_threads(<::session::id)) .def("get_cache_info", &get_cache_info1, (arg("handle") = torrent_handle(), arg("flags") = 0)) .def("add_port_mapping", allow_threads(<::session::add_port_mapping)) .def("delete_port_mapping", allow_threads(<::session::delete_port_mapping)) @@ -985,6 +984,7 @@ void bind_session() .def("set_peer_class", &set_peer_class) #ifndef TORRENT_NO_DEPRECATE + .def("id", allow_threads(<::session::id)) .def( "listen_on", &listen_on , (arg("min"), "max", arg("interface") = (char const*)0, arg("flags") = 0) diff --git a/include/libtorrent/aux_/session_impl.hpp b/include/libtorrent/aux_/session_impl.hpp index 1d3d922e9..3d60ce92f 100644 --- a/include/libtorrent/aux_/session_impl.hpp +++ b/include/libtorrent/aux_/session_impl.hpp @@ -265,8 +265,6 @@ namespace libtorrent , peer_connection* pc) TORRENT_OVERRIDE; void set_queue_position(torrent* t, int p) TORRENT_OVERRIDE; - peer_id const& get_peer_id() const TORRENT_OVERRIDE { return m_peer_id; } - void close_connection(peer_connection* p, error_code const& ec) TORRENT_OVERRIDE; #ifndef TORRENT_NO_DEPRECATE @@ -479,9 +477,9 @@ namespace libtorrent #ifndef TORRENT_NO_DEPRECATE session_status status() const; + peer_id deprecated_get_peer_id() const; #endif - void set_peer_id(peer_id const& id); void set_key(int key); address listen_address() const; boost::uint16_t listen_port() const TORRENT_OVERRIDE; @@ -659,7 +657,6 @@ namespace libtorrent void update_lsd(); void update_dht(); void update_count_slow(); - void update_peer_fingerprint(); void update_dht_bootstrap_nodes(); void update_socket_buffer_size(); @@ -838,9 +835,6 @@ namespace libtorrent // filters outgoing connections port_filter m_port_filter; - // the peer id that is generated at the start of the session - peer_id m_peer_id; - // this is the highest queue position of any torrent // in this session. queue positions are packed (i.e. there // are no gaps). If there are no torrents with queue positions diff --git a/include/libtorrent/aux_/session_interface.hpp b/include/libtorrent/aux_/session_interface.hpp index 8a646a23d..b3738bd7c 100644 --- a/include/libtorrent/aux_/session_interface.hpp +++ b/include/libtorrent/aux_/session_interface.hpp @@ -34,7 +34,6 @@ POSSIBILITY OF SUCH DAMAGE. #define TORRENT_SESSION_INTERFACE_HPP_INCLUDED #include "libtorrent/config.hpp" -#include "libtorrent/peer_id.hpp" #include "libtorrent/address.hpp" #include "libtorrent/io_service.hpp" #include "libtorrent/disk_buffer_holder.hpp" @@ -204,8 +203,6 @@ namespace libtorrent { namespace aux virtual void set_queue_position(torrent* t, int p) = 0; virtual int num_torrents() const = 0; - virtual peer_id const& get_peer_id() const = 0; - // cork a peer and schedule a delayed uncork // does nothing if the peer is already corked virtual void cork_burst(peer_connection* p) = 0; diff --git a/include/libtorrent/bt_peer_connection.hpp b/include/libtorrent/bt_peer_connection.hpp index 880172773..49707d1e0 100644 --- a/include/libtorrent/bt_peer_connection.hpp +++ b/include/libtorrent/bt_peer_connection.hpp @@ -76,8 +76,7 @@ namespace libtorrent // this is the constructor where the we are the active part. // The peer_connection should handshake and verify that the // other end has the correct id - bt_peer_connection(peer_connection_args const& pack - , peer_id const& pid); + bt_peer_connection(peer_connection_args const& pack); virtual void start() TORRENT_OVERRIDE; diff --git a/include/libtorrent/session_handle.hpp b/include/libtorrent/session_handle.hpp index 0f726113f..4a2a10e0e 100644 --- a/include/libtorrent/session_handle.hpp +++ b/include/libtorrent/session_handle.hpp @@ -588,11 +588,11 @@ namespace libtorrent // deprecated in 1.1, use settings_pack::peer_fingerprint instead TORRENT_DEPRECATED void set_peer_id(peer_id const& pid); -#endif - // returns the raw peer ID used by libtorrent. When anonymous mode is set - // the peer ID is randomized per peer. + // deprecated in 1.1.7. read settings_pack::peer_fingerprint instead + TORRENT_DEPRECATED peer_id id() const; +#endif // sets the key sent to trackers. If it's not set, it is initialized // by libtorrent. The key may be used by the tracker to identify the diff --git a/include/libtorrent/settings_pack.hpp b/include/libtorrent/settings_pack.hpp index 415f7e571..ad5afb71b 100644 --- a/include/libtorrent/settings_pack.hpp +++ b/include/libtorrent/settings_pack.hpp @@ -227,7 +227,7 @@ namespace libtorrent // this is the fingerprint for the client. It will be used as the // prefix to the peer_id. If this is 20 bytes (or longer) it will be - // truncated at 20 bytes and used as the entire peer-id + // truncated to 20 bytes and used as the entire peer-id // // There is a utility function, generate_fingerprint() that can be used // to generate a standard client peer ID fingerprint prefix. diff --git a/include/libtorrent/torrent.hpp b/include/libtorrent/torrent.hpp index 965eab326..c1c41e4ae 100644 --- a/include/libtorrent/torrent.hpp +++ b/include/libtorrent/torrent.hpp @@ -111,6 +111,7 @@ namespace libtorrent class bt_peer_connection; struct listen_socket_t; + peer_id generate_peer_id(aux::session_settings const& sett); namespace aux { @@ -358,7 +359,7 @@ namespace libtorrent // if we're connected to a peer at ep, return its peer connection // only count BitTorrent peers bt_peer_connection* find_peer(tcp::endpoint const& ep) const; - peer_connection* find_peer(sha1_hash const& pid); + peer_connection* find_peer(peer_id const& pid); void on_resume_data_checked(disk_io_job const* j); void on_force_recheck(disk_io_job const* j); @@ -1452,6 +1453,12 @@ namespace libtorrent // connections (if we've reached the connection limit) boost::uint16_t m_num_connecting; + // this is the peer id we generate when we add the torrent. Peers won't + // use this (they generate their own peer ids) but this is used in case + // the tracker returns peer IDs, to identify ourself in the peer list to + // avoid connecting back to it. + peer_id m_peer_id; + // ============================== // The following members are specifically // ordered to make the 24 bit members diff --git a/src/bt_peer_connection.cpp b/src/bt_peer_connection.cpp index bd7d79115..eb5119050 100644 --- a/src/bt_peer_connection.cpp +++ b/src/bt_peer_connection.cpp @@ -100,9 +100,7 @@ namespace libtorrent #endif }; - - bt_peer_connection::bt_peer_connection(peer_connection_args const& pack - , peer_id const& pid) + bt_peer_connection::bt_peer_connection(peer_connection_args const& pack) : peer_connection(pack) , m_state(read_protocol_identifier) , m_supports_extensions(false) @@ -116,7 +114,7 @@ namespace libtorrent , m_rc4_encrypted(false) , m_recv_buffer(peer_connection::m_recv_buffer) #endif - , m_our_peer_id(pid) + , m_our_peer_id(generate_peer_id(*pack.sett)) #if !defined(TORRENT_DISABLE_ENCRYPTION) && !defined(TORRENT_DISABLE_EXTENSIONS) , m_sync_bytes_read(0) #endif @@ -837,15 +835,6 @@ namespace libtorrent memcpy(ptr, &ih[0], 20); ptr += 20; - // peer id - if (m_settings.get_bool(settings_pack::anonymous_mode)) - { - // in anonymous mode, every peer connection - // has a unique peer-id - for (int i = 0; i < 20; ++i) - m_our_peer_id[i] = random() & 0xff; - } - memcpy(ptr, &m_our_peer_id[0], 20); ptr += 20; @@ -3394,16 +3383,6 @@ namespace libtorrent } set_pid(pid); - - // disconnect if the peer has the same peer-id as ourself - // since it most likely is ourself then - if (pid == m_our_peer_id) - { - if (peer_info_struct()) t->ban_peer(peer_info_struct()); - disconnect(errors::self_connection, op_bittorrent, 1); - return; - } - m_client_version = identify_client(pid); if (pid[0] == '-' && pid[1] == 'B' && pid[2] == 'C' && pid[7] == '-') { diff --git a/src/session_handle.cpp b/src/session_handle.cpp index a795631aa..22370fef8 100644 --- a/src/session_handle.cpp +++ b/src/session_handle.cpp @@ -580,12 +580,12 @@ namespace libtorrent p.set_str(settings_pack::peer_fingerprint, id.to_string()); apply_settings(p); } -#endif peer_id session_handle::id() const { - return TORRENT_SYNC_CALL_RET(peer_id, get_peer_id); + return TORRENT_SYNC_CALL_RET(peer_id, deprecated_get_peer_id); } +#endif void session_handle::set_key(int key) { diff --git a/src/session_impl.cpp b/src/session_impl.cpp index ba3aa6816..d12df4698 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -533,8 +533,6 @@ namespace aux { #ifndef TORRENT_DISABLE_LOGGING session_log(" max connections: %d", m_settings.get_int(settings_pack::connections_limit)); session_log(" max files: %d", max_files); - - session_log(" generated peer ID: %s", m_peer_id.to_string().c_str()); #endif m_io_service.post(boost::bind(&session_impl::init, this)); @@ -2809,8 +2807,7 @@ retry: pack.peerinfo = 0; boost::shared_ptr c - = boost::make_shared(boost::cref(pack) - , get_peer_id()); + = boost::make_shared(boost::cref(pack)); #if TORRENT_USE_ASSERTS c->m_in_constructor = false; #endif @@ -2876,10 +2873,12 @@ retry: if (i != m_connections.end()) m_connections.erase(i); } - void session_impl::set_peer_id(peer_id const& id) +#ifndef TORRENT_NO_DEPRECATE + peer_id session_impl::deprecated_get_peer_id() const { - m_peer_id = id; + return generate_peer_id(m_settings); } +#endif void session_impl::set_key(int key) { @@ -5447,20 +5446,6 @@ retry: #endif } - void session_impl::update_peer_fingerprint() - { - // ---- generate a peer id ---- - std::string print = m_settings.get_str(settings_pack::peer_fingerprint); - if (print.size() > 20) print.resize(20); - - // the client's fingerprint - std::copy(print.begin(), print.begin() + print.length(), m_peer_id.begin()); - if (print.length() < 20) - { - url_random(m_peer_id.data() + print.length(), m_peer_id.data() + 20); - } - } - void session_impl::update_dht_bootstrap_nodes() { #ifndef TORRENT_DISABLE_DHT @@ -6493,7 +6478,6 @@ retry: } if (m_upnp) m_upnp->set_user_agent(""); - url_random(m_peer_id.data(), m_peer_id.data() + 20); } void session_impl::update_force_proxy() diff --git a/src/settings_pack.cpp b/src/settings_pack.cpp index 0b2a28ec9..e0a95b9e1 100644 --- a/src/settings_pack.cpp +++ b/src/settings_pack.cpp @@ -148,7 +148,7 @@ namespace libtorrent SET_NOPREV(proxy_username, "", &session_impl::update_proxy), SET_NOPREV(proxy_password, "", &session_impl::update_proxy), SET_NOPREV(i2p_hostname, "", &session_impl::update_i2p_bridge), - SET_NOPREV(peer_fingerprint, "-LT1160-", &session_impl::update_peer_fingerprint), + SET_NOPREV(peer_fingerprint, "-LT1160-", 0), SET_NOPREV(dht_bootstrap_nodes, "dht.libtorrent.org:25401", &session_impl::update_dht_bootstrap_nodes) }; diff --git a/src/torrent.cpp b/src/torrent.cpp index feacfa4e4..16407d659 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -162,6 +162,22 @@ namespace libtorrent restart_request.length = -1; } + peer_id generate_peer_id(aux::session_settings const& sett) + { + // ---- generate a peer id ---- + std::string print = sett.get_str(settings_pack::peer_fingerprint); + if (print.size() > 20) print.resize(20); + + // the client's fingerprint + peer_id ret; + std::copy(print.begin(), print.begin() + print.length(), ret.begin()); + if (print.length() < 20) + { + url_random(ret.data() + print.length(), ret.data() + 20); + } + return ret; + } + #ifndef TORRENT_DISABLE_EXTENSIONS // defined in ut_pex.cpp bool was_introduced_by(peer_plugin const*, tcp::endpoint const&); @@ -223,6 +239,7 @@ namespace libtorrent , m_sequence_number(seq) , m_peer_class(0) , m_num_connecting(0) + , m_peer_id(generate_peer_id(settings())) , m_upload_mode_time(0) , m_announce_to_trackers((p.flags & add_torrent_params::flag_paused) == 0) , m_announce_to_lsd((p.flags & add_torrent_params::flag_paused) == 0) @@ -2326,7 +2343,7 @@ namespace libtorrent return NULL; } - peer_connection* torrent::find_peer(sha1_hash const& pid) + peer_connection* torrent::find_peer(peer_id const& pid) { for (peer_iterator i = m_connections.begin(); i != m_connections.end(); ++i) { @@ -3174,7 +3191,7 @@ namespace { req.private_torrent = m_torrent_file->priv(); req.info_hash = m_torrent_file->info_hash(); - req.pid = m_ses.get_peer_id(); + req.pid = m_peer_id; req.downloaded = m_stat.total_payload_download() - m_total_failed_bytes; req.uploaded = m_stat.total_payload_upload(); req.corrupt = m_total_failed_bytes; @@ -3545,7 +3562,7 @@ namespace { i != resp.peers.end(); ++i) { // don't make connections to ourself - if (i->pid == m_ses.get_peer_id()) + if (i->pid == m_peer_id) continue; #if TORRENT_USE_I2P @@ -7856,7 +7873,7 @@ namespace { pack.peerinfo = peerinfo; boost::shared_ptr c = boost::make_shared( - boost::cref(pack), m_ses.get_peer_id()); + boost::cref(pack)); TORRENT_TRY { diff --git a/test/setup_transfer.cpp b/test/setup_transfer.cpp index 85c5894cc..e2fd77f9d 100644 --- a/test/setup_transfer.cpp +++ b/test/setup_transfer.cpp @@ -726,30 +726,13 @@ setup_transfer(lt::session* ses1, lt::session* ses2, lt::session* ses3 if (ses3) pack.set_bool(settings_pack::allow_multiple_connections_per_ip, true); pack.set_int(settings_pack::mixed_mode_algorithm, settings_pack::prefer_tcp); pack.set_int(settings_pack::max_failcount, 1); - peer_id pid; - std::generate(&pid[0], &pid[0] + 20, random_byte); - pack.set_str(settings_pack::peer_fingerprint, pid.to_string()); ses1->apply_settings(pack); - TORRENT_ASSERT(ses1->id() == pid); - - std::generate(&pid[0], &pid[0] + 20, random_byte); - TORRENT_ASSERT(ses1->id() != pid); - pack.set_str(settings_pack::peer_fingerprint, pid.to_string()); ses2->apply_settings(pack); - TORRENT_ASSERT(ses2->id() == pid); if (ses3) { - std::generate(&pid[0], &pid[0] + 20, random_byte); - TORRENT_ASSERT(ses1->id() != pid); - TORRENT_ASSERT(ses2->id() != pid); - pack.set_str(settings_pack::peer_fingerprint, pid.to_string()); ses3->apply_settings(pack); - TORRENT_ASSERT(ses3->id() == pid); } - TORRENT_ASSERT(ses1->id() != ses2->id()); - if (ses3) TORRENT_ASSERT(ses3->id() != ses2->id()); - boost::shared_ptr t; if (torrent == 0) { diff --git a/test/test_session.cpp b/test/test_session.cpp index ecb5f6e3b..e64c47a8d 100644 --- a/test/test_session.cpp +++ b/test/test_session.cpp @@ -314,10 +314,7 @@ TORRENT_TEST(save_state_peer_id) lt::settings_pack pack; pack.set_str(settings_pack::peer_fingerprint, "AAA"); lt::session ses(pack); - lt::peer_id const pid1 = ses.id(); - TEST_CHECK(pid1[0] == 'A'); - TEST_CHECK(pid1[1] == 'A'); - TEST_CHECK(pid1[2] == 'A'); + TEST_EQUAL(ses.get_settings().get_str(settings_pack::peer_fingerprint), "AAA"); lt::entry st; ses.save_state(st); @@ -325,14 +322,7 @@ TORRENT_TEST(save_state_peer_id) pack.set_str(settings_pack::peer_fingerprint, "foobar"); ses.apply_settings(pack); - lt::peer_id const pid2 = ses.id(); - TEST_CHECK(pid2[0] == 'f'); - TEST_CHECK(pid2[1] == 'o'); - TEST_CHECK(pid2[2] == 'o'); - TEST_CHECK(pid2[3] == 'b'); - TEST_CHECK(pid2[4] == 'a'); - TEST_CHECK(pid2[5] == 'r'); - + TEST_EQUAL(ses.get_settings().get_str(settings_pack::peer_fingerprint), "foobar"); std::vector buf; bencode(std::back_inserter(buf), st); @@ -343,13 +333,7 @@ TORRENT_TEST(save_state_peer_id) TEST_EQUAL(ret, 0); ses.load_state(state); - lt::peer_id const pid3 = ses.id(); - TEST_CHECK(pid3[0] == 'f'); - TEST_CHECK(pid3[1] == 'o'); - TEST_CHECK(pid3[2] == 'o'); - TEST_CHECK(pid3[3] == 'b'); - TEST_CHECK(pid3[4] == 'a'); - TEST_CHECK(pid3[5] == 'r'); + TEST_EQUAL(ses.get_settings().get_str(settings_pack::peer_fingerprint), "foobar"); } #endif