merged RC_1_1 into master
This commit is contained in:
commit
e0fa1cd247
|
@ -73,6 +73,9 @@
|
|||
* require C++11 to build libtorrent
|
||||
|
||||
|
||||
* bind upnp requests to correct local address
|
||||
* save resume data when removing web seeds
|
||||
* fix proxying of https connections
|
||||
* fix race condition in disk I/O storage class
|
||||
* fix http connection timeout on multi-homed hosts
|
||||
* removed depdendency on boost::uintptr_t for better compatibility
|
||||
|
|
|
@ -100,7 +100,7 @@ struct TORRENT_EXTRA_EXPORT http_connection
|
|||
std::string m_sendbuffer;
|
||||
|
||||
void get(std::string const& url, time_duration timeout = seconds(30)
|
||||
, int prio = 0, aux::proxy_settings const* ps = 0, int handle_redirects = 5
|
||||
, int prio = 0, aux::proxy_settings const* ps = NULL, int handle_redirects = 5
|
||||
, std::string const& user_agent = std::string()
|
||||
, boost::optional<address> const& bind_addr = boost::optional<address>()
|
||||
, int resolve_flags = 0, std::string const& auth_ = std::string()
|
||||
|
@ -110,7 +110,7 @@ struct TORRENT_EXTRA_EXPORT http_connection
|
|||
);
|
||||
|
||||
void start(std::string const& hostname, int port
|
||||
, time_duration timeout, int prio = 0, aux::proxy_settings const* ps = 0
|
||||
, time_duration timeout, int prio = 0, aux::proxy_settings const* ps = NULL
|
||||
, bool ssl = false, int handle_redirect = 5
|
||||
, boost::optional<address> const& bind_addr = boost::optional<address>()
|
||||
, int resolve_flags = 0
|
||||
|
|
|
@ -55,7 +55,7 @@ struct TORRENT_EXTRA_EXPORT natpmp
|
|||
|
||||
// maps the ports, if a port is set to 0
|
||||
// it will not be mapped
|
||||
int add_mapping(aux::portmap_protocol p, int external_port, int local_port);
|
||||
int add_mapping(aux::portmap_protocol p, int external_port, tcp::endpoint local_ep);
|
||||
void delete_mapping(int mapping_index);
|
||||
bool get_mapping(int mapping_index, int& local_port, int& external_port
|
||||
, aux::portmap_protocol& protocol) const;
|
||||
|
|
|
@ -249,8 +249,8 @@ protected:
|
|||
bool handle_error(error_code const& e, handler_type const& h);
|
||||
|
||||
tcp::socket m_sock;
|
||||
std::string m_hostname;
|
||||
int m_port;
|
||||
std::string m_hostname; // proxy host
|
||||
int m_port; // proxy port
|
||||
|
||||
endpoint_type m_remote_endpoint;
|
||||
|
||||
|
|
|
@ -172,13 +172,13 @@ struct TORRENT_EXTRA_EXPORT upnp final
|
|||
// portmap_alert_ respectively. If The mapping fails immediately, the return value
|
||||
// is -1, which means failure. There will not be any error alert notification for
|
||||
// mappings that fail with a -1 return value.
|
||||
int add_mapping(aux::portmap_protocol p, int external_port, int local_port);
|
||||
int add_mapping(aux::portmap_protocol p, int external_port, tcp::endpoint local_ep);
|
||||
|
||||
// This function removes a port mapping. ``mapping_index`` is the index that refers
|
||||
// to the mapping you want to remove, which was returned from add_mapping().
|
||||
void delete_mapping(int mapping_index);
|
||||
|
||||
bool get_mapping(int mapping_index, int& local_port, int& external_port
|
||||
bool get_mapping(int mapping_index, tcp::endpoint& local_ep, int& external_port
|
||||
, aux::portmap_protocol& protocol) const;
|
||||
|
||||
void discover_device();
|
||||
|
@ -249,7 +249,7 @@ private:
|
|||
{
|
||||
aux::portmap_protocol protocol = aux::portmap_protocol::none;
|
||||
int external_port = 0;
|
||||
int local_port = 0;
|
||||
tcp::endpoint local_ep;
|
||||
};
|
||||
|
||||
struct mapping_t
|
||||
|
@ -263,7 +263,7 @@ private:
|
|||
|
||||
// the local port for this mapping. If this is set
|
||||
// to 0, the mapping is not in use
|
||||
int local_port = 0;
|
||||
tcp::endpoint local_ep;
|
||||
|
||||
// the external (on the NAT router) port
|
||||
// for the mapping. This is the port we
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 0e8d74baf1f6d9db19857eaa87734faecd530f94
|
||||
Subproject commit 70feadef80dc76ae6d5e7c2f92334377d698dd7d
|
|
@ -602,6 +602,53 @@ TORRENT_TEST(http_connection_http_error)
|
|||
test_proxy_failure(settings_pack::http);
|
||||
}
|
||||
|
||||
// Requests a proxied SSL connection. This test just ensures that the correct CONNECT request
|
||||
// is sent to the proxy server.
|
||||
TORRENT_TEST(http_connection_ssl_proxy)
|
||||
{
|
||||
using sim::asio::ip::address_v4;
|
||||
sim_config network_cfg;
|
||||
sim::simulation sim{network_cfg};
|
||||
|
||||
sim::asio::io_service client_ios(sim, address_v4::from_string("10.0.0.1"));
|
||||
sim::asio::io_service proxy_ios(sim, address_v4::from_string("50.50.50.50"));
|
||||
lt::resolver res(client_ios);
|
||||
|
||||
sim::http_server http_proxy(proxy_ios, 4445);
|
||||
|
||||
lt::aux::proxy_settings ps = make_proxy_settings(settings_pack::http);
|
||||
|
||||
int client_counter = 0;
|
||||
int proxy_counter = 0;
|
||||
|
||||
http_proxy.register_handler("10.0.0.2:8080"
|
||||
, [&proxy_counter](std::string method, std::string req, std::map<std::string, std::string>& headers)
|
||||
{
|
||||
proxy_counter++;
|
||||
TEST_EQUAL(method, "CONNECT");
|
||||
return sim::send_response(403, "Not supported", 1337);
|
||||
});
|
||||
|
||||
auto h = std::make_shared<http_connection>(client_ios
|
||||
, res
|
||||
, [&client_counter](error_code const& ec, http_parser const& parser
|
||||
, char const* data, const int size, http_connection& c)
|
||||
{
|
||||
client_counter++;
|
||||
TEST_EQUAL(ec, boost::asio::error::operation_not_supported);
|
||||
});
|
||||
|
||||
h->start("10.0.0.2", 8080, seconds(1), 0, &ps, true /*ssl*/);
|
||||
|
||||
error_code e;
|
||||
sim.run(e);
|
||||
|
||||
TEST_EQUAL(client_counter, 1);
|
||||
TEST_EQUAL(proxy_counter, 1);
|
||||
if (e) std::cerr << " run failed: " << e.message() << std::endl;
|
||||
TEST_EQUAL(e, error_code());
|
||||
}
|
||||
|
||||
// TODO: test http proxy with password
|
||||
// TODO: test socks5 with password
|
||||
// TODO: test SSL
|
||||
|
|
|
@ -64,15 +64,7 @@ namespace libtorrent {
|
|||
|
||||
// send CONNECT
|
||||
std::back_insert_iterator<std::vector<char>> p(m_buffer);
|
||||
std::string endpoint;
|
||||
if (!m_hostname.empty())
|
||||
{
|
||||
endpoint = m_hostname + ':' + to_string(m_remote_endpoint.port()).data();
|
||||
}
|
||||
else
|
||||
{
|
||||
endpoint = print_endpoint(m_remote_endpoint);
|
||||
}
|
||||
std::string const endpoint = print_endpoint(m_remote_endpoint);
|
||||
write_string("CONNECT " + endpoint + " HTTP/1.0\r\n", p);
|
||||
if (!m_user.empty())
|
||||
{
|
||||
|
|
|
@ -229,7 +229,7 @@ void natpmp::delete_mapping(int const index)
|
|||
}
|
||||
|
||||
int natpmp::add_mapping(portmap_protocol const p, int const external_port
|
||||
, int const local_port)
|
||||
, tcp::endpoint const local_ep)
|
||||
{
|
||||
TORRENT_ASSERT(is_single_thread());
|
||||
|
||||
|
@ -244,7 +244,7 @@ int natpmp::add_mapping(portmap_protocol const p, int const external_port
|
|||
}
|
||||
i->protocol = p;
|
||||
i->external_port = external_port;
|
||||
i->local_port = local_port;
|
||||
i->local_port = local_ep.port();
|
||||
i->act = mapping_t::action::add;
|
||||
|
||||
int const mapping_index = int(i - m_mappings.begin());
|
||||
|
|
|
@ -1528,7 +1528,7 @@ namespace {
|
|||
}
|
||||
#endif // TORRENT_DISABLE_LOGGING
|
||||
}
|
||||
#endif // TORRENT_WINDOWS
|
||||
#else
|
||||
|
||||
{
|
||||
// this is best-effort. ignore errors
|
||||
|
@ -1542,6 +1542,7 @@ namespace {
|
|||
}
|
||||
#endif // TORRENT_DISABLE_LOGGING
|
||||
}
|
||||
#endif // TORRENT_WINDOWS
|
||||
|
||||
#if TORRENT_USE_IPV6
|
||||
if (bind_ep.address().is_v6())
|
||||
|
@ -2200,7 +2201,12 @@ namespace {
|
|||
|
||||
// only update this mapping if we actually have a socket listening
|
||||
if (ep != EndpointType())
|
||||
map_handle = m.add_mapping(protocol, ep.port(), ep.port());
|
||||
map_handle = m.add_mapping(protocol, ep.port(), ep);
|
||||
}
|
||||
|
||||
tcp::endpoint to_tcp(udp::endpoint const ep)
|
||||
{
|
||||
return tcp::endpoint(ep.address(), ep.port());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2213,12 +2219,12 @@ namespace {
|
|||
if ((mask & remap_natpmp) && m_natpmp)
|
||||
{
|
||||
map_port(*m_natpmp, portmap_protocol::tcp, tcp_ep, s.tcp_port_mapping[0]);
|
||||
map_port(*m_natpmp, portmap_protocol::udp, udp_ep, s.udp_port_mapping[0]);
|
||||
map_port(*m_natpmp, portmap_protocol::udp, to_tcp(udp_ep), s.udp_port_mapping[0]);
|
||||
}
|
||||
if ((mask & remap_upnp) && m_upnp)
|
||||
{
|
||||
map_port(*m_upnp, portmap_protocol::tcp, tcp_ep, s.tcp_port_mapping[1]);
|
||||
map_port(*m_upnp, portmap_protocol::udp, udp_ep, s.udp_port_mapping[1]);
|
||||
map_port(*m_upnp, portmap_protocol::udp, to_tcp(udp_ep), s.udp_port_mapping[1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5011,8 +5017,9 @@ namespace {
|
|||
{
|
||||
#ifdef TORRENT_WINDOWS
|
||||
s.set_option(exclusive_address_use(true), ec);
|
||||
#endif
|
||||
#else
|
||||
s.set_option(tcp::acceptor::reuse_address(true), ec);
|
||||
#endif
|
||||
// ignore errors because the underlying socket may not
|
||||
// be opened yet. This happens when we're routing through
|
||||
// a proxy. In that case, we don't yet know the address of
|
||||
|
@ -6613,9 +6620,9 @@ namespace {
|
|||
{
|
||||
int ret = 0;
|
||||
if (m_upnp) ret = m_upnp->add_mapping(static_cast<portmap_protocol>(t), external_port
|
||||
, local_port);
|
||||
, tcp::endpoint({}, static_cast<std::uint16_t>(local_port)));
|
||||
if (m_natpmp) ret = m_natpmp->add_mapping(static_cast<portmap_protocol>(t), external_port
|
||||
, local_port);
|
||||
, tcp::endpoint({}, static_cast<std::uint16_t>(local_port)));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -9776,7 +9776,11 @@ namespace libtorrent {
|
|||
auto const i = std::find_if(m_web_seeds.begin(), m_web_seeds.end()
|
||||
, [&] (web_seed_t const& w) { return w.url == url && w.type == type; });
|
||||
|
||||
if (i != m_web_seeds.end()) remove_web_seed_iter(i);
|
||||
if (i != m_web_seeds.end())
|
||||
{
|
||||
remove_web_seed_iter(i);
|
||||
set_need_save_resume();
|
||||
}
|
||||
}
|
||||
|
||||
void torrent::disconnect_web_seed(peer_connection* p)
|
||||
|
|
|
@ -433,8 +433,9 @@ void udp_socket::open(udp const& protocol, error_code& ec)
|
|||
error_code err;
|
||||
#ifdef TORRENT_WINDOWS
|
||||
m_socket.set_option(exclusive_address_use(true), err);
|
||||
#endif
|
||||
#else
|
||||
m_socket.set_option(boost::asio::socket_base::reuse_address(true), err);
|
||||
#endif
|
||||
}
|
||||
|
||||
void udp_socket::bind(udp::endpoint const& ep, error_code& ec)
|
||||
|
|
28
src/upnp.cpp
28
src/upnp.cpp
|
@ -182,7 +182,7 @@ void upnp::discover_device_impl()
|
|||
|
||||
// returns a reference to a mapping or -1 on failure
|
||||
int upnp::add_mapping(portmap_protocol const p, int const external_port
|
||||
, int const local_port)
|
||||
, tcp::endpoint const local_ep)
|
||||
{
|
||||
TORRENT_ASSERT(is_single_thread());
|
||||
// external port 0 means _every_ port
|
||||
|
@ -190,9 +190,9 @@ int upnp::add_mapping(portmap_protocol const p, int const external_port
|
|||
|
||||
#ifndef TORRENT_DISABLE_LOGGING
|
||||
log("adding port map: [ protocol: %s ext_port: %u "
|
||||
"local_port: %u ] %s", (p == portmap_protocol::tcp?"tcp":"udp")
|
||||
"local_ep: %s ] %s", (p == portmap_protocol::tcp?"tcp":"udp")
|
||||
, external_port
|
||||
, local_port, m_disabled ? "DISABLED": "");
|
||||
, print_endpoint(local_ep).c_str(), m_disabled ? "DISABLED": "");
|
||||
#endif
|
||||
if (m_disabled) return -1;
|
||||
|
||||
|
@ -208,7 +208,7 @@ int upnp::add_mapping(portmap_protocol const p, int const external_port
|
|||
|
||||
mapping_it->protocol = p;
|
||||
mapping_it->external_port = external_port;
|
||||
mapping_it->local_port = local_port;
|
||||
mapping_it->local_ep = local_ep;
|
||||
|
||||
int const mapping_index = int(mapping_it - m_mappings.begin());
|
||||
|
||||
|
@ -224,7 +224,7 @@ int upnp::add_mapping(portmap_protocol const p, int const external_port
|
|||
m.act = mapping_t::action::add;
|
||||
m.protocol = p;
|
||||
m.external_port = external_port;
|
||||
m.local_port = local_port;
|
||||
m.local_ep = local_ep;
|
||||
|
||||
if (!d.service_namespace.empty()) update_map(d, mapping_index);
|
||||
}
|
||||
|
@ -242,8 +242,8 @@ void upnp::delete_mapping(int const mapping)
|
|||
|
||||
#ifndef TORRENT_DISABLE_LOGGING
|
||||
log("deleting port map: [ protocol: %s ext_port: %u "
|
||||
"local_port: %u ]", (m.protocol == portmap_protocol::tcp?"tcp":"udp"), m.external_port
|
||||
, m.local_port);
|
||||
"local_ep: %s ]", (m.protocol == portmap_protocol::tcp?"tcp":"udp"), m.external_port
|
||||
, print_endpoint(m.local_ep).c_str());
|
||||
#endif
|
||||
|
||||
if (m.protocol == portmap_protocol::none) return;
|
||||
|
@ -261,7 +261,7 @@ void upnp::delete_mapping(int const mapping)
|
|||
}
|
||||
|
||||
bool upnp::get_mapping(int const index
|
||||
, int& local_port
|
||||
, tcp::endpoint& local_ep
|
||||
, int& external_port
|
||||
, portmap_protocol& protocol) const
|
||||
{
|
||||
|
@ -270,7 +270,7 @@ bool upnp::get_mapping(int const index
|
|||
if (index >= int(m_mappings.size()) || index < 0) return false;
|
||||
global_mapping_t const& m = m_mappings[index];
|
||||
if (m.protocol == portmap_protocol::none) return false;
|
||||
local_port = m.local_port;
|
||||
local_ep = m.local_ep;
|
||||
external_port = m.external_port;
|
||||
protocol = m.protocol;
|
||||
return true;
|
||||
|
@ -586,7 +586,7 @@ void upnp::on_reply(udp::endpoint const& from, char* buffer
|
|||
{
|
||||
mapping_t m;
|
||||
m.act = mapping_t::action::add;
|
||||
m.local_port = j.local_port;
|
||||
m.local_ep = j.local_ep;
|
||||
m.external_port = j.external_port;
|
||||
m.protocol = j.protocol;
|
||||
d.mapping.push_back(m);
|
||||
|
@ -744,9 +744,9 @@ void upnp::create_port_mapping(http_connection& c, rootdevice& d, int const i)
|
|||
"</u:%s></s:Body></s:Envelope>"
|
||||
, soap_action, d.service_namespace.c_str(), d.mapping[i].external_port
|
||||
, (d.mapping[i].protocol == portmap_protocol::udp ? "UDP" : "TCP")
|
||||
, d.mapping[i].local_port
|
||||
, d.mapping[i].local_ep.port()
|
||||
, local_endpoint.c_str()
|
||||
, m_user_agent.c_str(), local_endpoint.c_str(), d.mapping[i].local_port
|
||||
, m_user_agent.c_str(), local_endpoint.c_str(), d.mapping[i].local_ep.port()
|
||||
, d.lease_duration, soap_action);
|
||||
|
||||
post(d, soap, soap_action);
|
||||
|
@ -817,7 +817,7 @@ void upnp::update_map(rootdevice& d, int const i)
|
|||
, std::bind(&upnp::create_port_mapping, self(), _1, std::ref(d), i));
|
||||
|
||||
d.upnp_connection->start(d.hostname, d.port
|
||||
, seconds(10), 1);
|
||||
, seconds(10), 1, NULL, false, 5, m.local_ep.address());
|
||||
}
|
||||
else if (m.act == mapping_t::action::del)
|
||||
{
|
||||
|
@ -828,7 +828,7 @@ void upnp::update_map(rootdevice& d, int const i)
|
|||
, std::ref(d), i, _5), true, default_max_bottled_buffer_size
|
||||
, std::bind(&upnp::delete_port_mapping, self(), std::ref(d), i));
|
||||
d.upnp_connection->start(d.hostname, d.port
|
||||
, seconds(10), 1);
|
||||
, seconds(10), 1, NULL, false, 5, m.local_ep.address());
|
||||
}
|
||||
|
||||
m.act = mapping_t::action::none;
|
||||
|
|
|
@ -135,6 +135,7 @@ struct mock_dht_socket final : aux::session_listen_socket
|
|||
tcp::endpoint m_local_endpoint;
|
||||
};
|
||||
|
||||
#if TORRENT_USE_IPV6
|
||||
struct mock_dht_socket6 final : aux::session_listen_socket
|
||||
{
|
||||
address get_external_address() override { return m_external_address; }
|
||||
|
@ -143,6 +144,7 @@ struct mock_dht_socket6 final : aux::session_listen_socket
|
|||
address m_external_address = addr6("2002::1");
|
||||
tcp::endpoint m_local_endpoint = tcp::endpoint(addr6("2002::1"), 6881);
|
||||
};
|
||||
#endif
|
||||
|
||||
node* get_foreign_node_stub(node_id const&, std::string const&)
|
||||
{
|
||||
|
|
|
@ -87,8 +87,9 @@ int main(int argc, char* argv[])
|
|||
deadline_timer timer(ios);
|
||||
|
||||
int const tcp_map = natpmp_handler->add_mapping(portmap_protocol::tcp
|
||||
, atoi(argv[1]), atoi(argv[1]));
|
||||
natpmp_handler->add_mapping(portmap_protocol::udp, atoi(argv[2]), atoi(argv[2]));
|
||||
, atoi(argv[1]), tcp::endpoint({}, atoi(argv[1])));
|
||||
natpmp_handler->add_mapping(portmap_protocol::udp, atoi(argv[2])
|
||||
, tcp::endpoint({}, atoi(argv[2])));
|
||||
|
||||
error_code ec;
|
||||
timer.expires_from_now(seconds(2), ec);
|
||||
|
|
|
@ -36,6 +36,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/bencode.hpp"
|
||||
#include "libtorrent/bdecode.hpp"
|
||||
#include "libtorrent/hex.hpp"
|
||||
#include "setup_transfer.hpp" // for addr6
|
||||
#include "settings.hpp"
|
||||
|
||||
#include "test.hpp"
|
||||
|
@ -112,8 +113,10 @@ TORRENT_TEST(dht_state)
|
|||
s.nids.emplace_back(addr4("0.0.0.0"), to_hash("0000000000000000000000000000000000000001"));
|
||||
s.nodes.push_back(uep("1.1.1.1", 1));
|
||||
s.nodes.push_back(uep("2.2.2.2", 2));
|
||||
#if TORRENT_USE_IPV6
|
||||
// not important that IPv6 is disabled here
|
||||
s.nids.emplace_back(addr6("::"), to_hash("0000000000000000000000000000000000000002"));
|
||||
#endif
|
||||
|
||||
session_params params(p);
|
||||
params.dht_settings = sett;
|
||||
|
|
|
@ -198,8 +198,8 @@ void run_upnp_test(char const* root_filename, char const* router_model, char con
|
|||
std::cout << "router: " << upnp_handler->router_model() << std::endl;
|
||||
TEST_EQUAL(upnp_handler->router_model(), router_model);
|
||||
|
||||
int mapping1 = upnp_handler->add_mapping(portmap_protocol::tcp, 500, 500);
|
||||
int mapping2 = upnp_handler->add_mapping(portmap_protocol::udp, 501, 501);
|
||||
int const mapping1 = upnp_handler->add_mapping(portmap_protocol::tcp, 500, ep("127.0.0.1", 500));
|
||||
int const mapping2 = upnp_handler->add_mapping(portmap_protocol::udp, 501, ep("127.0.0.1", 501));
|
||||
|
||||
for (int i = 0; i < 40; ++i)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue