improve support for listening on multiple sockets and interfaces, with the listen_interfaces setting
This commit is contained in:
parent
3842a0a197
commit
887e79eb22
|
@ -1,3 +1,4 @@
|
||||||
|
* improved support for listening on multiple sockets and interfaces
|
||||||
* resume data no longer has timestamps of files
|
* resume data no longer has timestamps of files
|
||||||
|
|
||||||
1.1.0 release
|
1.1.0 release
|
||||||
|
|
|
@ -1268,7 +1268,7 @@ namespace libtorrent
|
||||||
listen_failed_alert(
|
listen_failed_alert(
|
||||||
aux::stack_allocator& alloc
|
aux::stack_allocator& alloc
|
||||||
, std::string const& iface
|
, std::string const& iface
|
||||||
, int port
|
, tcp::endpoint const& ep
|
||||||
, int op
|
, int op
|
||||||
, error_code const& ec
|
, error_code const& ec
|
||||||
, socket_type_t t);
|
, socket_type_t t);
|
||||||
|
@ -1278,7 +1278,7 @@ namespace libtorrent
|
||||||
static const int static_category = alert::status_notification | alert::error_notification;
|
static const int static_category = alert::status_notification | alert::error_notification;
|
||||||
virtual std::string message() const TORRENT_OVERRIDE;
|
virtual std::string message() const TORRENT_OVERRIDE;
|
||||||
|
|
||||||
// the interface libtorrent attempted to listen on that failed.
|
// the network device libtorrent attempted to listen on, or the IP address
|
||||||
char const* listen_interface() const;
|
char const* listen_interface() const;
|
||||||
|
|
||||||
// the error the system returned
|
// the error the system returned
|
||||||
|
@ -1286,7 +1286,7 @@ namespace libtorrent
|
||||||
|
|
||||||
enum op_t
|
enum op_t
|
||||||
{
|
{
|
||||||
parse_addr, open, bind, listen, get_peer_name, accept
|
parse_addr, open, bind, listen, get_socket_name, accept, enum_if
|
||||||
};
|
};
|
||||||
|
|
||||||
// the specific low level operation that failed. See op_t.
|
// the specific low level operation that failed. See op_t.
|
||||||
|
|
|
@ -124,12 +124,21 @@ namespace libtorrent
|
||||||
|
|
||||||
struct listen_socket_t
|
struct listen_socket_t
|
||||||
{
|
{
|
||||||
listen_socket_t(): external_port(0), ssl(false) {}
|
listen_socket_t()
|
||||||
|
: tcp_external_port(0)
|
||||||
|
, ssl(false)
|
||||||
|
{
|
||||||
|
tcp_port_mapping[0] = -1;
|
||||||
|
tcp_port_mapping[1] = -1;
|
||||||
|
}
|
||||||
|
|
||||||
// this is typically empty but can be set
|
// this is typically empty but can be set
|
||||||
// to the WAN IP address of NAT-PMP or UPnP router
|
// to the WAN IP address of NAT-PMP or UPnP router
|
||||||
address external_address;
|
address external_address;
|
||||||
|
|
||||||
|
// this is a cached local endpoint for the listen socket
|
||||||
|
tcp::endpoint local_endpoint;
|
||||||
|
|
||||||
// this is typically set to the same as the local
|
// this is typically set to the same as the local
|
||||||
// listen port. In case a NAT port forward was
|
// listen port. In case a NAT port forward was
|
||||||
// successfully opened, this will be set to the
|
// successfully opened, this will be set to the
|
||||||
|
@ -137,7 +146,10 @@ namespace libtorrent
|
||||||
// on the NAT box itself. This is the port that has
|
// on the NAT box itself. This is the port that has
|
||||||
// to be published to peers, since this is the port
|
// to be published to peers, since this is the port
|
||||||
// the client is reachable through.
|
// the client is reachable through.
|
||||||
int external_port;
|
int tcp_external_port;
|
||||||
|
|
||||||
|
// 0 is natpmp 1 is upnp
|
||||||
|
int tcp_port_mapping[2];
|
||||||
|
|
||||||
// set to true if this is an SSL listen socket
|
// set to true if this is an SSL listen socket
|
||||||
bool ssl;
|
bool ssl;
|
||||||
|
@ -837,10 +849,6 @@ namespace libtorrent
|
||||||
// which interface to listen on
|
// which interface to listen on
|
||||||
std::vector<std::pair<std::string, int> > m_listen_interfaces;
|
std::vector<std::pair<std::string, int> > m_listen_interfaces;
|
||||||
|
|
||||||
// keep this around until everything uses the list of interfaces
|
|
||||||
// instead.
|
|
||||||
tcp::endpoint m_listen_interface;
|
|
||||||
|
|
||||||
// the network interfaces outgoing connections are opened through. If
|
// the network interfaces outgoing connections are opened through. If
|
||||||
// there is more then one, they are used in a round-robin fashion
|
// there is more then one, they are used in a round-robin fashion
|
||||||
// each element is a device name or IP address (in string form) and
|
// each element is a device name or IP address (in string form) and
|
||||||
|
@ -850,12 +858,6 @@ namespace libtorrent
|
||||||
// socket fails.
|
// socket fails.
|
||||||
std::vector<std::string> m_outgoing_interfaces;
|
std::vector<std::string> m_outgoing_interfaces;
|
||||||
|
|
||||||
// if we're listening on an IPv6 interface
|
|
||||||
// this is one of the non local IPv6 interfaces
|
|
||||||
// on this machine
|
|
||||||
tcp::endpoint m_ipv6_interface;
|
|
||||||
tcp::endpoint m_ipv4_interface;
|
|
||||||
|
|
||||||
// since we might be listening on multiple interfaces
|
// since we might be listening on multiple interfaces
|
||||||
// we might need more than one listen socket
|
// we might need more than one listen socket
|
||||||
std::list<listen_socket_t> m_listen_sockets;
|
std::list<listen_socket_t> m_listen_sockets;
|
||||||
|
@ -887,8 +889,7 @@ namespace libtorrent
|
||||||
};
|
};
|
||||||
|
|
||||||
listen_socket_t setup_listener(std::string const& device
|
listen_socket_t setup_listener(std::string const& device
|
||||||
, boost::asio::ip::tcp const& protocol, int port, int flags
|
, tcp::endpoint bind_ep, int flags, error_code& ec);
|
||||||
, error_code& ec);
|
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_DHT
|
#ifndef TORRENT_DISABLE_DHT
|
||||||
entry m_dht_state;
|
entry m_dht_state;
|
||||||
|
@ -1026,6 +1027,7 @@ namespace libtorrent
|
||||||
|
|
||||||
// see m_external_listen_port. This is the same
|
// see m_external_listen_port. This is the same
|
||||||
// but for the udp port used by the DHT.
|
// but for the udp port used by the DHT.
|
||||||
|
// TODO: 3 once udp sockets are part of m_listen_sockets, remove this
|
||||||
int m_external_udp_port;
|
int m_external_udp_port;
|
||||||
|
|
||||||
udp_socket m_udp_socket;
|
udp_socket m_udp_socket;
|
||||||
|
@ -1046,18 +1048,18 @@ namespace libtorrent
|
||||||
boost::shared_ptr<upnp> m_upnp;
|
boost::shared_ptr<upnp> m_upnp;
|
||||||
boost::shared_ptr<lsd> m_lsd;
|
boost::shared_ptr<lsd> m_lsd;
|
||||||
|
|
||||||
|
// TODO: 3 once the udp socket is in listen_socket_t, these should
|
||||||
|
// move in there too
|
||||||
|
// 0 is natpmp 1 is upnp
|
||||||
|
int m_udp_mapping[2];
|
||||||
|
#ifdef TORRENT_USE_OPENSSL
|
||||||
|
int m_ssl_udp_mapping[2];
|
||||||
|
#endif
|
||||||
|
|
||||||
// mask is a bitmask of which protocols to remap on:
|
// mask is a bitmask of which protocols to remap on:
|
||||||
// 1: NAT-PMP
|
// 1: NAT-PMP
|
||||||
// 2: UPnP
|
// 2: UPnP
|
||||||
void remap_tcp_ports(boost::uint32_t mask, int tcp_port, int ssl_port);
|
void remap_ports(boost::uint32_t mask, listen_socket_t& s);
|
||||||
|
|
||||||
// 0 is natpmp 1 is upnp
|
|
||||||
int m_tcp_mapping[2];
|
|
||||||
int m_udp_mapping[2];
|
|
||||||
#ifdef TORRENT_USE_OPENSSL
|
|
||||||
int m_ssl_tcp_mapping[2];
|
|
||||||
int m_ssl_udp_mapping[2];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// the timer used to fire the tick
|
// the timer used to fire the tick
|
||||||
deadline_timer m_timer;
|
deadline_timer m_timer;
|
||||||
|
|
|
@ -246,6 +246,7 @@ namespace libtorrent { namespace aux
|
||||||
|
|
||||||
virtual void prioritize_connections(boost::weak_ptr<torrent> t) = 0;
|
virtual void prioritize_connections(boost::weak_ptr<torrent> t) = 0;
|
||||||
|
|
||||||
|
// TODO: 3 these should go away!
|
||||||
virtual tcp::endpoint get_ipv6_interface() const = 0;
|
virtual tcp::endpoint get_ipv6_interface() const = 0;
|
||||||
virtual tcp::endpoint get_ipv4_interface() const = 0;
|
virtual tcp::endpoint get_ipv4_interface() const = 0;
|
||||||
|
|
||||||
|
|
|
@ -723,8 +723,7 @@ namespace libtorrent
|
||||||
void force_tracker_request(time_point, int tracker_idx);
|
void force_tracker_request(time_point, int tracker_idx);
|
||||||
void scrape_tracker(int idx, bool user_triggered);
|
void scrape_tracker(int idx, bool user_triggered);
|
||||||
void announce_with_tracker(boost::uint8_t e
|
void announce_with_tracker(boost::uint8_t e
|
||||||
= tracker_request::none
|
= tracker_request::none);
|
||||||
, address const& bind_interface = address_v4::any());
|
|
||||||
int seconds_since_last_scrape() const
|
int seconds_since_last_scrape() const
|
||||||
{
|
{
|
||||||
return m_last_scrape == (std::numeric_limits<boost::int16_t>::min)()
|
return m_last_scrape == (std::numeric_limits<boost::int16_t>::min)()
|
||||||
|
|
|
@ -134,7 +134,7 @@ class TORRENT_EXTRA_EXPORT upnp : public boost::enable_shared_from_this<upnp>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
upnp(io_service& ios
|
upnp(io_service& ios
|
||||||
, address const& listen_interface, std::string const& user_agent
|
, std::string const& user_agent
|
||||||
, portmap_callback_t const& cb, log_callback_t const& lcb
|
, portmap_callback_t const& cb, log_callback_t const& lcb
|
||||||
, bool ignore_nonrouters);
|
, bool ignore_nonrouters);
|
||||||
~upnp();
|
~upnp();
|
||||||
|
|
|
@ -786,26 +786,19 @@ namespace libtorrent {
|
||||||
"HTTPS",
|
"HTTPS",
|
||||||
"SSL/uTP"
|
"SSL/uTP"
|
||||||
};
|
};
|
||||||
|
|
||||||
tcp::endpoint parse_interface(std::string const& iface, int port)
|
|
||||||
{
|
|
||||||
// ignore errors
|
|
||||||
error_code ec;
|
|
||||||
return tcp::endpoint(address::from_string(iface, ec), port);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
listen_failed_alert::listen_failed_alert(
|
listen_failed_alert::listen_failed_alert(
|
||||||
aux::stack_allocator& alloc
|
aux::stack_allocator& alloc
|
||||||
, std::string const& iface
|
, std::string const& iface
|
||||||
, int prt
|
, tcp::endpoint const& ep
|
||||||
, int op
|
, int op
|
||||||
, error_code const& ec
|
, error_code const& ec
|
||||||
, socket_type_t t)
|
, socket_type_t t)
|
||||||
: error(ec)
|
: error(ec)
|
||||||
, operation(op)
|
, operation(op)
|
||||||
, sock_type(t)
|
, sock_type(t)
|
||||||
, endpoint(parse_interface(iface, prt))
|
, endpoint(ep)
|
||||||
, m_alloc(alloc)
|
, m_alloc(alloc)
|
||||||
, m_interface_idx(alloc.copy_string(iface))
|
, m_interface_idx(alloc.copy_string(iface))
|
||||||
{}
|
{}
|
||||||
|
@ -823,11 +816,13 @@ namespace libtorrent {
|
||||||
"open",
|
"open",
|
||||||
"bind",
|
"bind",
|
||||||
"listen",
|
"listen",
|
||||||
"get_peer_name",
|
"get_socket_name",
|
||||||
"accept"
|
"accept",
|
||||||
|
"enum_if"
|
||||||
};
|
};
|
||||||
char ret[300];
|
char ret[300];
|
||||||
snprintf(ret, sizeof(ret), "listening on %s failed: [%s] [%s] %s"
|
snprintf(ret, sizeof(ret), "listening on %s (device: %s) failed: [%s] [%s] %s"
|
||||||
|
, print_endpoint(endpoint).c_str()
|
||||||
, listen_interface()
|
, listen_interface()
|
||||||
, op_str[operation]
|
, op_str[operation]
|
||||||
, sock_type_str[sock_type]
|
, sock_type_str[sock_type]
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -125,6 +125,12 @@ namespace libtorrent
|
||||||
|
|
||||||
using aux::session_impl;
|
using aux::session_impl;
|
||||||
|
|
||||||
|
#if TORRENT_USE_IPV6
|
||||||
|
#define DEFAULT_LISTEN_INTERFACE "0.0.0.0:6881,[::]:6881"
|
||||||
|
#else
|
||||||
|
#define DEFAULT_LISTEN_INTERFACE "0.0.0.0:6881"
|
||||||
|
#endif
|
||||||
|
|
||||||
str_setting_entry_t str_settings[settings_pack::num_string_settings] =
|
str_setting_entry_t str_settings[settings_pack::num_string_settings] =
|
||||||
{
|
{
|
||||||
SET(user_agent, "libtorrent/" LIBTORRENT_VERSION, &session_impl::update_user_agent),
|
SET(user_agent, "libtorrent/" LIBTORRENT_VERSION, &session_impl::update_user_agent),
|
||||||
|
@ -132,7 +138,7 @@ namespace libtorrent
|
||||||
SET(mmap_cache, 0, 0),
|
SET(mmap_cache, 0, 0),
|
||||||
SET(handshake_client_version, 0, 0),
|
SET(handshake_client_version, 0, 0),
|
||||||
SET_NOPREV(outgoing_interfaces, "", &session_impl::update_outgoing_interfaces),
|
SET_NOPREV(outgoing_interfaces, "", &session_impl::update_outgoing_interfaces),
|
||||||
SET_NOPREV(listen_interfaces, "0.0.0.0:6881", &session_impl::update_listen_interfaces),
|
SET_NOPREV(listen_interfaces, DEFAULT_LISTEN_INTERFACE, &session_impl::update_listen_interfaces),
|
||||||
SET_NOPREV(proxy_hostname, "", &session_impl::update_proxy),
|
SET_NOPREV(proxy_hostname, "", &session_impl::update_proxy),
|
||||||
SET_NOPREV(proxy_username, "", &session_impl::update_proxy),
|
SET_NOPREV(proxy_username, "", &session_impl::update_proxy),
|
||||||
SET_NOPREV(proxy_password, "", &session_impl::update_proxy),
|
SET_NOPREV(proxy_password, "", &session_impl::update_proxy),
|
||||||
|
@ -140,6 +146,8 @@ namespace libtorrent
|
||||||
SET_NOPREV(peer_fingerprint, "-LT1100-", &session_impl::update_peer_fingerprint)
|
SET_NOPREV(peer_fingerprint, "-LT1100-", &session_impl::update_peer_fingerprint)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#undef DEFAULT_LISTEN_INTERFACE
|
||||||
|
|
||||||
bool_setting_entry_t bool_settings[settings_pack::num_bool_settings] =
|
bool_setting_entry_t bool_settings[settings_pack::num_bool_settings] =
|
||||||
{
|
{
|
||||||
SET(allow_multiple_connections_per_ip, false, 0),
|
SET(allow_multiple_connections_per_ip, false, 0),
|
||||||
|
|
|
@ -3058,8 +3058,7 @@ namespace libtorrent
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void torrent::announce_with_tracker(boost::uint8_t e
|
void torrent::announce_with_tracker(boost::uint8_t e)
|
||||||
, address const& bind_interface)
|
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(is_single_thread());
|
TORRENT_ASSERT(is_single_thread());
|
||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
|
@ -3183,8 +3182,6 @@ namespace libtorrent
|
||||||
req.triggered_manually = ae.triggered_manually;
|
req.triggered_manually = ae.triggered_manually;
|
||||||
ae.triggered_manually = false;
|
ae.triggered_manually = false;
|
||||||
|
|
||||||
req.bind_ip = bind_interface;
|
|
||||||
|
|
||||||
if (settings().get_bool(settings_pack::force_proxy))
|
if (settings().get_bool(settings_pack::force_proxy))
|
||||||
{
|
{
|
||||||
// in force_proxy mode we don't talk directly to trackers
|
// in force_proxy mode we don't talk directly to trackers
|
||||||
|
@ -3574,6 +3571,8 @@ namespace libtorrent
|
||||||
// matches one of the listen interfaces, since that means this
|
// matches one of the listen interfaces, since that means this
|
||||||
// announce was the second one
|
// announce was the second one
|
||||||
|
|
||||||
|
// TODO: 3 instead of announcing once per IP version, announce once per
|
||||||
|
// listen interface (i.e. m_listen_sockets)
|
||||||
if (((!is_any(m_ses.get_ipv6_interface().address()) && tracker_ip.is_v4())
|
if (((!is_any(m_ses.get_ipv6_interface().address()) && tracker_ip.is_v4())
|
||||||
|| (!is_any(m_ses.get_ipv4_interface().address()) && tracker_ip.is_v6()))
|
|| (!is_any(m_ses.get_ipv4_interface().address()) && tracker_ip.is_v6()))
|
||||||
&& r.bind_ip != m_ses.get_ipv4_interface().address()
|
&& r.bind_ip != m_ses.get_ipv4_interface().address()
|
||||||
|
|
11
src/upnp.cpp
11
src/upnp.cpp
|
@ -69,8 +69,11 @@ namespace upnp_errors
|
||||||
|
|
||||||
static error_code ignore_error;
|
static error_code ignore_error;
|
||||||
|
|
||||||
|
// TODO: 3 bind the broadcast socket. it would probably have to be changed to a vector of interfaces to
|
||||||
|
// bind to, since the broadcast socket opens one socket per local
|
||||||
|
// interface by default
|
||||||
upnp::upnp(io_service& ios
|
upnp::upnp(io_service& ios
|
||||||
, address const& listen_interface, std::string const& user_agent
|
, std::string const& user_agent
|
||||||
, portmap_callback_t const& cb, log_callback_t const& lcb
|
, portmap_callback_t const& cb, log_callback_t const& lcb
|
||||||
, bool ignore_nonrouters)
|
, bool ignore_nonrouters)
|
||||||
: m_user_agent(user_agent)
|
: m_user_agent(user_agent)
|
||||||
|
@ -90,12 +93,6 @@ upnp::upnp(io_service& ios
|
||||||
, m_last_if_update(min_time())
|
, m_last_if_update(min_time())
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(cb);
|
TORRENT_ASSERT(cb);
|
||||||
|
|
||||||
// TODO: 3 listen_interface is not used. It's meant to bind the broadcast
|
|
||||||
// socket. it would probably have to be changed to a vector of interfaces to
|
|
||||||
// bind to though, since the broadcast socket opens one socket per local
|
|
||||||
// interface by default
|
|
||||||
TORRENT_UNUSED(listen_interface);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void upnp::start()
|
void upnp::start()
|
||||||
|
|
Loading…
Reference in New Issue