Skip to content

Commit

Permalink
merged RC_2_0 into master
Browse files Browse the repository at this point in the history
  • Loading branch information
arvidn committed Aug 14, 2022
2 parents 884782c + fd3d56a commit 283cea5
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 89 deletions.
3 changes: 3 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,9 @@
* libtorrent now requires C++14 to build
* added support for GnuTLS for HTTPS and torrents over SSL


* made UPnP and LSD code avoid using select_reactor (to work around an issue on windows in boost.asio < 1.80)

1.2.17 released

* fixed tracker connections spinning when hostname lookups stall
Expand Down
4 changes: 3 additions & 1 deletion include/libtorrent/aux_/lsd.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,16 @@ struct lsd : std::enable_shared_from_this<lsd>
void announce_impl(sha1_hash const& ih, int listen_port, int retry_count);
void resend_announce(error_code const& e, sha1_hash const& info_hash
, int listen_port, int retry_count);
void on_announce(error_code const& ec);
void on_announce(error_code const& ec, std::size_t len);

lsd_callback& m_callback;

address m_listen_address;
address m_netmask;

udp::socket m_socket;
std::array<char, 1500> m_buffer;
udp::endpoint m_remote;

#ifndef TORRENT_DISABLE_LOGGING
bool should_log() const;
Expand Down
21 changes: 16 additions & 5 deletions include/libtorrent/upnp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,17 @@ namespace libtorrent {
class http_parser;
}

namespace aux {

struct socket_package
{
socket_package(io_context& ios) : socket(ios) {}
udp::socket socket;
std::array<char, 1500> buffer;
udp::endpoint remote;
};
}

namespace upnp_errors {
// error codes for the upnp_error_category. They hold error codes
// returned by UPnP routers when mapping ports
Expand Down Expand Up @@ -185,15 +196,15 @@ struct TORRENT_EXTRA_EXPORT upnp final

std::shared_ptr<upnp> self() { return shared_from_this(); }

void open_multicast_socket(udp::socket& s, error_code& ec);
void open_unicast_socket(udp::socket& s, error_code& ec);
void open_multicast_socket(aux::socket_package& s, error_code& ec);
void open_unicast_socket(aux::socket_package& s, error_code& ec);

void map_timer(error_code const& ec);
void try_map_upnp();
void discover_device_impl();

void resend_request(error_code const& e);
void on_reply(udp::socket& s, error_code const& ec);
void on_reply(aux::socket_package& s, error_code const& ec, std::size_t len);

struct rootdevice;
void next(rootdevice& d, port_mapping_t i);
Expand Down Expand Up @@ -326,8 +337,8 @@ struct TORRENT_EXTRA_EXPORT upnp final

// the udp socket used to send and receive
// multicast messages on the network
udp::socket m_multicast_socket;
udp::socket m_unicast_socket;
aux::socket_package m_multicast;
aux::socket_package m_unicast;

// used to resend udp packets in case
// they time out
Expand Down
41 changes: 20 additions & 21 deletions src/lsd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ see LICENSE file.
#include "libtorrent/hex.hpp" // to_hex, from_hex
#include "libtorrent/aux_/numeric_cast.hpp"
#include "libtorrent/aux_/enum_net.hpp"
#include "libtorrent/aux_/scope_end.hpp"

#include "libtorrent/aux_/disable_warnings_push.hpp"
#include <boost/asio/ip/multicast.hpp>
Expand Down Expand Up @@ -113,8 +114,8 @@ void lsd::start(error_code& ec)
}

ADD_OUTSTANDING_ASYNC("lsd::on_announce");
m_socket.async_wait(udp::socket::wait_read
, std::bind(&lsd::on_announce, self(), _1));
m_socket.async_receive_from(boost::asio::buffer(m_buffer), m_remote
, std::bind(&lsd::on_announce, self(), _1, _2));
}

lsd::~lsd() = default;
Expand Down Expand Up @@ -184,20 +185,26 @@ void lsd::resend_announce(error_code const& e, sha1_hash const& info_hash
announce_impl(info_hash, listen_port, retry_count);
}

void lsd::on_announce(error_code const& ec)
void lsd::on_announce(error_code const& ec, std::size_t len)
{
COMPLETE_ASYNC("lsd::on_announce");
if (ec) return;
if (ec)
{
#ifndef TORRENT_DISABLE_LOGGING
debug_log("<== LSD: receive error: %s", ec.message().c_str());
#endif
return;
}

std::array<char, 1500> buffer;
udp::endpoint from;
error_code err;
int const len = static_cast<int>(m_socket.receive_from(
boost::asio::buffer(buffer), from, {}, err));
udp::endpoint const from = m_remote;

ADD_OUTSTANDING_ASYNC("lsd::on_announce");
m_socket.async_wait(udp::socket::wait_read
, std::bind(&lsd::on_announce, self(), _1));
// reissue the async receive as we exit the function. We can't do this
// earlier because we still need to use m_buffer
auto reissue_receive = aux::scope_end([&] {
ADD_OUTSTANDING_ASYNC("lsd::on_announce");
m_socket.async_receive_from(boost::asio::buffer(m_buffer), m_remote
, std::bind(&lsd::on_announce, self(), _1, _2));
});

if (!aux::match_addr_mask(from.address(), m_listen_address, m_netmask))
{
Expand All @@ -209,18 +216,10 @@ void lsd::on_announce(error_code const& ec)
return;
}

if (err)
{
#ifndef TORRENT_DISABLE_LOGGING
debug_log("<== LSD: receive error: %s", err.message().c_str());
#endif
return;
}

aux::http_parser p;

bool error = false;
p.incoming(span<char const>{buffer.data(), len}, error);
p.incoming(span<char const>{m_buffer.data(), std::ptrdiff_t(len)}, error);

if (!p.header_finished() || error)
{
Expand Down
76 changes: 38 additions & 38 deletions src/upnp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ see LICENSE file.
#include "libtorrent/aux_/http_connection.hpp"
#include "libtorrent/aux_/numeric_cast.hpp"
#include "libtorrent/aux_/ssl.hpp"
#include "libtorrent/aux_/scope_end.hpp"

#if defined TORRENT_ASIO_DEBUGGING
#include "libtorrent/aux_/debug.hpp"
Expand Down Expand Up @@ -91,8 +92,8 @@ upnp::upnp(io_context& ios
, m_callback(cb)
, m_io_service(ios)
, m_resolver(ios)
, m_multicast_socket(ios)
, m_unicast_socket(ios)
, m_multicast(ios)
, m_unicast(ios)
, m_broadcast_timer(ios)
, m_refresh_timer(ios)
, m_map_timer(ios)
Expand All @@ -114,7 +115,7 @@ void upnp::start()
TORRENT_ASSERT(is_single_thread());

error_code ec;
open_multicast_socket(m_multicast_socket, ec);
open_multicast_socket(m_multicast, ec);
#ifndef TORRENT_DISABLE_LOGGING
if (ec && should_log())
{
Expand All @@ -125,7 +126,7 @@ void upnp::start()
}
#endif

open_unicast_socket(m_unicast_socket, ec);
open_unicast_socket(m_unicast, ec);
#ifndef TORRENT_DISABLE_LOGGING
if (ec && should_log())
{
Expand All @@ -147,39 +148,39 @@ namespace {

}

void upnp::open_multicast_socket(udp::socket& s, error_code& ec)
void upnp::open_multicast_socket(aux::socket_package& s, error_code& ec)
{
using namespace boost::asio::ip::multicast;
s.open(udp::v4(), ec);
s.socket.open(udp::v4(), ec);
if (ec) return;
s.set_option(udp::socket::reuse_address(true), ec);
s.socket.set_option(udp::socket::reuse_address(true), ec);
if (ec) return;
s.bind(udp::endpoint(m_listen_address, ssdp_port), ec);
s.socket.bind(udp::endpoint(m_listen_address, ssdp_port), ec);
if (ec) return;
s.set_option(join_group(ssdp_multicast_addr), ec);
s.socket.set_option(join_group(ssdp_multicast_addr), ec);
if (ec) return;
s.set_option(hops(255), ec);
s.socket.set_option(hops(255), ec);
if (ec) return;
s.set_option(enable_loopback(true), ec);
s.socket.set_option(enable_loopback(true), ec);
if (ec) return;
s.set_option(outbound_interface(m_listen_address), ec);
s.socket.set_option(outbound_interface(m_listen_address), ec);
if (ec) return;

ADD_OUTSTANDING_ASYNC("upnp::on_reply");
s.async_receive(boost::asio::null_buffers{}
, std::bind(&upnp::on_reply, self(), std::ref(s), _1));
s.socket.async_receive_from(boost::asio::buffer(s.buffer), s.remote
, std::bind(&upnp::on_reply, self(), std::ref(s), _1, _2));
}

void upnp::open_unicast_socket(udp::socket& s, error_code& ec)
void upnp::open_unicast_socket(aux::socket_package& s, error_code& ec)
{
s.open(udp::v4(), ec);
s.socket.open(udp::v4(), ec);
if (ec) return;
s.bind(udp::endpoint(m_listen_address, 0), ec);
s.socket.bind(udp::endpoint(m_listen_address, 0), ec);
if (ec) return;

ADD_OUTSTANDING_ASYNC("upnp::on_reply");
s.async_receive(boost::asio::null_buffers{}
, std::bind(&upnp::on_reply, self(), std::ref(s), _1));
s.socket.async_receive_from(boost::asio::buffer(s.buffer), s.remote
, std::bind(&upnp::on_reply, self(), std::ref(s), _1, _2));
}

upnp::~upnp() = default;
Expand Down Expand Up @@ -222,9 +223,9 @@ void upnp::discover_device_impl()

error_code mcast_ec;
error_code ucast_ec;
m_multicast_socket.send_to(boost::asio::buffer(msearch, sizeof(msearch) - 1)
m_multicast.socket.send_to(boost::asio::buffer(msearch, sizeof(msearch) - 1)
, udp::endpoint(ssdp_multicast_addr, ssdp_port), 0, mcast_ec);
m_unicast_socket.send_to(boost::asio::buffer(msearch, sizeof(msearch) - 1)
m_unicast.socket.send_to(boost::asio::buffer(msearch, sizeof(msearch) - 1)
, udp::endpoint(ssdp_multicast_addr, ssdp_port), 0, ucast_ec);

if (mcast_ec && ucast_ec)
Expand Down Expand Up @@ -439,7 +440,7 @@ void upnp::connect(rootdevice& d)
}
}

void upnp::on_reply(udp::socket& s, error_code const& ec)
void upnp::on_reply(aux::socket_package& s, error_code const& ec, std::size_t const len)
{
TORRENT_ASSERT(is_single_thread());
COMPLETE_ASYNC("upnp::on_reply");
Expand All @@ -448,13 +449,7 @@ void upnp::on_reply(udp::socket& s, error_code const& ec)
if (m_closing) return;

std::shared_ptr<upnp> me(self());

std::array<char, 1500> buffer{};
udp::endpoint from;
error_code err;
int const len = static_cast<int>(s.receive_from(boost::asio::buffer(buffer)
, from, 0, err));

udp::endpoint const from = s.remote;
// parse out the url for the device

/*
Expand Down Expand Up @@ -482,11 +477,15 @@ void upnp::on_reply(udp::socket& s, error_code const& ec)
*/

ADD_OUTSTANDING_ASYNC("upnp::on_reply");
s.async_receive(boost::asio::null_buffers{}
, std::bind(&upnp::on_reply, self(), std::ref(s), _1));
// reissue the async receive as we exit the function. We can't do this
// earlier because we still need to use s.buffer
auto reissue_receive = scope_end([&] {
ADD_OUTSTANDING_ASYNC("upnp::on_reply");
s.socket.async_receive_from(boost::asio::buffer(s.buffer), s.remote
, std::bind(&upnp::on_reply, self(), std::ref(s), _1, _2));
});

if (err) return;
if (ec) return;

if (m_settings.get_bool(settings_pack::upnp_ignore_nonrouters)
&& !match_addr_mask(m_listen_address, from.address(), m_netmask))
Expand All @@ -505,7 +504,7 @@ void upnp::on_reply(udp::socket& s, error_code const& ec)

aux::http_parser p;
bool error = false;
p.incoming({buffer.data(), len}, error);
p.incoming({s.buffer.data(), std::ptrdiff_t(len)}, error);
if (error)
{
#ifndef TORRENT_DISABLE_LOGGING
Expand Down Expand Up @@ -572,6 +571,7 @@ void upnp::on_reply(udp::socket& s, error_code const& ec)
{
std::string protocol;
std::string auth;
error_code err;
// we don't have this device in our list. Add it
std::tie(protocol, auth, d.hostname, d.port, d.path)
= parse_url_components(d.url, err);
Expand Down Expand Up @@ -1137,8 +1137,8 @@ void upnp::disable(error_code const& ec)
m_refresh_timer.cancel();
m_map_timer.cancel();
error_code e;
m_unicast_socket.close(e);
m_multicast_socket.close(e);
m_unicast.socket.close(e);
m_multicast.socket.close(e);
}

void find_error_code(int const type, string_view string, error_code_parse_state& state)
Expand Down Expand Up @@ -1633,8 +1633,8 @@ void upnp::close()
m_map_timer.cancel();
m_closing = true;
error_code ec;
m_unicast_socket.close(ec);
m_multicast_socket.close(ec);
m_unicast.socket.close(ec);
m_multicast.socket.close(ec);

for (auto const& dev : m_devices)
{
Expand Down
Loading

0 comments on commit 283cea5

Please sign in to comment.