Skip to content

Commit

Permalink
Add announce_port support
Browse files Browse the repository at this point in the history
  • Loading branch information
0xThiebaut committed Oct 29, 2024
1 parent 24e658a commit 136ff93
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 5 deletions.
1 change: 1 addition & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
* fix integer overflow in piece picker
* torrent_status::num_pieces counts pieces passed hash check, as documented
* check settings_pack::max_out_request_queue before performance alert
* add announce_port setting to overwrite the port announced to trackers

2.0.10 released

Expand Down
14 changes: 14 additions & 0 deletions include/libtorrent/settings_pack.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2068,6 +2068,20 @@ namespace aux {
i2p_inbound_length,
i2p_outbound_length,

// ``announce_port`` is the port passed along to trackers as the
// ``port`` parameter. This setting does not affect the effective
// listening port nor local service discovery announcements.
// If left as zero (default), the listening port value is used.
//
// .. note::
// This setting is only meant for very special cases where a
// seed's listening port differs from the external port. As an
// example, if a local proxy is used and that the proxy supports
// reverse tunnels through NAT-PMP, the tracker must connect to
// the external NAT-PMP port (configured using ``announce_port``)
// instead of the actual local listening port.
announce_port,

max_int_setting_internal
};

Expand Down
84 changes: 84 additions & 0 deletions simulation/test_tracker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,90 @@ void on_alert_notify(lt::session* ses)
});
}

void test_announce()
{
using sim::asio::ip::address_v4;
sim::default_config network_cfg;
sim::simulation sim{network_cfg};

sim::asio::io_context web_server(sim, make_address_v4("2.2.2.2"));

// listen on port 8080
sim::http_server http(web_server, 8080);

int announces = 0;

// expect announced IP & port
std::string const expect_port = "&port=1234";
std::string const expect_ip = "&ip=1.2.3.4";

http.register_handler("/announce"
, [&announces, expect_port, expect_ip](std::string method, std::string req
, std::map<std::string, std::string>&)
{
++announces;
TEST_EQUAL(method, "GET");
TEST_CHECK(req.find(expect_port) != std::string::npos);
TEST_CHECK(req.find(expect_ip) != std::string::npos);
char response[500];
int const size = std::snprintf(response, sizeof(response), "d8:intervali1800e5:peers0:e");
return sim::send_response(200, "OK", size) + response;
});

{
lt::session_proxy zombie;

std::vector<asio::ip::address> ips;
ips.push_back(make_address("123.0.0.3"));

asio::io_context ios(sim, ips);
lt::settings_pack sett = settings();
sett.set_str(settings_pack::listen_interfaces, "0.0.0.0:6881");
sett.set_str(settings_pack::announce_ip, "1.2.3.4");
sett.set_int(settings_pack::announce_port, 1234);

auto ses = std::make_unique<lt::session>(sett, ios);

ses->set_alert_notify(std::bind(&on_alert_notify, ses.get()));

lt::add_torrent_params p;
p.name = "test-torrent";
p.save_path = ".";
p.info_hashes.v1.assign("abababababababababab");

p.trackers.push_back("http://2.2.2.2:8080/announce");
ses->async_add_torrent(p);

// stop the torrent 5 seconds in
sim::timer t1(sim, lt::seconds(5)
, [&ses](boost::system::error_code const&)
{
std::vector<lt::torrent_handle> torrents = ses->get_torrents();
for (auto const& t : torrents)
{
t.pause();
}
});

// then shut down 10 seconds in
sim::timer t2(sim, lt::seconds(10)
, [&ses,&zombie](boost::system::error_code const&)
{
zombie = ses->abort();
ses.reset();
});

sim.run();
}

TEST_EQUAL(announces, 2);
}

// this test makes sure that a seed can overwrite its announced IP & port
TORRENT_TEST(announce_ip_port) {
test_announce();
}

static const int num_interfaces = 3;

void test_ipv6_support(char const* listen_interfaces
Expand Down
15 changes: 11 additions & 4 deletions src/session_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1301,9 +1301,11 @@ namespace {
#endif
req.ssl_ctx = &m_ssl_ctx;
#endif

auto ls = req.outgoing_socket.get();
if (ls)
if (const auto announce_port = std::uint16_t(m_settings.get_int(settings_pack::announce_port)))
{
req.listen_port = announce_port;
}
else if (auto ls = req.outgoing_socket.get())
{
req.listen_port =
#ifdef TORRENT_SSL_PEERS
Expand Down Expand Up @@ -6214,9 +6216,14 @@ namespace {
m_dht->get_peers(info_hash, std::bind(&on_dht_get_peers, std::ref(m_alerts), info_hash, _1));
}

void session_impl::dht_announce(sha1_hash const& info_hash, int port, dht::announce_flags_t const flags)
void session_impl::dht_announce(sha1_hash const& info_hash, int port, dht::announce_flags_t flags)
{
if (!m_dht) return;
if (const auto announce_port = std::uint16_t(m_settings.get_int(settings_pack::announce_port)))
{
port = announce_port;
flags &= ~dht::announce::implied_port;
}
m_dht->announce(info_hash, port, flags, std::bind(&on_dht_get_peers, std::ref(m_alerts), info_hash, _1));
}

Expand Down
3 changes: 2 additions & 1 deletion src/settings_pack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,8 @@ constexpr int DISK_WRITE_MODE = settings_pack::enable_os_cache;
SET(i2p_inbound_quantity, 3, nullptr),
SET(i2p_outbound_quantity, 3, nullptr),
SET(i2p_inbound_length, 3, nullptr),
SET(i2p_outbound_length, 3, nullptr)
SET(i2p_outbound_length, 3, nullptr),
SET(announce_port, 0, nullptr)
}});

#undef SET
Expand Down

0 comments on commit 136ff93

Please sign in to comment.