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() endif()
# add_definitions() doesn't seem to let you say wich build type to apply it to # 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) if(UNIX)
set(CMAKE_C_FLAGS_RELWITHDEBINFO "-Os -g") set(CMAKE_C_FLAGS_RELWITHDEBINFO "-Os -g")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")

View File

@ -73,6 +73,8 @@
* require C++11 to build libtorrent * 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 * fix NAT-PMP crash when removing a mapping at the wrong time
* improve path sanitization (filter unicode text direction characters) * improve path sanitization (filter unicode text direction characters)
* deprecate partial_piece_info::piece_state * deprecate partial_piece_info::piece_state

View File

@ -8,6 +8,7 @@
#include <libtorrent/aux_/disable_warnings_push.hpp> #include <libtorrent/aux_/disable_warnings_push.hpp>
#include <iostream> #include <iostream>
#include <boost/python.hpp> #include <boost/python.hpp>
#include <boost/python/stl_iterator.hpp>
#include <libtorrent/aux_/disable_warnings_pop.hpp> #include <libtorrent/aux_/disable_warnings_pop.hpp>
// something in here creates a define for this, presumably to make older // 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)); dict o(borrowed(x));
std::map<T1, T2> m; std::map<T1, T2> m;
list iterkeys = (list)o.keys(); stl_input_iterator<T1> i(o.keys()), end;
int const len = int(boost::python::len(iterkeys)); for (; i != end; ++i)
for (int i = 0; i < len; i++)
{ {
object key = iterkeys[i]; T1 const& key = *i;
m[extract<T1>(key)] = extract<T2>(o[key]); m[key] = extract<T2>(o[key]);
} }
new (storage) std::map<T1, T2>(m); new (storage) std::map<T1, T2>(m);
data->convertible = storage; data->convertible = storage;

View File

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

View File

@ -208,6 +208,21 @@ namespace libtorrent {
bool is_not_thread() const {return true; } bool is_not_thread() const {return true; }
}; };
#endif #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 #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 // set to true when torrent is start()ed. It may only be started once
bool m_was_started = false; bool m_was_started = false;
bool m_outstanding_check_files = 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 #endif
}; };
} }

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

View File

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

View File

@ -64,6 +64,7 @@ struct socks5 : std::enable_shared_from_this<socks5>
: m_socks5_sock(ios) : m_socks5_sock(ios)
, m_resolver(ios) , m_resolver(ios)
, m_timer(ios) , m_timer(ios)
, m_retry_timer(ios)
, m_abort(false) , m_abort(false)
, m_active(false) , m_active(false)
{ {
@ -91,10 +92,12 @@ private:
void connect1(error_code const& e); void connect1(error_code const& e);
void connect2(error_code const& e); void connect2(error_code const& e);
void hung_up(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::socket m_socks5_sock;
tcp::resolver m_resolver; tcp::resolver m_resolver;
deadline_timer m_timer; deadline_timer m_timer;
deadline_timer m_retry_timer;
char m_tmp_buf[270]; char m_tmp_buf[270];
aux::proxy_settings m_proxy_settings; 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; 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); start(m_proxy_settings);
} }