From 9ca12d6db589035056a087762aebce5c17633420 Mon Sep 17 00:00:00 2001 From: arvidn Date: Fri, 11 May 2018 22:34:36 +0200 Subject: [PATCH 1/2] restore aspects of the previous behavior of force-proxy. Instead of not opening any TCP listen sockets at all, open them but reject any incoming connection. This is because in RC_1_1, the UDP and TCP sockets are tied in subtle and unintuitive ways. This is much cleaner in the next major release and this patch will not need to be merged --- ChangeLog | 1 + simulation/test_session.cpp | 7 ++++--- src/session_impl.cpp | 21 +++++++-------------- 3 files changed, 12 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index b79799968..6a522a5e6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,5 @@ + * fix recent regression with force_proxy setting * don't perform DNS lookups for the DHT bootstrap unless DHT is enabled * fix issue where setting file/piece priority would stop checking * expose post_dht_stats() to python binding diff --git a/simulation/test_session.cpp b/simulation/test_session.cpp index df6cfe8bf..efcf42026 100644 --- a/simulation/test_session.cpp +++ b/simulation/test_session.cpp @@ -79,8 +79,9 @@ TORRENT_TEST(force_proxy) // create session std::shared_ptr ses = std::make_shared(pack, *ios); - // disable force proxy in 3 seconds (this should make us open up listen - // sockets) + // disable force proxy in 3 seconds. this won't make us open up listen + // sockets, since force proxy rejects incoming connections, it doesn't + // prevent the listen sockets from opening sim::timer t1(sim, lt::seconds(3), [&](boost::system::error_code const& ec) { lt::settings_pack p; @@ -111,6 +112,6 @@ TORRENT_TEST(force_proxy) sim.run(); TEST_EQUAL(num_listen_tcp, 1); - TEST_EQUAL(num_listen_udp, 2); + TEST_EQUAL(num_listen_udp, 1); } diff --git a/src/session_impl.cpp b/src/session_impl.cpp index b54a5eb18..5ce9c9b5b 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -1660,9 +1660,6 @@ namespace aux { (pack.has_val(settings_pack::ssl_listen) && pack.get_int(settings_pack::ssl_listen) != m_settings.get_int(settings_pack::ssl_listen)) - || (pack.has_val(settings_pack::force_proxy) - && !pack.get_bool(settings_pack::force_proxy) - && m_settings.get_bool(settings_pack::force_proxy)) || (pack.has_val(settings_pack::listen_interfaces) && pack.get_str(settings_pack::listen_interfaces) != m_settings.get_str(settings_pack::listen_interfaces)); @@ -1880,8 +1877,7 @@ retry: // TODO: instead of having a special case for this, just make the // default listen interfaces be "0.0.0.0:6881,[::]:6881" and use // the generic path. That would even allow for not listening at all. - if (m_listen_interfaces.empty() - && !m_settings.get_bool(settings_pack::force_proxy)) + if (m_listen_interfaces.empty()) { // this means we should open two listen sockets // one for IPv4 and one for IPv6 @@ -1948,7 +1944,7 @@ retry: #endif // TORRENT_USE_IPV6 } - else if (!m_settings.get_bool(settings_pack::force_proxy)) + else { // TODO: 2 the udp socket(s) should be using the same generic // mechanism and not be restricted to a single one @@ -1957,7 +1953,7 @@ retry: for (int i = 0; i < m_listen_interfaces.size(); ++i) { std::string const& device = m_listen_interfaces[i].first; - int port = m_listen_interfaces[i].second; + int const port = m_listen_interfaces[i].second; int num_device_fails = 0; @@ -2005,7 +2001,6 @@ retry: #endif m_ipv4_interface = bind_ep; } - #ifdef TORRENT_USE_OPENSSL if (m_settings.get_int(settings_pack::ssl_listen)) { @@ -2517,6 +2512,10 @@ retry: } async_accept(listener, ssl); + // don't accept any connections from our local sockets + if (m_settings.get_bool(settings_pack::force_proxy)) + return; + #ifdef TORRENT_USE_OPENSSL if (ssl) { @@ -6532,12 +6531,6 @@ retry: #ifndef TORRENT_DISABLE_DHT stop_dht(); #endif - // close the listen sockets - error_code ec; - for (std::list::iterator i = m_listen_sockets.begin() - , end(m_listen_sockets.end()); i != end; ++i) - i->sock->close(ec); - m_listen_sockets.clear(); } #ifndef TORRENT_NO_DEPRECATE From 243353a14482b37dc84bd1abfff40049f5d18b18 Mon Sep 17 00:00:00 2001 From: Steven Siloti Date: Sat, 12 May 2018 19:12:51 -0700 Subject: [PATCH 2/2] account for partially downloaded pieces when announcing as a seed --- ChangeLog | 1 + src/torrent.cpp | 26 +++++++++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 6a522a5e6..6b5bdd743 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,7 @@ * fix backwards compatibility to downloads without partfiles * improve part-file related error messages * fix reporting &redundant= in tracker announces + * fix tracker announces reporting more data downloaded than the size of the torrent * fix tie-break in duplicate peer connection disconnect logic * fix issue with SSL tracker connections left in CLOSE_WAIT state * defer truncating existing files until the first time we write to them diff --git a/src/torrent.cpp b/src/torrent.cpp index 075bbeb52..fee1f047b 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -3223,10 +3223,34 @@ namespace { req.ssl_ctx = m_ssl_ctx.get(); #endif + req.redundant = m_total_redundant_bytes; // exclude redundant bytes if we should if (!settings().get_bool(settings_pack::report_true_downloaded)) + { req.downloaded -= m_total_redundant_bytes; - req.redundant = m_total_redundant_bytes; + + // if the torrent is complete we know that all incoming pieces will be + // marked redundant so add them to the redundant count + // this is mainly needed to cover the case where a torrent has just completed + // but still has partially downloaded pieces + // if the incoming pieces are not accounted for it could cause the downloaded + // amount to exceed the total size of the torrent which upsets some trackers + if (is_seed()) + { + for (peer_iterator i = m_connections.begin(); + i != m_connections.end(); ++i) + { + TORRENT_INCREMENT(m_iterating_connections); + peer_connection* p = *i; + boost::optional pbp = p->downloading_piece_progress(); + if (pbp && pbp->bytes_downloaded > 0) + { + req.downloaded -= pbp->bytes_downloaded; + req.redundant += pbp->bytes_downloaded; + } + } + } + } if (req.downloaded < 0) req.downloaded = 0; req.event = e;