forked from premiere/premiere-libtorrent
fix socks5 support for UDP. based on patch in https://github.com/arvidn/libtorrent/issues/1373
This commit is contained in:
parent
8adcbdd32b
commit
ad7e796d05
|
@ -1,3 +1,4 @@
|
|||
* fix socks5 support for UDP
|
||||
* add setting urlseed_max_request_bytes to handle large web seed requests
|
||||
* fix python build with CC/CXX environment
|
||||
* add trackers from add_torrent_params/magnet links to separate tiers
|
||||
|
|
|
@ -53,10 +53,6 @@ struct fake_peer
|
|||
{
|
||||
fake_peer(simulation& sim, char const* ip)
|
||||
: m_ios(sim, asio::ip::address::from_string(ip))
|
||||
, m_acceptor(m_ios)
|
||||
, m_in_socket(m_ios)
|
||||
, m_out_socket(m_ios)
|
||||
, m_tripped(false)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
m_acceptor.open(asio::ip::tcp::v4(), ec);
|
||||
|
@ -177,20 +173,20 @@ private:
|
|||
char m_out_buffer[300];
|
||||
|
||||
asio::io_service m_ios;
|
||||
asio::ip::tcp::acceptor m_acceptor;
|
||||
asio::ip::tcp::socket m_in_socket;
|
||||
asio::ip::tcp::socket m_out_socket;
|
||||
bool m_tripped;
|
||||
asio::ip::tcp::acceptor m_acceptor{m_ios};
|
||||
asio::ip::tcp::socket m_in_socket{m_ios};
|
||||
asio::ip::tcp::socket m_out_socket{m_ios};
|
||||
bool m_tripped = false;
|
||||
|
||||
std::vector<char> m_send_buffer;
|
||||
};
|
||||
|
||||
struct fake_node
|
||||
struct udp_server
|
||||
{
|
||||
fake_node(simulation& sim, char const* ip, int port = 6881)
|
||||
udp_server(simulation& sim, char const* ip, int port
|
||||
, std::function<std::vector<char>(char const*, int)> handler)
|
||||
: m_ios(sim, asio::ip::address::from_string(ip))
|
||||
, m_socket(m_ios)
|
||||
, m_tripped(false)
|
||||
, m_handler(handler)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
m_socket.open(asio::ip::udp::v4(), ec);
|
||||
|
@ -198,31 +194,73 @@ struct fake_node
|
|||
m_socket.bind(asio::ip::udp::endpoint(asio::ip::address_v4::any(), port), ec);
|
||||
TEST_CHECK(!ec);
|
||||
|
||||
fprintf(stderr, "fake_node::async_read_some\n");
|
||||
m_socket.async_receive(boost::asio::buffer(m_in_buffer)
|
||||
, [&] (boost::system::error_code const& ec, size_t bytes_transferred)
|
||||
{
|
||||
fprintf(stderr, "fake_node::async_read_some callback. ec: %s transferred: %d\n"
|
||||
, ec.message().c_str(), int(bytes_transferred));
|
||||
if (ec) return;
|
||||
m_socket.io_control(lt::udp::socket::non_blocking_io(true));
|
||||
|
||||
std::printf("udp_server::async_read_some\n");
|
||||
using namespace std::placeholders;
|
||||
m_socket.async_receive_from(boost::asio::buffer(m_in_buffer)
|
||||
, m_from, 0, std::bind(&udp_server::on_read, this, _1, _2));
|
||||
}
|
||||
|
||||
void close() { m_socket.close(); }
|
||||
|
||||
private:
|
||||
|
||||
void on_read(boost::system::error_code const& ec, size_t bytes_transferred)
|
||||
{
|
||||
std::printf("udp_server::async_read_some callback. ec: %s transferred: %d\n"
|
||||
, ec.message().c_str(), int(bytes_transferred));
|
||||
if (ec) return;
|
||||
|
||||
std::vector<char> send_buffer = m_handler(m_in_buffer.data(), int(bytes_transferred));
|
||||
|
||||
if (!send_buffer.empty())
|
||||
{
|
||||
lt::error_code err;
|
||||
m_socket.send_to(boost::asio::buffer(send_buffer), m_from, 0, err);
|
||||
if (err)
|
||||
{
|
||||
std::printf("send_to FAILED: %s\n", err.message().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
std::printf("udp_server responding with %d bytes\n"
|
||||
, int(send_buffer.size()));
|
||||
}
|
||||
}
|
||||
|
||||
std::printf("udp_server::async_read_some\n");
|
||||
using namespace std::placeholders;
|
||||
m_socket.async_receive_from(boost::asio::buffer(m_in_buffer)
|
||||
, m_from, 0, std::bind(&udp_server::on_read, this, _1, _2));
|
||||
}
|
||||
|
||||
std::array<char, 1500> m_in_buffer;
|
||||
|
||||
asio::io_service m_ios;
|
||||
asio::ip::udp::socket m_socket{m_ios};
|
||||
asio::ip::udp::endpoint m_from;
|
||||
|
||||
std::function<std::vector<char>(char const*, int)> m_handler;
|
||||
};
|
||||
|
||||
struct fake_node : udp_server
|
||||
{
|
||||
fake_node(simulation& sim, char const* ip, int port = 6881)
|
||||
: udp_server(sim, ip, port, [&](char const* incoming, int size)
|
||||
{
|
||||
lt::bdecode_node n;
|
||||
boost::system::error_code err;
|
||||
int const ret = bdecode(m_in_buffer.data(), m_in_buffer.data() + bytes_transferred
|
||||
, n, err, nullptr, 10, 200);
|
||||
int const ret = bdecode(incoming, incoming + size, n, err, nullptr, 10, 200);
|
||||
TEST_EQUAL(ret, 0);
|
||||
|
||||
m_incoming_packets.emplace_back(m_in_buffer.data(), m_in_buffer.data() + bytes_transferred);
|
||||
m_incoming_packets.emplace_back(incoming, incoming + size);
|
||||
|
||||
// TODO: ideally we would validate the DHT message
|
||||
m_tripped = true;
|
||||
});
|
||||
}
|
||||
|
||||
void close()
|
||||
{
|
||||
m_socket.close();
|
||||
}
|
||||
return std::vector<char>();
|
||||
})
|
||||
{}
|
||||
|
||||
bool tripped() const { return m_tripped; }
|
||||
|
||||
|
@ -231,15 +269,8 @@ struct fake_node
|
|||
|
||||
private:
|
||||
|
||||
std::array<char, 300> m_in_buffer;
|
||||
|
||||
std::vector<std::vector<char>> m_incoming_packets;
|
||||
|
||||
asio::io_service m_ios;
|
||||
asio::ip::udp::socket m_socket;
|
||||
bool m_tripped;
|
||||
|
||||
std::vector<char> m_send_buffer;
|
||||
bool m_tripped = false;
|
||||
};
|
||||
|
||||
inline void add_fake_peers(lt::torrent_handle h)
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit e450864958668f8c2ecf8b9839fa278c9c797571
|
||||
Subproject commit 36b46fc2c316d34714315c04c87cf74de6efae90
|
|
@ -303,3 +303,90 @@ TORRENT_TEST(socks5_tcp_announce)
|
|||
TEST_CHECK(tracker_port != -1);
|
||||
}
|
||||
|
||||
TORRENT_TEST(udp_tracker)
|
||||
{
|
||||
using namespace libtorrent;
|
||||
bool tracker_alert = false;
|
||||
bool connected = false;
|
||||
bool announced = false;
|
||||
run_test(
|
||||
[](lt::session& ses)
|
||||
{
|
||||
set_proxy(ses, settings_pack::socks5);
|
||||
|
||||
// The socks server in libsimulator does not support forwarding UDP
|
||||
// packets to hostnames (just IPv4 destinations)
|
||||
settings_pack p;
|
||||
p.set_bool(settings_pack::proxy_hostnames, false);
|
||||
ses.apply_settings(p);
|
||||
|
||||
lt::add_torrent_params params;
|
||||
params.info_hash = sha1_hash("abababababababababab");
|
||||
params.trackers.push_back("udp://2.2.2.2:8080/announce");
|
||||
params.save_path = ".";
|
||||
ses.async_add_torrent(params);
|
||||
},
|
||||
[&tracker_alert](lt::session& ses, lt::alert const* alert) {
|
||||
if (lt::alert_cast<lt::tracker_announce_alert>(alert))
|
||||
tracker_alert = true;
|
||||
},
|
||||
[&](sim::simulation& sim, lt::session& ses
|
||||
, boost::shared_ptr<lt::torrent_info> ti)
|
||||
{
|
||||
// listen on port 8080
|
||||
udp_server tracker(sim, "2.2.2.2", 8080,
|
||||
[&](char const* msg, int size)
|
||||
{
|
||||
using namespace libtorrent::detail;
|
||||
std::vector<char> ret;
|
||||
TEST_CHECK(size >= 16);
|
||||
|
||||
if (size < 16) return ret;
|
||||
|
||||
std::uint64_t connection_id = read_uint64(msg);
|
||||
std::uint32_t action = read_uint32(msg);
|
||||
std::uint32_t transaction_id = read_uint32(msg);
|
||||
|
||||
std::uint64_t const conn_id = 0xfeedface1337ull;
|
||||
|
||||
if (action == 0)
|
||||
{
|
||||
std::printf("udp connect\n");
|
||||
// udp tracker connect
|
||||
TEST_CHECK(connection_id == 0x41727101980ull);
|
||||
auto inserter = std::back_inserter(ret);
|
||||
write_uint32(0, inserter); // connect
|
||||
write_uint32(transaction_id, inserter);
|
||||
write_uint64(conn_id, inserter);
|
||||
connected = true;
|
||||
}
|
||||
else if (action == 1)
|
||||
{
|
||||
std::printf("udp announce\n");
|
||||
// udp tracker announce
|
||||
TEST_EQUAL(connection_id, conn_id);
|
||||
|
||||
auto inserter = std::back_inserter(ret);
|
||||
write_uint32(1, inserter); // announce
|
||||
write_uint32(transaction_id, inserter);
|
||||
write_uint32(1800, inserter);
|
||||
write_uint32(0, inserter); // leechers
|
||||
write_uint32(0, inserter); // seeders
|
||||
announced = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::printf("unsupported udp tracker action: %d\n", action);
|
||||
}
|
||||
return ret;
|
||||
});
|
||||
|
||||
sim.run();
|
||||
}
|
||||
);
|
||||
|
||||
TEST_CHECK(tracker_alert);
|
||||
TEST_CHECK(connected);
|
||||
TEST_CHECK(announced);
|
||||
}
|
||||
|
||||
|
|
|
@ -112,6 +112,7 @@ void set_proxy(lt::session& ses, int proxy_type, int flags, bool proxy_peer_conn
|
|||
p.set_bool(settings_pack::proxy_hostnames, true);
|
||||
p.set_bool(settings_pack::proxy_peer_connections, proxy_peer_connections);
|
||||
p.set_bool(settings_pack::proxy_tracker_connections, true);
|
||||
p.set_bool(settings_pack::force_proxy, true);
|
||||
|
||||
ses.apply_settings(p);
|
||||
}
|
||||
|
|
|
@ -2109,6 +2109,7 @@ retry:
|
|||
maybe_update_udp_mapping(0, true, ssl_port, ssl_port);
|
||||
maybe_update_udp_mapping(1, true, ssl_port, ssl_port);
|
||||
}
|
||||
m_ssl_udp_socket.set_proxy_settings(proxy());
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -2170,6 +2171,8 @@ retry:
|
|||
maybe_update_udp_mapping(0, false, m_listen_interface.port(), m_listen_interface.port());
|
||||
maybe_update_udp_mapping(1, false, m_listen_interface.port(), m_listen_interface.port());
|
||||
}
|
||||
|
||||
m_udp_socket.set_proxy_settings(proxy());
|
||||
}
|
||||
|
||||
// we made it! now post all the listen_succeeded_alerts
|
||||
|
|
|
@ -845,10 +845,14 @@ void udp_socket::bind(udp::endpoint const& ep, error_code& ec)
|
|||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
error_code err;
|
||||
m_bind_port = m_ipv4_sock.local_endpoint(err).port();
|
||||
if (err) m_bind_port = ep.port();
|
||||
|
||||
#if TORRENT_USE_ASSERTS
|
||||
m_started = true;
|
||||
#endif
|
||||
m_bind_port = ep.port();
|
||||
}
|
||||
|
||||
void udp_socket::set_proxy_settings(aux::proxy_settings const& ps)
|
||||
|
|
Loading…
Reference in New Issue