diff --git a/include/upnp/upnp_context.h b/include/upnp/upnp_context.h index 46254dc1..57f6d826 100644 --- a/include/upnp/upnp_context.h +++ b/include/upnp/upnp_context.h @@ -138,6 +138,17 @@ class UPnPContext : public UpnpMappingObserver // then the state of all pending mappings is set to FAILED. void setIgdDiscoveryTimeout(std::chrono::milliseconds timeout); + // Set limits on the number of "available" mappings that the UPnPContext + // can keep at any given time. An available mapping is one that has been + // opened, but isn't being used by any Controller. The context will attempt + // to close or open mappings as needed to keep the number of available + // mappings between `minCount` and `maxCount`. + void setAvailableMappingsLimits(PortType type, unsigned minCount, unsigned maxCount) { + unsigned index = (type == PortType::TCP) ? 0 : 1; + maxAvailableMappings_[index] = maxCount; + minAvailableMappings_[index] = (minCount <= maxCount) ? minCount : 0; + } + private: // Initialization void init(); @@ -286,8 +297,8 @@ class UPnPContext : public UpnpMappingObserver // Minimum and maximum limits on the number of available // mappings to keep in the list at any given time - static constexpr unsigned minAvailableMappings_[2] {4, 8}; - static constexpr unsigned maxAvailableMappings_[2] {8, 12}; + unsigned minAvailableMappings_[2] {4, 8}; + unsigned maxAvailableMappings_[2] {8, 12}; unsigned getMinAvailableMappings(PortType type) { unsigned index = (type == PortType::TCP) ? 0 : 1; return minAvailableMappings_[index]; diff --git a/tools/upnp/upnpctrl.cpp b/tools/upnp/upnpctrl.cpp index 7c4febff..ba13de58 100644 --- a/tools/upnp/upnpctrl.cpp +++ b/tools/upnp/upnpctrl.cpp @@ -62,6 +62,8 @@ main(int argc, char** argv) auto ioContext = std::make_shared(); std::shared_ptr logger = dht::log::getStdLogger(); auto upnpContext = std::make_shared(ioContext, logger); + upnpContext->setAvailableMappingsLimits(dhtnet::upnp::PortType::TCP, 0, 0); + upnpContext->setAvailableMappingsLimits(dhtnet::upnp::PortType::UDP, 0, 0); auto ioContextRunner = std::make_shared([context = ioContext]() { try {