merged RC_1_1 into master

This commit is contained in:
arvidn 2017-05-12 21:46:45 -04:00
commit e0fa1cd247
17 changed files with 108 additions and 48 deletions

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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())
{

View File

@ -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());

View File

@ -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;
}

View File

@ -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)

View File

@ -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)

View File

@ -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;

View File

@ -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&)
{

View File

@ -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);

View File

@ -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;

View File

@ -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)
{