merged RC_1_1 into master

This commit is contained in:
arvidn 2017-05-21 21:02:09 -04:00
commit 680ca6ea2b
11 changed files with 107 additions and 12 deletions

View File

@ -186,7 +186,7 @@ if (NOT CMAKE_BUILD_TYPE)
endif()
# add_definitions() doesn't seem to let you say wich build type to apply it to
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DTORRENT_DEBUG")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DTORRENT_DEBUG")
if(UNIX)
set(CMAKE_C_FLAGS_RELWITHDEBINFO "-Os -g")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")

View File

@ -73,6 +73,8 @@
* require C++11 to build libtorrent
* fix python3 portability issue in python binding
* delay 5 seconds before reconnecting socks5 proxy for UDP ASSOCIATE
* fix NAT-PMP crash when removing a mapping at the wrong time
* improve path sanitization (filter unicode text direction characters)
* deprecate partial_piece_info::piece_state

View File

@ -8,6 +8,7 @@
#include <libtorrent/aux_/disable_warnings_push.hpp>
#include <iostream>
#include <boost/python.hpp>
#include <boost/python/stl_iterator.hpp>
#include <libtorrent/aux_/disable_warnings_pop.hpp>
// something in here creates a define for this, presumably to make older

View File

@ -131,12 +131,11 @@ struct dict_to_map
dict o(borrowed(x));
std::map<T1, T2> m;
list iterkeys = (list)o.keys();
int const len = int(boost::python::len(iterkeys));
for (int i = 0; i < len; i++)
stl_input_iterator<T1> i(o.keys()), end;
for (; i != end; ++i)
{
object key = iterkeys[i];
m[extract<T1>(key)] = extract<T2>(o[key]);
T1 const& key = *i;
m[key] = extract<T2>(o[key]);
}
new (storage) std::map<T1, T2>(m);
data->convertible = storage;

View File

@ -108,11 +108,10 @@ namespace
void make_settings_pack(lt::settings_pack& p, dict const& sett_dict)
{
list iterkeys = (list)sett_dict.keys();
int const len = int(boost::python::len(iterkeys));
for (int i = 0; i < len; i++)
stl_input_iterator<std::string> i(sett_dict.keys()), end;
for (; i != end; ++i)
{
std::string const key = extract<std::string>(iterkeys[i]);
std::string const key = *i;
int sett = setting_by_name(key);
if (sett < 0)

View File

@ -208,6 +208,21 @@ namespace libtorrent {
bool is_not_thread() const {return true; }
};
#endif
#if TORRENT_USE_ASSERTS
struct increment_guard
{
int& m_cnt;
increment_guard(int& c) : m_cnt(c) { TORRENT_ASSERT(m_cnt >= 0); ++m_cnt; }
~increment_guard() { --m_cnt; TORRENT_ASSERT(m_cnt >= 0); }
private:
increment_guard(increment_guard const&);
increment_guard operator=(increment_guard const&);
};
#define TORRENT_INCREMENT(x) increment_guard inc_(x)
#else
#define TORRENT_INCREMENT(x) do {} while (false)
#endif
}
#endif // TORRENT_DEBUG_HPP_INCLUDED

View File

@ -1660,6 +1660,10 @@ namespace libtorrent {
// set to true when torrent is start()ed. It may only be started once
bool m_was_started = false;
bool m_outstanding_check_files = false;
// this is set to true while we're looping over m_connections. We may not
// mutate the list while doing this
mutable int m_iterating_connections = 0;
#endif
};
}

@ -1 +1 @@
Subproject commit 70feadef80dc76ae6d5e7c2f92334377d698dd7d
Subproject commit 96e8e2414df955c04b37b6bccd2b7360a54ff2f1

View File

@ -246,3 +246,40 @@ TORRENT_TEST(udp_tracker)
TEST_CHECK(announced);
}
TORRENT_TEST(socks5_udp_retry)
{
// this test is asserting that when a UDP associate command fails, we have a
// 5 second delay before we try again. There is no need to actually add a
// torrent for this test, just to open the udp socket with a socks5 proxy
using namespace libtorrent;
// setup the simulation
sim::default_config network_cfg;
sim::simulation sim{network_cfg};
std::unique_ptr<sim::asio::io_service> ios = make_io_service(sim, 0);
lt::session_proxy zombie;
sim::asio::io_service proxy_ios{sim, addr("50.50.50.50") };
// close UDP associate connectons prematurely
sim::socks_server socks5(proxy_ios, 5555, 5, socks_flag::disconnect_udp_associate);
lt::settings_pack pack = settings();
pack.set_str(settings_pack::listen_interfaces, "50.50.50.50:6881");
// create session
std::shared_ptr<lt::session> ses = std::make_shared<lt::session>(pack, *ios);
set_proxy(*ses, settings_pack::socks5);
// run for 60 seconds.The sokcks5 retry interval is expected to be 5 seconds,
// meaning there should have been 12 connection attempts
sim::timer t(sim, lt::seconds(60), [&](boost::system::error_code const& ec)
{
fprintf(stderr, "shutting down\n");
// shut down
zombie = ses->abort();
ses.reset();
});
sim.run();
// number of UDP ASSOCIATE commands invoked on the socks proxy
TEST_EQUAL(socks5.cmd_counts()[2], 12);
}

View File

@ -867,6 +867,7 @@ namespace libtorrent {
#ifndef TORRENT_DISABLE_EXTENSIONS
for (auto const pc : m_connections)
{
TORRENT_INCREMENT(m_iterating_connections);
if (pc->type() != connection_type::bittorrent) continue;
bt_peer_connection* p = static_cast<bt_peer_connection*>(pc);
p->write_share_mode();
@ -882,6 +883,7 @@ namespace libtorrent {
for (auto p : m_connections)
{
TORRENT_INCREMENT(m_iterating_connections);
if (p->type() != connection_type::bittorrent)
continue;
@ -937,6 +939,7 @@ namespace libtorrent {
// clear request queues of all peers
for (auto p : m_connections)
{
TORRENT_INCREMENT(m_iterating_connections);
// we may want to disconnect other upload-only peers
if (p->upload_only())
p->update_interest();
@ -956,6 +959,7 @@ namespace libtorrent {
// send_block_requests on all peers
for (auto p : m_connections)
{
TORRENT_INCREMENT(m_iterating_connections);
// we may be interested now, or no longer interested
p->update_interest();
p->send_block_requests();
@ -1185,6 +1189,7 @@ namespace libtorrent {
for (auto p : m_connections)
{
TORRENT_INCREMENT(m_iterating_connections);
peer_has(p->get_bitfield(), p);
}
}
@ -1357,6 +1362,7 @@ namespace libtorrent {
for (auto p : m_connections)
{
TORRENT_INCREMENT(m_iterating_connections);
std::shared_ptr<peer_plugin> pp(tp->new_connection(peer_connection_handle(p->self())));
if (pp) p->add_extension(std::move(pp));
}
@ -1871,6 +1877,7 @@ namespace libtorrent {
#ifndef TORRENT_DISABLE_EXTENSIONS
for (auto pe : m_connections)
{
TORRENT_INCREMENT(m_iterating_connections);
if (pe->type() != connection_type::bittorrent) continue;
bt_peer_connection* p = static_cast<bt_peer_connection*>(pe);
if (!p->supports_holepunch()) continue;
@ -1886,6 +1893,7 @@ namespace libtorrent {
{
for (auto p : m_connections)
{
TORRENT_INCREMENT(m_iterating_connections);
if (p->type() != connection_type::bittorrent) continue;
if (p->remote() == ep) return static_cast<bt_peer_connection*>(p);
}
@ -3820,6 +3828,7 @@ namespace libtorrent {
// invalidate the iterator
for (auto p : m_connections)
{
TORRENT_INCREMENT(m_iterating_connections);
// if we're not interested already, no need to check
if (!p->is_interesting()) continue;
// if the peer doesn't have the piece we just got, it
@ -3956,6 +3965,7 @@ namespace libtorrent {
for (auto p : m_connections)
{
TORRENT_INCREMENT(m_iterating_connections);
#ifndef TORRENT_DISABLE_LOGGING
p->peer_log(peer_log_alert::outgoing, "PREDICTIVE_HAVE", "piece: %d expected in %d ms"
, static_cast<int>(index), milliseconds);
@ -3993,6 +4003,7 @@ namespace libtorrent {
{
for (auto p : m_connections)
{
TORRENT_INCREMENT(m_iterating_connections);
// send reject messages for
// potential outstanding requests to this piece
p->reject_piece(index);
@ -4186,6 +4197,7 @@ namespace libtorrent {
// blocks to this piece
for (auto p : m_connections)
{
TORRENT_INCREMENT(m_iterating_connections);
for (auto const& b : p->download_queue())
{
if (b.timed_out || b.not_wanted) continue;
@ -4518,6 +4530,7 @@ namespace libtorrent {
for (auto p : m_connections)
{
TORRENT_INCREMENT(m_iterating_connections);
// for each peer, go through its download and request queue
// and cancel everything, except pieces that are time critical
@ -5210,6 +5223,7 @@ namespace libtorrent {
for (auto p : m_connections)
{
TORRENT_INCREMENT(m_iterating_connections);
p->cancel_request(block);
}
}
@ -5922,6 +5936,7 @@ namespace libtorrent {
TORRENT_ASSERT(!c->m_in_constructor);
// add the newly connected peer to this torrent's peer list
TORRENT_ASSERT(m_iterating_connections == 0);
sorted_insert(m_connections, c.get());
update_want_peers();
update_want_tick();
@ -6515,6 +6530,7 @@ namespace libtorrent {
#endif
// add the newly connected peer to this torrent's peer list
TORRENT_ASSERT(m_iterating_connections == 0);
sorted_insert(m_connections, c.get());
m_ses.insert_peer(c);
need_peer_list();
@ -6532,6 +6548,7 @@ namespace libtorrent {
}
TORRENT_CATCH (std::exception const&)
{
TORRENT_ASSERT(m_iterating_connections == 0);
c->disconnect(errors::no_error, op_bittorrent, 1);
return false;
}
@ -6802,6 +6819,7 @@ namespace libtorrent {
peers_erased(st.erased);
TORRENT_ASSERT(sorted_find(m_connections, p) == m_connections.end());
TORRENT_ASSERT(m_iterating_connections == 0);
sorted_insert(m_connections, p);
update_want_peers();
update_want_tick();
@ -7056,8 +7074,10 @@ namespace libtorrent {
void torrent::disconnect_all(error_code const& ec, operation_t op)
{
TORRENT_ASSERT(m_iterating_connections == 0);
for (auto const& p : m_connections)
{
TORRENT_INCREMENT(m_iterating_connections);
TORRENT_ASSERT(p->associated_torrent().lock().get() == this);
p->disconnect(ec, op);
}
@ -7116,7 +7136,10 @@ namespace libtorrent {
#if TORRENT_USE_ASSERTS
// make sure we don't have any dangling pointers
for (auto p : m_connections)
{
TORRENT_INCREMENT(m_iterating_connections);
TORRENT_ASSERT(m_ses.has_peer(p));
}
#endif
aux::vector<peer_connection*> to_disconnect;
to_disconnect.resize(num);
@ -7165,6 +7188,7 @@ namespace libtorrent {
std::vector<peer_connection*> seeds;
for (auto const p : m_connections)
{
TORRENT_INCREMENT(m_iterating_connections);
TORRENT_ASSERT(p->associated_torrent().lock().get() == this);
if (p->upload_only())
{
@ -7400,6 +7424,7 @@ namespace libtorrent {
for (auto pc : m_connections)
{
TORRENT_INCREMENT(m_iterating_connections);
// all peer connections have to initialize themselves now that the metadata
// is available
if (notify_initialized)
@ -8414,6 +8439,7 @@ namespace libtorrent {
// requests
for (peer_connection* p : m_connections)
{
TORRENT_INCREMENT(m_iterating_connections);
TORRENT_ASSERT(p->associated_torrent().lock().get() == this);
if (p->is_disconnecting()) continue;
@ -9075,6 +9101,7 @@ namespace libtorrent {
int num_interested = 0;
for (auto const p : m_connections)
{
TORRENT_INCREMENT(m_iterating_connections);
if (p->is_connecting()) continue;
if (p->is_disconnecting()) continue;
++num_peers;

View File

@ -64,6 +64,7 @@ struct socks5 : std::enable_shared_from_this<socks5>
: m_socks5_sock(ios)
, m_resolver(ios)
, m_timer(ios)
, m_retry_timer(ios)
, m_abort(false)
, m_active(false)
{
@ -91,10 +92,12 @@ private:
void connect1(error_code const& e);
void connect2(error_code const& e);
void hung_up(error_code const& e);
void retry_socks_connect(error_code const& e);
tcp::socket m_socks5_sock;
tcp::resolver m_resolver;
deadline_timer m_timer;
deadline_timer m_retry_timer;
char m_tmp_buf[270];
aux::proxy_settings m_proxy_settings;
@ -738,7 +741,15 @@ void socks5::hung_up(error_code const& e)
if (e == boost::asio::error::operation_aborted || m_abort) return;
// the socks connection was closed, re-open it
// the socks connection was closed, re-open it in a bit
m_retry_timer.expires_from_now(seconds(5));
m_retry_timer.async_wait(std::bind(&socks5::retry_socks_connect
, self(), _1));
}
void socks5::retry_socks_connect(error_code const& e)
{
if (e) return;
start(m_proxy_settings);
}