add limit of max 50 upnp mappings and recover free global mappings (#2470)

This commit is contained in:
Alden Torres 2017-10-24 10:16:22 -04:00 committed by Arvid Norberg
parent 989a65f18e
commit 174a2ca65f
2 changed files with 36 additions and 0 deletions

View File

@ -63,6 +63,11 @@ namespace libtorrent {
using namespace aux;
// due to the recursive nature of update_map, it's necessary to
// limit the internal list of global mappings to a small size
// this can be changed once the entire UPnP code is refactored
constexpr std::size_t max_global_mappings = 50;
namespace upnp_errors
{
boost::system::error_code make_error_code(error_code_enum e)
@ -227,6 +232,14 @@ port_mapping_t upnp::add_mapping(portmap_protocol const p, int const external_po
if (mapping_it == m_mappings.end())
{
TORRENT_ASSERT(m_mappings.size() <= max_global_mappings);
if (m_mappings.size() >= max_global_mappings)
{
#ifndef TORRENT_DISABLE_LOGGING
log("too many mappings registered");
#endif
return port_mapping_t{-1};
}
m_mappings.push_back(global_mapping_t());
mapping_it = m_mappings.end() - 1;
}
@ -1560,6 +1573,14 @@ void upnp::on_upnp_unmap_response(error_code const& e
d.mapping[mapping].protocol = portmap_protocol::none;
// free the slot in global mappings
auto pred = [mapping](rootdevice const& rd)
{ return rd.mapping[mapping].protocol == portmap_protocol::none; };
if (std::all_of(m_devices.begin(), m_devices.end(), pred))
{
m_mappings[mapping].protocol = portmap_protocol::none;
}
next(d, mapping);
}

View File

@ -260,3 +260,18 @@ TORRENT_TEST(upnp)
run_upnp_test(combine_path("..", "root2.xml").c_str(), "D-Link Router", "WANIPConnection", 1);
run_upnp_test(combine_path("..", "root3.xml").c_str(), "D-Link Router", "WANIPConnection_2", 2);
}
TORRENT_TEST(upnp_max_mappings)
{
lt::io_service ios;
upnp_callback cb;
auto upnp_handler = std::make_shared<upnp>(ios, "test agent", cb, false);
for (int i = 0; i < 50; ++i)
{
auto const mapping = upnp_handler->add_mapping(portmap_protocol::tcp
, 500 + i, ep("127.0.0.1", 500 + i));
TEST_CHECK(mapping != port_mapping_t{-1});
}
}