forked from premiere/premiere-libtorrent
add new socks5_alert to trouble shoot SOCKS5 proxies
This commit is contained in:
parent
b5bf6c3260
commit
0675bd263f
|
@ -1,3 +1,5 @@
|
|||
* add new socks5_alert to trouble shoot SOCKS5 proxies
|
||||
|
||||
1.2.3 release
|
||||
|
||||
* fix erroneous event=completed tracker announce when checking files
|
||||
|
|
|
@ -236,6 +236,7 @@ namespace boost
|
|||
POLY(block_uploaded_alert)
|
||||
POLY(alerts_dropped_alert)
|
||||
POLY(session_stats_alert)
|
||||
POLY(socks5_alert)
|
||||
|
||||
#if TORRENT_ABI_VERSION == 1
|
||||
POLY(anonymous_mode_alert)
|
||||
|
@ -1029,6 +1030,13 @@ void bind_alert()
|
|||
.add_property("dropped_alerts", &get_dropped_alerts)
|
||||
;
|
||||
|
||||
class_<socks5_alert, bases<alert>, noncopyable>(
|
||||
"socks5_alert", no_init)
|
||||
.def_readonly("error", &socks5_alert::error)
|
||||
.def_readonly("op", &socks5_alert::op)
|
||||
.add_property("ip", make_getter(&socks5_alert::ip, by_value()))
|
||||
;
|
||||
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
|
|
@ -83,7 +83,7 @@ namespace libtorrent {
|
|||
constexpr int user_alert_id = 10000;
|
||||
|
||||
// this constant represents "max_alert_index" + 1
|
||||
constexpr int num_alert_types = 96;
|
||||
constexpr int num_alert_types = 97;
|
||||
|
||||
// internal
|
||||
enum alert_priority
|
||||
|
@ -2947,6 +2947,28 @@ TORRENT_VERSION_NAMESPACE_2
|
|||
std::bitset<num_alert_types> dropped_alerts;
|
||||
};
|
||||
|
||||
// this alert is posted with SOCKS5 related errors, when a SOCKS5 proxy is
|
||||
// configured. It's enabled with the error_notification alert category.
|
||||
struct TORRENT_EXPORT socks5_alert final : alert
|
||||
{
|
||||
// internal
|
||||
explicit socks5_alert(aux::stack_allocator& alloc
|
||||
, tcp::endpoint const& ep, operation_t operation, error_code const& ec);
|
||||
TORRENT_DEFINE_ALERT(socks5_alert, 96)
|
||||
|
||||
static constexpr alert_category_t static_category = alert::error_notification;
|
||||
std::string message() const override;
|
||||
|
||||
// the error
|
||||
error_code error;
|
||||
|
||||
// the operation that failed
|
||||
operation_t op;
|
||||
|
||||
// the endpoint configured as the proxy
|
||||
aux::noexcept_movable<tcp::endpoint> ip;
|
||||
};
|
||||
|
||||
TORRENT_VERSION_NAMESPACE_2_END
|
||||
|
||||
#undef TORRENT_DEFINE_ALERT_IMPL
|
||||
|
|
|
@ -39,7 +39,11 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <boost/asio/io_service.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace libtorrent { namespace aux {
|
||||
namespace libtorrent {
|
||||
|
||||
class alert_manager;
|
||||
|
||||
namespace aux {
|
||||
|
||||
struct listen_endpoint_t;
|
||||
struct proxy_settings;
|
||||
|
@ -92,7 +96,7 @@ namespace libtorrent { namespace aux {
|
|||
tcp::endpoint bind(socket_type& s, address const& remote_address
|
||||
, error_code& ec) const;
|
||||
|
||||
void update_proxy(proxy_settings const& settings);
|
||||
void update_proxy(proxy_settings const& settings, alert_manager& alerts);
|
||||
|
||||
// close all sockets
|
||||
void close();
|
||||
|
|
|
@ -139,6 +139,7 @@ struct session_stats_header_alert;
|
|||
struct dht_sample_infohashes_alert;
|
||||
struct block_uploaded_alert;
|
||||
struct alerts_dropped_alert;
|
||||
struct socks5_alert;
|
||||
TORRENT_VERSION_NAMESPACE_2_END
|
||||
|
||||
// include/libtorrent/announce_entry.hpp
|
||||
|
@ -280,6 +281,9 @@ TORRENT_VERSION_NAMESPACE_2_END
|
|||
// include/libtorrent/file_storage.hpp
|
||||
struct file_entry;
|
||||
|
||||
// include/libtorrent/fingerprint.hpp
|
||||
struct fingerprint;
|
||||
|
||||
// include/libtorrent/lazy_entry.hpp
|
||||
struct pascal_string;
|
||||
struct lazy_entry;
|
||||
|
|
|
@ -166,10 +166,13 @@ namespace libtorrent {
|
|||
|
||||
// create or read a symlink
|
||||
symlink,
|
||||
|
||||
// handshake with a peer or server
|
||||
handshake,
|
||||
};
|
||||
|
||||
// maps an operation id (from peer_error_alert and peer_disconnected_alert)
|
||||
// to its name. See peer_connection for the constants
|
||||
// to its name. See operation_t for the constants
|
||||
TORRENT_EXPORT char const* operation_name(operation_t op);
|
||||
|
||||
#if TORRENT_ABI_VERSION == 1
|
||||
|
|
|
@ -46,6 +46,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
namespace libtorrent {
|
||||
|
||||
class alert_manager;
|
||||
struct socks5;
|
||||
|
||||
using udp_send_flags_t = flags::bitfield_flag<std::uint8_t, struct udp_send_flags_tag>;
|
||||
|
@ -95,7 +96,7 @@ namespace libtorrent {
|
|||
void close();
|
||||
int local_port() const { return m_bind_port; }
|
||||
|
||||
void set_proxy_settings(aux::proxy_settings const& ps);
|
||||
void set_proxy_settings(aux::proxy_settings const& ps, alert_manager& alerts);
|
||||
aux::proxy_settings const& get_proxy_settings() { return m_proxy_settings; }
|
||||
|
||||
bool is_closed() const { return m_abort; }
|
||||
|
|
|
@ -895,6 +895,7 @@ namespace {
|
|||
case o::partfile_write: return -1;
|
||||
case o::hostname_lookup: return -1;
|
||||
case o::symlink: return -1;
|
||||
case o::handshake: return -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
@ -1560,7 +1561,8 @@ namespace {
|
|||
"partfile_read",
|
||||
"partfile_write",
|
||||
"hostname_lookup",
|
||||
"symlink"
|
||||
"symlink",
|
||||
"handshake"
|
||||
};
|
||||
|
||||
int const idx = static_cast<int>(op);
|
||||
|
@ -2582,7 +2584,7 @@ namespace {
|
|||
"dht_pkt", "dht_get_peers_reply", "dht_direct_response",
|
||||
"picker_log", "session_error", "dht_live_nodes",
|
||||
"session_stats_header", "dht_sample_infohashes",
|
||||
"block_uploaded", "alerts_dropped"
|
||||
"block_uploaded", "alerts_dropped", "socks5"
|
||||
}};
|
||||
|
||||
TORRENT_ASSERT(alert_type >= 0);
|
||||
|
@ -2605,6 +2607,21 @@ namespace {
|
|||
return ret;
|
||||
}
|
||||
|
||||
socks5_alert::socks5_alert(aux::stack_allocator&
|
||||
, tcp::endpoint const& ep, operation_t operation, error_code const& ec)
|
||||
: error(ec)
|
||||
, op(operation)
|
||||
, ip(ep)
|
||||
{}
|
||||
|
||||
std::string socks5_alert::message() const
|
||||
{
|
||||
char buf[512];
|
||||
std::snprintf(buf, sizeof(buf), "SOCKS5 error. op: %s ec: %s ep: %s"
|
||||
, operation_name(op), error.message().c_str(), print_endpoint(ip).c_str());
|
||||
return buf;
|
||||
}
|
||||
|
||||
// this will no longer be necessary in C++17
|
||||
constexpr alert_category_t torrent_removed_alert::static_category;
|
||||
constexpr alert_category_t read_piece_alert::static_category;
|
||||
|
@ -2693,6 +2710,7 @@ namespace {
|
|||
constexpr alert_category_t dht_sample_infohashes_alert::static_category;
|
||||
constexpr alert_category_t block_uploaded_alert::static_category;
|
||||
constexpr alert_category_t alerts_dropped_alert::static_category;
|
||||
constexpr alert_category_t socks5_alert::static_category;
|
||||
#if TORRENT_ABI_VERSION == 1
|
||||
constexpr alert_category_t anonymous_mode_alert::static_category;
|
||||
constexpr alert_category_t mmap_cache_alert::static_category;
|
||||
|
|
|
@ -1665,7 +1665,7 @@ namespace aux {
|
|||
// change after the session is up and listening, at no other point
|
||||
// set_proxy_settings is called with the correct proxy configuration,
|
||||
// internally, this method handle the SOCKS5's connection logic
|
||||
ret->udp_sock->sock.set_proxy_settings(proxy());
|
||||
ret->udp_sock->sock.set_proxy_settings(proxy(), m_alerts);
|
||||
|
||||
ADD_OUTSTANDING_ASYNC("session_impl::on_udp_packet");
|
||||
ret->udp_sock->sock.async_read(aux::make_handler(std::bind(&session_impl::on_udp_packet
|
||||
|
@ -2100,7 +2100,7 @@ namespace aux {
|
|||
// change after the session is up and listening, at no other point
|
||||
// set_proxy_settings is called with the correct proxy configuration,
|
||||
// internally, this method handle the SOCKS5's connection logic
|
||||
udp_sock->sock.set_proxy_settings(proxy());
|
||||
udp_sock->sock.set_proxy_settings(proxy(), m_alerts);
|
||||
|
||||
ADD_OUTSTANDING_ASYNC("session_impl::on_udp_packet");
|
||||
udp_sock->sock.async_read(aux::make_handler(std::bind(&session_impl::on_udp_packet
|
||||
|
@ -5286,8 +5286,8 @@ namespace aux {
|
|||
void session_impl::update_proxy()
|
||||
{
|
||||
for (auto& i : m_listen_sockets)
|
||||
i->udp_sock->sock.set_proxy_settings(proxy());
|
||||
m_outgoing_sockets.update_proxy(proxy());
|
||||
i->udp_sock->sock.set_proxy_settings(proxy(), m_alerts);
|
||||
m_outgoing_sockets.update_proxy(proxy(), m_alerts);
|
||||
}
|
||||
|
||||
void session_impl::update_ip_notifier()
|
||||
|
|
|
@ -108,10 +108,10 @@ namespace libtorrent { namespace aux {
|
|||
return tcp::endpoint();
|
||||
}
|
||||
|
||||
void outgoing_sockets::update_proxy(proxy_settings const& settings)
|
||||
void outgoing_sockets::update_proxy(proxy_settings const& settings, alert_manager& alerts)
|
||||
{
|
||||
for (auto const& i : sockets)
|
||||
i->sock.set_proxy_settings(settings);
|
||||
i->sock.set_proxy_settings(settings, alerts);
|
||||
}
|
||||
|
||||
void outgoing_sockets::close()
|
||||
|
|
|
@ -40,6 +40,8 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/deadline_timer.hpp"
|
||||
#include "libtorrent/aux_/numeric_cast.hpp"
|
||||
#include "libtorrent/broadcast_socket.hpp" // for is_v4
|
||||
#include "libtorrent/alert_manager.hpp"
|
||||
#include "libtorrent/socks5_stream.hpp" // for socks_error
|
||||
|
||||
#include <cstdlib>
|
||||
#include <functional>
|
||||
|
@ -67,11 +69,12 @@ std::size_t const max_header_size = 255;
|
|||
// the common case cheaper by not allocating this space unconditionally
|
||||
struct socks5 : std::enable_shared_from_this<socks5>
|
||||
{
|
||||
explicit socks5(io_service& ios)
|
||||
explicit socks5(io_service& ios, alert_manager& alerts)
|
||||
: m_socks5_sock(ios)
|
||||
, m_resolver(ios)
|
||||
, m_timer(ios)
|
||||
, m_retry_timer(ios)
|
||||
, m_alerts(alerts)
|
||||
, m_abort(false)
|
||||
, m_active(false)
|
||||
{}
|
||||
|
@ -103,6 +106,7 @@ private:
|
|||
tcp::resolver m_resolver;
|
||||
deadline_timer m_timer;
|
||||
deadline_timer m_retry_timer;
|
||||
alert_manager& m_alerts;
|
||||
std::array<char, tmp_buffer_size> m_tmp_buf;
|
||||
|
||||
aux::proxy_settings m_proxy_settings;
|
||||
|
@ -111,7 +115,7 @@ private:
|
|||
// when performing a UDP associate, we get another
|
||||
// endpoint (presumably on the same IP) where we're
|
||||
// supposed to send UDP packets.
|
||||
udp::endpoint m_proxy_addr;
|
||||
tcp::endpoint m_proxy_addr;
|
||||
|
||||
// this is where UDP packets that are to be forwarded
|
||||
// are sent. The result from UDP ASSOCIATE is stored
|
||||
|
@ -472,7 +476,8 @@ void udp_socket::bind(udp::endpoint const& ep, error_code& ec)
|
|||
if (err) m_bind_port = ep.port();
|
||||
}
|
||||
|
||||
void udp_socket::set_proxy_settings(aux::proxy_settings const& ps)
|
||||
void udp_socket::set_proxy_settings(aux::proxy_settings const& ps
|
||||
, alert_manager& alerts)
|
||||
{
|
||||
TORRENT_ASSERT(is_single_thread());
|
||||
|
||||
|
@ -490,8 +495,7 @@ void udp_socket::set_proxy_settings(aux::proxy_settings const& ps)
|
|||
|| ps.type == settings_pack::socks5_pw)
|
||||
{
|
||||
// connect to socks5 server and open up the UDP tunnel
|
||||
|
||||
m_socks5_connection = std::make_shared<socks5>(lt::get_io_service(m_socket));
|
||||
m_socks5_connection = std::make_shared<socks5>(lt::get_io_service(m_socket), alerts);
|
||||
m_socks5_connection->start(ps);
|
||||
}
|
||||
}
|
||||
|
@ -517,10 +521,14 @@ void socks5::on_name_lookup(error_code const& e, tcp::resolver::iterator i)
|
|||
|
||||
if (e == boost::asio::error::operation_aborted) return;
|
||||
|
||||
if (e) return;
|
||||
if (e)
|
||||
{
|
||||
if (m_alerts.should_post<socks5_alert>())
|
||||
m_alerts.emplace_alert<socks5_alert>(m_proxy_addr, operation_t::hostname_lookup, e);
|
||||
return;
|
||||
}
|
||||
|
||||
m_proxy_addr.address(i->endpoint().address());
|
||||
m_proxy_addr.port(i->endpoint().port());
|
||||
m_proxy_addr = i->endpoint();
|
||||
|
||||
error_code ec;
|
||||
m_socks5_sock.open(is_v4(m_proxy_addr) ? tcp::v4() : tcp::v6(), ec);
|
||||
|
@ -529,7 +537,7 @@ void socks5::on_name_lookup(error_code const& e, tcp::resolver::iterator i)
|
|||
m_socks5_sock.set_option(boost::asio::socket_base::keep_alive(true), ec);
|
||||
|
||||
ADD_OUTSTANDING_ASYNC("socks5::on_connected");
|
||||
m_socks5_sock.async_connect(tcp::endpoint(m_proxy_addr.address(), m_proxy_addr.port())
|
||||
m_socks5_sock.async_connect(m_proxy_addr
|
||||
, std::bind(&socks5::on_connected, self(), _1));
|
||||
|
||||
ADD_OUTSTANDING_ASYNC("socks5::on_connect_timeout");
|
||||
|
@ -546,6 +554,9 @@ void socks5::on_connect_timeout(error_code const& e)
|
|||
|
||||
if (m_abort) return;
|
||||
|
||||
if (m_alerts.should_post<socks5_alert>())
|
||||
m_alerts.emplace_alert<socks5_alert>(m_proxy_addr, operation_t::connect, errors::timed_out);
|
||||
|
||||
error_code ignore;
|
||||
m_socks5_sock.close(ignore);
|
||||
}
|
||||
|
@ -561,7 +572,12 @@ void socks5::on_connected(error_code const& e)
|
|||
if (m_abort) return;
|
||||
|
||||
// we failed to connect to the proxy
|
||||
if (e) return;
|
||||
if (e)
|
||||
{
|
||||
if (m_alerts.should_post<socks5_alert>())
|
||||
m_alerts.emplace_alert<socks5_alert>(m_proxy_addr, operation_t::connect, e);
|
||||
return;
|
||||
}
|
||||
|
||||
using namespace libtorrent::detail;
|
||||
|
||||
|
@ -591,7 +607,12 @@ void socks5::handshake1(error_code const& e)
|
|||
{
|
||||
COMPLETE_ASYNC("socks5::on_handshake1");
|
||||
if (m_abort) return;
|
||||
if (e) return;
|
||||
if (e)
|
||||
{
|
||||
if (m_alerts.should_post<socks5_alert>())
|
||||
m_alerts.emplace_alert<socks5_alert>(m_proxy_addr, operation_t::handshake, e);
|
||||
return;
|
||||
}
|
||||
|
||||
ADD_OUTSTANDING_ASYNC("socks5::on_handshake2");
|
||||
boost::asio::async_read(m_socks5_sock, boost::asio::buffer(m_tmp_buf.data(), 2)
|
||||
|
@ -603,7 +624,12 @@ void socks5::handshake2(error_code const& e)
|
|||
COMPLETE_ASYNC("socks5::on_handshake2");
|
||||
if (m_abort) return;
|
||||
|
||||
if (e) return;
|
||||
if (e)
|
||||
{
|
||||
if (m_alerts.should_post<socks5_alert>())
|
||||
m_alerts.emplace_alert<socks5_alert>(m_proxy_addr, operation_t::handshake, e);
|
||||
return;
|
||||
}
|
||||
|
||||
using namespace libtorrent::detail;
|
||||
|
||||
|
@ -613,6 +639,9 @@ void socks5::handshake2(error_code const& e)
|
|||
|
||||
if (version < 5)
|
||||
{
|
||||
if (m_alerts.should_post<socks5_alert>())
|
||||
m_alerts.emplace_alert<socks5_alert>(m_proxy_addr, operation_t::handshake
|
||||
, socks_error::unsupported_version);
|
||||
error_code ec;
|
||||
m_socks5_sock.close(ec);
|
||||
return;
|
||||
|
@ -626,6 +655,9 @@ void socks5::handshake2(error_code const& e)
|
|||
{
|
||||
if (m_proxy_settings.username.empty())
|
||||
{
|
||||
if (m_alerts.should_post<socks5_alert>())
|
||||
m_alerts.emplace_alert<socks5_alert>(m_proxy_addr, operation_t::handshake
|
||||
, socks_error::username_required);
|
||||
error_code ec;
|
||||
m_socks5_sock.close(ec);
|
||||
return;
|
||||
|
@ -648,6 +680,10 @@ void socks5::handshake2(error_code const& e)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (m_alerts.should_post<socks5_alert>())
|
||||
m_alerts.emplace_alert<socks5_alert>(m_proxy_addr, operation_t::handshake
|
||||
, socks_error::unsupported_authentication_method);
|
||||
|
||||
error_code ec;
|
||||
m_socks5_sock.close(ec);
|
||||
return;
|
||||
|
@ -658,7 +694,12 @@ void socks5::handshake3(error_code const& e)
|
|||
{
|
||||
COMPLETE_ASYNC("socks5::on_handshake3");
|
||||
if (m_abort) return;
|
||||
if (e) return;
|
||||
if (e)
|
||||
{
|
||||
if (m_alerts.should_post<socks5_alert>())
|
||||
m_alerts.emplace_alert<socks5_alert>(m_proxy_addr, operation_t::handshake, e);
|
||||
return;
|
||||
}
|
||||
|
||||
ADD_OUTSTANDING_ASYNC("socks5::on_handshake4");
|
||||
boost::asio::async_read(m_socks5_sock, boost::asio::buffer(m_tmp_buf.data(), 2)
|
||||
|
@ -669,7 +710,12 @@ void socks5::handshake4(error_code const& e)
|
|||
{
|
||||
COMPLETE_ASYNC("socks5::on_handshake4");
|
||||
if (m_abort) return;
|
||||
if (e) return;
|
||||
if (e)
|
||||
{
|
||||
if (m_alerts.should_post<socks5_alert>())
|
||||
m_alerts.emplace_alert<socks5_alert>(m_proxy_addr, operation_t::handshake, e);
|
||||
return;
|
||||
}
|
||||
|
||||
using namespace libtorrent::detail;
|
||||
|
||||
|
@ -705,7 +751,12 @@ void socks5::connect1(error_code const& e)
|
|||
{
|
||||
COMPLETE_ASYNC("socks5::connect1");
|
||||
if (m_abort) return;
|
||||
if (e) return;
|
||||
if (e)
|
||||
{
|
||||
if (m_alerts.should_post<socks5_alert>())
|
||||
m_alerts.emplace_alert<socks5_alert>(m_proxy_addr, operation_t::connect, e);
|
||||
return;
|
||||
}
|
||||
|
||||
ADD_OUTSTANDING_ASYNC("socks5::connect2");
|
||||
boost::asio::async_read(m_socks5_sock, boost::asio::buffer(m_tmp_buf.data(), 10)
|
||||
|
@ -717,7 +768,12 @@ void socks5::connect2(error_code const& e)
|
|||
COMPLETE_ASYNC("socks5::connect2");
|
||||
|
||||
if (m_abort) return;
|
||||
if (e) return;
|
||||
if (e)
|
||||
{
|
||||
if (m_alerts.should_post<socks5_alert>())
|
||||
m_alerts.emplace_alert<socks5_alert>(m_proxy_addr, operation_t::handshake, e);
|
||||
return;
|
||||
}
|
||||
|
||||
using namespace libtorrent::detail;
|
||||
|
||||
|
@ -757,6 +813,9 @@ void socks5::hung_up(error_code const& e)
|
|||
|
||||
if (e == boost::asio::error::operation_aborted || m_abort) return;
|
||||
|
||||
if (e && m_alerts.should_post<socks5_alert>())
|
||||
m_alerts.emplace_alert<socks5_alert>(m_proxy_addr, operation_t::sock_read, e);
|
||||
|
||||
// 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
|
||||
|
|
|
@ -178,10 +178,11 @@ TORRENT_TEST(alerts_types)
|
|||
TEST_ALERT_TYPE(dht_sample_infohashes_alert, 93, 0, alert::dht_operation_notification);
|
||||
TEST_ALERT_TYPE(block_uploaded_alert, 94, 0, PROGRESS_NOTIFICATION alert::upload_notification);
|
||||
TEST_ALERT_TYPE(alerts_dropped_alert, 95, 3, alert::error_notification);
|
||||
TEST_ALERT_TYPE(socks5_alert, 96, 0, alert::error_notification);
|
||||
|
||||
#undef TEST_ALERT_TYPE
|
||||
|
||||
TEST_EQUAL(num_alert_types, 96);
|
||||
TEST_EQUAL(num_alert_types, 97);
|
||||
TEST_EQUAL(num_alert_types, count_alert_types);
|
||||
}
|
||||
|
||||
|
|
|
@ -489,7 +489,6 @@ TORRENT_TEST(file_priority_multiple_calls)
|
|||
settings_pack pack = settings();
|
||||
lt::session ses(pack);
|
||||
|
||||
error_code ec;
|
||||
auto t = ::generate_torrent(true);
|
||||
|
||||
add_torrent_params addp;
|
||||
|
|
Loading…
Reference in New Issue