diff --git a/include/upnp/upnp_context.h b/include/upnp/upnp_context.h index d16105372438f9873846dcbdb830b154548f7f98..e29e05bdf24a6bda9c423236d7004b5b7840abcb 100644 --- a/include/upnp/upnp_context.h +++ b/include/upnp/upnp_context.h @@ -105,7 +105,6 @@ public: Mapping::sharedPtr_t reserveMapping(Mapping& requestedMap); // Release a used mapping (make it available for future use). - // TODO: The current implementation doesn't seem to do the "make it available for future use" part... fix this. void releaseMapping(const Mapping& map); // Register a controller diff --git a/src/upnp/upnp_context.cpp b/src/upnp/upnp_context.cpp index cf9b6ed3ddd501bb1b389225247b5464966f1e4e..cffab9987df22b665fa806369adcf2f45630a913 100644 --- a/src/upnp/upnp_context.cpp +++ b/src/upnp/upnp_context.cpp @@ -399,9 +399,14 @@ UPnPContext::releaseMapping(const Mapping& map) return; } - // Remove it. - requestRemoveMapping(mapPtr); - unregisterMapping(mapPtr, true); + // Reset the mapping options: disable auto-update and remove the notify callback. + // This is important because the mapping will be available again and can be reused + // by another (or the same) controller which may have different preferences. + // The notify callback is also removed to avoid calling it when the mapping is not used anymore. + mapPtr->setNotifyCallback(nullptr); + mapPtr->enableAutoUpdate(false); + mapPtr->setAvailable(true); + if (logger_) logger_->debug("Mapping {} released", mapPtr->toString()); enforceAvailableMappingsLimits(); }); } @@ -620,7 +625,7 @@ UPnPContext::enforceAvailableMappingsLimits() // If there is no valid IGD, do nothing. if (!isReady()) return; - + for (auto type : {PortType::TCP, PortType::UDP}) { int pendingCount = 0; int inProgressCount = 0;