forked from premiere/premiere-libtorrent
add limit of max 50 upnp mappings and recover free global mappings (#2470)
This commit is contained in:
parent
989a65f18e
commit
174a2ca65f
21
src/upnp.cpp
21
src/upnp.cpp
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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});
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue