Skip to content
Snippets Groups Projects
Commit e9a6da65 authored by Mohamed Chibani's avatar Mohamed Chibani
Browse files

upnp: unconditionally remove failed mappings

In the previous implementation, a failed mapping was not removed if it's
beeing used. The responsability was left to the owner to release it when
done with it. This requires that all the owners implement the mapping
callback and properly release the mapping. This might be somehow cumbersome
and prune to error.
Now, a failed mapping is automatically removed, and no further action is
required from the owner. The mapping's owner will still receive a notification
callback (if registered) when the state of the mapping changes to failed (or
to any other state).

Change-Id: I014ba3906b836efce3173fb22fbe298a4023db7e
Gitlab: #335
parent 27504587
Branches
No related tags found
No related merge requests found
...@@ -800,6 +800,7 @@ IceTransport::Impl::requestUpnpMappings() ...@@ -800,6 +800,7 @@ IceTransport::Impl::requestUpnpMappings()
} }
} else { } else {
JAMI_ERR("[ice:%p]: UPNP mapping request failed!", this); JAMI_ERR("[ice:%p]: UPNP mapping request failed!", this);
upnp_->releaseMapping(requestedMap);
} }
} }
} }
......
...@@ -115,10 +115,8 @@ UPnPContext::StopUpnp() ...@@ -115,10 +115,8 @@ UPnPContext::StopUpnp()
for (auto const& map : toRemoveList) { for (auto const& map : toRemoveList) {
map->cancelTimeoutTimer(); map->cancelTimeoutTimer();
updateMappingState(map, MappingState::FAILED); updateMappingState(map, MappingState::FAILED);
if (map->isAvailable()) {
unregisterMapping(map); unregisterMapping(map);
} }
}
for (auto const& [_, protocol] : protocolList_) { for (auto const& [_, protocol] : protocolList_) {
protocol->clearIgds(); protocol->clearIgds();
...@@ -529,6 +527,18 @@ UPnPContext::updateMappingList(bool async) ...@@ -529,6 +527,18 @@ UPnPContext::updateMappingList(bool async)
status.inProgressCount_, status.inProgressCount_,
status.failedCount_); status.failedCount_);
if (status.failedCount_ > 0) {
std::lock_guard<std::mutex> lock(mappingMutex_);
auto const& mappingList = getMappingList(type);
for (auto const& [_, map] : mappingList) {
if (map->getState() == MappingState::FAILED) {
JAMI_DBG("Mapping status [%s] - Available [%s]",
map->toString(true).c_str(),
map->isAvailable() ? "YES" : "NO");
}
}
}
int toRequestCount = (int) minOpenPortLimit_[idx] int toRequestCount = (int) minOpenPortLimit_[idx]
- (int) (status.readyCount_ + status.inProgressCount_ - (int) (status.readyCount_ + status.inProgressCount_
+ status.pendingCount_); + status.pendingCount_);
...@@ -626,13 +636,10 @@ UPnPContext::pruneUnMatchedMappings(const std::shared_ptr<IGD>& igd, ...@@ -626,13 +636,10 @@ UPnPContext::pruneUnMatchedMappings(const std::shared_ptr<IGD>& igd,
for (auto const& map : toRemoveList) { for (auto const& map : toRemoveList) {
updateMappingState(map, MappingState::FAILED); updateMappingState(map, MappingState::FAILED);
// Remove if not used.
if (map->isAvailable()) {
unregisterMapping(map); unregisterMapping(map);
} }
} }
} }
}
void void
UPnPContext::pruneUnTrackedMappings(const std::shared_ptr<IGD>& igd, UPnPContext::pruneUnTrackedMappings(const std::shared_ptr<IGD>& igd,
...@@ -695,11 +702,9 @@ UPnPContext::pruneMappingsWithInvalidIgds(const std::shared_ptr<IGD>& igd) ...@@ -695,11 +702,9 @@ UPnPContext::pruneMappingsWithInvalidIgds(const std::shared_ptr<IGD>& igd)
igd->getProtocolName()); igd->getProtocolName());
map->cancelTimeoutTimer(); map->cancelTimeoutTimer();
updateMappingState(map, MappingState::FAILED); updateMappingState(map, MappingState::FAILED);
if (map->isAvailable()) {
unregisterMapping(map); unregisterMapping(map);
} }
} }
}
void void
UPnPContext::processPendingRequests(const std::shared_ptr<IGD>& igd) UPnPContext::processPendingRequests(const std::shared_ptr<IGD>& igd)
...@@ -922,11 +927,8 @@ UPnPContext::onMappingAdded(const std::shared_ptr<IGD>& igd, const Mapping& mapR ...@@ -922,11 +927,8 @@ UPnPContext::onMappingAdded(const std::shared_ptr<IGD>& igd, const Mapping& mapR
map->toString().c_str(), map->toString().c_str(),
igd->getLocalIp().toString().c_str()); igd->getLocalIp().toString().c_str());
updateMappingState(map, MappingState::FAILED); updateMappingState(map, MappingState::FAILED);
// Remove if not used.
if (map->isAvailable()) {
unregisterMapping(map); unregisterMapping(map);
} }
}
// We have a response, so cancel the time-out. // We have a response, so cancel the time-out.
map->cancelTimeoutTimer(); map->cancelTimeoutTimer();
...@@ -1195,12 +1197,8 @@ UPnPContext::onRequestTimeOut(const std::shared_ptr<IGD>& igd, const Mapping::sh ...@@ -1195,12 +1197,8 @@ UPnPContext::onRequestTimeOut(const std::shared_ptr<IGD>& igd, const Mapping::sh
// Considere time-out as failure. // Considere time-out as failure.
updateMappingState(map, MappingState::FAILED); updateMappingState(map, MappingState::FAILED);
// Remove it if not used.
if (map->isAvailable()) {
unregisterMapping(map); unregisterMapping(map);
} }
}
void void
UPnPContext::updateMappingState(const Mapping::sharedPtr_t& map, MappingState newState, bool notify) UPnPContext::updateMappingState(const Mapping::sharedPtr_t& map, MappingState newState, bool notify)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment