Commit e23cbc96 authored by Adrien Béraud's avatar Adrien Béraud

nat-pmp: IGD cleanup

Change-Id: I825e71bab854b6b3d723c5601c6bff67bdf9f64e
parent 1ca77097
......@@ -45,10 +45,7 @@ class IGD
{
public:
IGD(IpAddr&& localIp = {}, IpAddr&& publicIp = {});
IGD(IGD&&) = default;
virtual ~IGD() = default;
IGD& operator=(IGD&&) = default;
bool operator==(IGD& other) const;
// Checks if the port is currently being used (i.e. the port is already opened).
......
......@@ -34,24 +34,29 @@ Mapping::Mapping(uint16_t portExternal, uint16_t portInternal,
};
Mapping::Mapping(Mapping&& other) noexcept:
#if HAVE_LIBNATPMP
renewal_(other.renewal_),
#endif
portExternal_(other.portExternal_),
portInternal_(other.portInternal_),
type_(other.type_),
description_(other.description_),
description_(std::move(other.description_)),
unique_(other.unique_)
{
other.portExternal_ = 0;
other.portInternal_ = 0;
}
Mapping::Mapping(const Mapping& other) noexcept
{
portExternal_ = other.portExternal_;
portInternal_ = other.portInternal_;
type_ = other.type_;
description_ = other.description_;
unique_ = other.unique_;
}
Mapping::Mapping(const Mapping& other) :
#if HAVE_LIBNATPMP
renewal_(other.renewal_),
#endif
portExternal_(other.portExternal_),
portInternal_(other.portInternal_),
type_(other.type_),
description_(std::move(other.description_)),
unique_(other.unique_)
{}
Mapping& Mapping::operator=(Mapping&& other) noexcept
{
......@@ -62,6 +67,9 @@ Mapping& Mapping::operator=(Mapping&& other) noexcept
other.portInternal_ = 0;
type_ = other.type_;
description_ = std::move(other.description_);
#if HAVE_LIBNATPMP
renewal_ = other.renewal_;
#endif
}
return *this;
}
......
......@@ -48,7 +48,7 @@ public:
PortType type = PortType::UDP, bool unique = true,
const std::string& description = UPNP_DEFAULT_MAPPING_DESCRIPTION);
Mapping(Mapping&& other) noexcept;
Mapping(const Mapping& other) noexcept;
Mapping(const Mapping& other);
~Mapping() = default;
Mapping& operator=(Mapping&&) noexcept;
......
......@@ -22,6 +22,9 @@
namespace jami { namespace upnp {
constexpr static unsigned int ADD_MAP_LIFETIME {3600};
constexpr static unsigned int MAX_RESTART_SEARCH_RETRY {5};
NatPmp::NatPmp()
{
clearNatPmpHdl(natpmpHdl_);
......@@ -43,7 +46,7 @@ NatPmp::NatPmp()
err = initnatpmp(&natpmpHdl_, 1, inaddr.s_addr);
}
if (err < 0) {
JAMI_ERR("NAT-PMP: Can't initialize libnatpmp -> %s", getNatPmpErrorStr(err).c_str());
JAMI_ERR("NAT-PMP: Can't initialize libnatpmp -> %s", getNatPmpErrorStr(err));
// Retry to init nat pmp in 10 seconds
std::this_thread::sleep_for(std::chrono::seconds(10));
} else {
......@@ -59,16 +62,13 @@ NatPmp::NatPmp()
while (pmpRun_) {
std::unique_lock<std::mutex> lk(validIgdMutex_);
pmpCv_.wait_until(lk, pmpIGD_->getRenewalTime(), [&] {
return not pmpRun_ or not pmpIGD_
or pmpIGD_->getRenewalTime() <= clock::now()
or not pmpIGD_->toAdd_.empty()
or not pmpIGD_->toRemove_.empty()
or not pmpIGD_->toRenew_.empty()
or restart_;
return not pmpRun_ or not pmpIGD_ or restart_
or pmpIGD_->getRenewalTime() <= clock::now();
});
if (not pmpRun_ or not pmpIGD_) break;
if (restart_) {
std::lock_guard<std::mutex> lkNat(natpmpMutex_);
closenatpmp(&natpmpHdl_);
clearNatPmpHdl(natpmpHdl_);
int err = 0;
char localHostBuf[INET_ADDRSTRLEN];
......@@ -83,7 +83,7 @@ NatPmp::NatPmp()
err = initnatpmp(&natpmpHdl_, 1, inaddr.s_addr);
}
if (err < 0) {
JAMI_ERR("NAT-PMP: Can't initialize libnatpmp -> %s", getNatPmpErrorStr(err).c_str());
JAMI_ERR("NAT-PMP: Can't initialize libnatpmp -> %s", getNatPmpErrorStr(err));
// Retry to re-init nat pmp in 10 seconds
if (pmpRun_)
pmpCv_.wait_for(lk, std::chrono::seconds(10));
......@@ -105,43 +105,49 @@ NatPmp::NatPmp()
lk.lock();
}
std::vector<Mapping> toRenew, toAdd, toRemove;
bool clearAll {false};
if (pmpIGD_) {
std::lock_guard<std::mutex> upnpLk(pmpIGD_->mapListMutex_);
if (pmpIGD_->clearAll_) {
std::lock_guard<std::mutex> lk(natpmpMutex_);
deleteAllPortMappings(*pmpIGD_, natpmpHdl_, NATPMP_PROTOCOL_UDP);
deleteAllPortMappings(*pmpIGD_, natpmpHdl_, NATPMP_PROTOCOL_TCP);
clearAll = true;
pmpIGD_->clearAll_ = false;
pmpIGD_->toRemove_.clear();
} else if (not pmpIGD_->toRemove_.empty()) {
// Remove mappings to be removed.
decltype(pmpIGD_->toRemove_) removed = std::move(pmpIGD_->toRemove_);
for (auto& m : removed) {
JAMI_DBG("NAT-PMP: Sent request to close port %s", m.toString().c_str());
lk.unlock();
removePortMapping(m);
lk.lock();
}
toRemove = std::move(pmpIGD_->toRemove_);
} else if (not pmpIGD_->toAdd_.empty()) {
// Add mappings to be added.
decltype(pmpIGD_->toAdd_) add = std::move(pmpIGD_->toAdd_);
for (auto& m : add) {
JAMI_DBG("NAT-PMP: Sent request to open port %s", m.toString().c_str());
lk.unlock();
addPortMapping(m, false);
lk.lock();
}
toAdd = std::move(pmpIGD_->toAdd_);
}
// Add mappings who's renewal times are up.
decltype(pmpIGD_->toRenew_) renew = std::move(pmpIGD_->toRenew_);
for (auto& m : renew) {
if (pmpIGD_->isMapUpForRenewal(Mapping(m.getPortExternal(), m.getPortInternal(), m.getType()), now)) {
JAMI_DBG("NAT-PMP: Sent request to renew port %s", m.toString().c_str());
lk.unlock();
addPortMapping(m, true);
lk.lock();
for (auto it = pmpIGD_->toRenew_.begin(); it != pmpIGD_->toRenew_.end(); ) {
if (it->renewal_ <= now) {
toRenew.emplace_back(std::move(*it));
it = pmpIGD_->toRenew_.erase(it);
} else {
++it;
}
}
}
lk.unlock();
if (clearAll) {
deleteAllPortMappings(NATPMP_PROTOCOL_UDP);
deleteAllPortMappings(NATPMP_PROTOCOL_TCP);
} else {
for (auto& m : toRemove) {
JAMI_DBG("NAT-PMP: Sending request to close port %s", m.toString().c_str());
removePortMapping(m);
}
for (auto& m : toRenew) {
JAMI_DBG("NAT-PMP: Sending request to renew port %s", m.toString().c_str());
addPortMapping(m, true);
}
}
for (auto& m : toAdd) {
JAMI_DBG("NAT-PMP: Sending request to open port %s", m.toString().c_str());
addPortMapping(m, false);
}
}
std::lock_guard<std::mutex> lk(natpmpMutex_);
closenatpmp(&natpmpHdl_);
......@@ -207,7 +213,6 @@ NatPmp::requestMappingAdd(IGD* igd, uint16_t port_external, uint16_t port_intern
void
NatPmp::addPortMapping(Mapping& mapping, bool renew)
{
std::lock_guard<std::mutex> lk1(natpmpMutex_);
std::unique_lock<std::mutex> lk2(validIgdMutex_);
Mapping mapToAdd(mapping.getPortExternal(),
mapping.getPortInternal(),
......@@ -219,7 +224,7 @@ NatPmp::addPortMapping(Mapping& mapping, bool renew)
mapping.getPortExternal(),
ADD_MAP_LIFETIME);
if (err < 0) {
JAMI_ERR("NAT-PMP: Can't send open port request -> %s %i", getNatPmpErrorStr(err).c_str(), errno);
JAMI_ERR("NAT-PMP: Can't send open port request -> %s %i", getNatPmpErrorStr(err), errno);
mapping.renewal_ = clock::now() + std::chrono::minutes(1);
if (pmpIGD_) {
pmpIGD_->removeMapToAdd(mapping);
......@@ -232,21 +237,21 @@ NatPmp::addPortMapping(Mapping& mapping, bool renew)
natpmpresp_t response;
std::this_thread::sleep_for(std::chrono::milliseconds(2));
auto r = readnatpmpresponseorretry(&natpmpHdl_, &response);
if (r < 0 && r != NATPMP_TRYAGAIN) {
JAMI_ERR("NAT-PMP: Can't register port mapping %s", mapping.toString().c_str());
break;
} else if (r != NATPMP_TRYAGAIN) {
mapping.renewal_ = clock::now()
+ std::chrono::seconds(response.pnu.newportmapping.lifetime/2);
if (pmpIGD_) {
if (not renew) {
JAMI_WARN("NAT-PMP: Opened port %s", mapping.toString().c_str());
pmpIGD_->removeMapToAdd(mapping);
if (r != NATPMP_TRYAGAIN) {
if (r < 0) {
JAMI_ERR("NAT-PMP: Can't register port mapping %s: %s", mapping.toString().c_str(), getNatPmpErrorStr(r));
} else {
mapping.renewal_ = clock::now()
+ std::chrono::seconds(response.pnu.newportmapping.lifetime/2);
if (pmpIGD_) {
if (not renew) {
JAMI_WARN("NAT-PMP: Opened port %s", mapping.toString().c_str());
lk2.unlock();
notifyContextPortOpenCb_(pmpIGD_->publicIp_, std::move(mapToAdd), true);
} else {
JAMI_WARN("NAT-PMP: Renewed port %s", mapping.toString().c_str());
}
pmpIGD_->addMapToRenew(std::move(mapping));
lk2.unlock();
notifyContextPortOpenCb_(pmpIGD_->publicIp_, std::move(mapToAdd), true);
} else {
JAMI_WARN("NAT-PMP: Renewed port %s", mapping.toString().c_str());
}
}
break;
......@@ -281,9 +286,9 @@ NatPmp::removePortMapping(Mapping& mapping)
mapping.getType() == PortType::UDP ? NATPMP_PROTOCOL_UDP : NATPMP_PROTOCOL_TCP,
mapping.getPortInternal(),
mapping.getPortExternal(),
REMOVE_MAP_LIFETIME);
0);
if (err < 0) {
JAMI_ERR("NAT-PMP: Can't send close port request -> %s", getNatPmpErrorStr(err).c_str());
JAMI_ERR("NAT-PMP: Can't send close port request -> %s", getNatPmpErrorStr(err));
mapping.renewal_ = clock::now() + std::chrono::minutes(1);
if (pmpIGD_) {
pmpIGD_->removeMapToRemove(mapping);
......@@ -331,7 +336,7 @@ NatPmp::searchForPmpIgd()
int err = sendpublicaddressrequest(&natpmpHdl_);
if (err < 0) {
std::lock_guard<std::mutex> lk2(validIgdMutex_);
JAMI_ERR("NAT-PMP: Can't send search request -> %s", getNatPmpErrorStr(err).c_str());
JAMI_ERR("NAT-PMP: Can't send search request -> %s", getNatPmpErrorStr(err));
if (pmpIGD_) {
updateIgdListCb_(this, pmpIGD_.get(), pmpIGD_.get()->publicIp_, false);
}
......@@ -366,7 +371,7 @@ NatPmp::searchForPmpIgd()
// Store public Ip address.
std::string publicIpStr(std::move(pmpIGD_.get()->publicIp_.toString()));
// Add the igd to the upnp context class list.
lk2.unlock();
lk2.unlock();
if (updateIgdListCb_(this, pmpIGD_.get(), pmpIGD_.get()->publicIp_, true)) {
JAMI_DBG("NAT-PMP: IGD with public IP %s was added to the list", publicIpStr.c_str());
} else {
......@@ -381,46 +386,9 @@ NatPmp::searchForPmpIgd()
}
void
NatPmp::addPortMapping(const PMPIGD& /*pmp_igd*/, natpmp_t& natpmp, GlobalMapping& mapping, bool remove) const
{
if (sendnewportmappingrequest(&natpmp,
mapping.getType() == PortType::UDP ? NATPMP_PROTOCOL_UDP : NATPMP_PROTOCOL_TCP,
mapping.getPortInternal(),
mapping.getPortExternal(), remove ? 0 : 3600) < 0) {
JAMI_ERR("NAT-PMP: Can't send port mapping request");
mapping.renewal_ = clock::now() + std::chrono::minutes(1);
return;
}
while (pmpRun_) {
natpmpresp_t response;
std::this_thread::sleep_for(std::chrono::milliseconds(2));
auto r = readnatpmpresponseorretry(&natpmp, &response);
if (r < 0 && r != NATPMP_TRYAGAIN) {
JAMI_ERR("NAT-PMP: Can't %sregister port mapping", remove ? "un" : "");
break;
}
else if (r != NATPMP_TRYAGAIN) {
mapping.renewal_ = clock::now()
+ std::chrono::seconds(response.pnu.newportmapping.lifetime/2);
if (remove) {
JAMI_WARN("NAT-PMP: Closed port %d:%d %s", mapping.getPortInternal(),
mapping.getPortExternal(),
mapping.getType() == PortType::UDP ? "UDP" : "TCP");
} else {
JAMI_WARN("NAT-PMP: Opened port %d:%d %s", mapping.getPortInternal(),
mapping.getPortExternal(),
mapping.getType() == PortType::UDP ? "UDP" : "TCP");
}
break;
}
}
}
void
NatPmp::deleteAllPortMappings(const PMPIGD& /*pmp_igd*/, natpmp_t& natpmp, int proto) const
NatPmp::deleteAllPortMappings(int proto)
{
if (sendnewportmappingrequest(&natpmp, proto, 0, 0, 0) < 0) {
if (sendnewportmappingrequest(&natpmpHdl_, proto, 0, 0, 0) < 0) {
JAMI_ERR("NAT-PMP: Can't send all port mapping removal request");
return;
}
......@@ -428,12 +396,10 @@ NatPmp::deleteAllPortMappings(const PMPIGD& /*pmp_igd*/, natpmp_t& natpmp, int p
while (pmpRun_) {
natpmpresp_t response;
std::this_thread::sleep_for(std::chrono::milliseconds(2));
auto r = readnatpmpresponseorretry(&natpmp, &response);
if (r < 0 && r != NATPMP_TRYAGAIN) {
JAMI_ERR("NAT-PMP: Can't remove all port mappings");
break;
}
else if (r != NATPMP_TRYAGAIN) {
auto r = readnatpmpresponseorretry(&natpmpHdl_, &response);
if (r != NATPMP_TRYAGAIN) {
if (r < 0)
JAMI_ERR("NAT-PMP: Can't remove all port mappings: %s", getNatPmpErrorStr(r));
break;
}
}
......@@ -442,43 +408,38 @@ NatPmp::deleteAllPortMappings(const PMPIGD& /*pmp_igd*/, natpmp_t& natpmp, int p
void
NatPmp::clearNatPmpHdl(natpmp_t& hdl)
{
memset(&hdl.s, 0, sizeof(hdl.s));
memset(&hdl.gateway, 0, sizeof(in_addr_t));
memset(&hdl.has_pending_request, 0, sizeof(hdl.has_pending_request));
memset(&hdl.pending_request, 0, sizeof(hdl.pending_request));
memset(&hdl.pending_request_len, 0, sizeof(hdl.pending_request_len));
memset(&hdl.try_number, 0, sizeof(hdl.try_number));
memset(&hdl.retry_time.tv_sec, 0, sizeof(hdl.retry_time.tv_sec));
memset(&hdl.retry_time.tv_usec, 0, sizeof(hdl.retry_time.tv_usec));
memset(&hdl, 0, sizeof(hdl));
}
std::string
const char*
NatPmp::getNatPmpErrorStr(int errorCode)
{
std::string errorStr {};
#ifdef ENABLE_STRNATPMPERR
return strnatpmperr(errorCode);
#else
switch(errorCode) {
case NATPMP_ERR_INVALIDARGS: errorStr = "INVALIDARGS"; break;
case NATPMP_ERR_SOCKETERROR: errorStr = "SOCKETERROR"; break;
case NATPMP_ERR_CANNOTGETGATEWAY: errorStr = "CANNOTGETGATEWAY"; break;
case NATPMP_ERR_CLOSEERR: errorStr = "CLOSEERR"; break;
case NATPMP_ERR_RECVFROM: errorStr = "RECVFROM"; break;
case NATPMP_ERR_NOPENDINGREQ: errorStr = "NOPENDINGREQ"; break;
case NATPMP_ERR_NOGATEWAYSUPPORT: errorStr = "NOGATEWAYSUPPORT"; break;
case NATPMP_ERR_CONNECTERR: errorStr = "CONNECTERR"; break;
case NATPMP_ERR_WRONGPACKETSOURCE: errorStr = "WRONGPACKETSOURCE"; break;
case NATPMP_ERR_SENDERR: errorStr = "SENDERR"; break;
case NATPMP_ERR_FCNTLERROR: errorStr = "FCNTLERROR"; break;
case NATPMP_ERR_GETTIMEOFDAYERR: errorStr = "GETTIMEOFDAYERR"; break;
case NATPMP_ERR_UNSUPPORTEDVERSION: errorStr = "UNSUPPORTEDVERSION"; break;
case NATPMP_ERR_UNSUPPORTEDOPCODE: errorStr = "UNSUPPORTEDOPCODE"; break;
case NATPMP_ERR_UNDEFINEDERROR: errorStr = "UNDEFINEDERROR"; break;
case NATPMP_ERR_NOTAUTHORIZED: errorStr = "NOTAUTHORIZED"; break;
case NATPMP_ERR_NETWORKFAILURE: errorStr = "NETWORKFAILURE"; break;
case NATPMP_ERR_OUTOFRESOURCES: errorStr = "OUTOFRESOURCES"; break;
case NATPMP_TRYAGAIN: errorStr = "TRYAGAIN"; break;
default: errorStr = "UNKNOWNERR"; break;
case NATPMP_ERR_INVALIDARGS: return "INVALIDARGS"; break;
case NATPMP_ERR_SOCKETERROR: return "SOCKETERROR"; break;
case NATPMP_ERR_CANNOTGETGATEWAY: return "CANNOTGETGATEWAY"; break;
case NATPMP_ERR_CLOSEERR: return "CLOSEERR"; break;
case NATPMP_ERR_RECVFROM: return "RECVFROM"; break;
case NATPMP_ERR_NOPENDINGREQ: return "NOPENDINGREQ"; break;
case NATPMP_ERR_NOGATEWAYSUPPORT: return "NOGATEWAYSUPPORT"; break;
case NATPMP_ERR_CONNECTERR: return "CONNECTERR"; break;
case NATPMP_ERR_WRONGPACKETSOURCE: return "WRONGPACKETSOURCE"; break;
case NATPMP_ERR_SENDERR: return "SENDERR"; break;
case NATPMP_ERR_FCNTLERROR: return "FCNTLERROR"; break;
case NATPMP_ERR_GETTIMEOFDAYERR: return "GETTIMEOFDAYERR"; break;
case NATPMP_ERR_UNSUPPORTEDVERSION: return "UNSUPPORTEDVERSION"; break;
case NATPMP_ERR_UNSUPPORTEDOPCODE: return "UNSUPPORTEDOPCODE"; break;
case NATPMP_ERR_UNDEFINEDERROR: return "UNDEFINEDERROR"; break;
case NATPMP_ERR_NOTAUTHORIZED: return "NOTAUTHORIZED"; break;
case NATPMP_ERR_NETWORKFAILURE: return "NETWORKFAILURE"; break;
case NATPMP_ERR_OUTOFRESOURCES: return "OUTOFRESOURCES"; break;
case NATPMP_TRYAGAIN: return "TRYAGAIN"; break;
default: return "UNKNOWNERR"; break;
}
return errorStr;
#endif
}
}} // namespace jami::upnp
\ No newline at end of file
......@@ -34,6 +34,8 @@
#include "noncopyable.h"
#include "compiler_intrinsics.h"
// uncomment to enable native natpmp error messages
//#define ENABLE_STRNATPMPERR 1
#include <natpmp.h>
#include <atomic>
......@@ -45,10 +47,6 @@ class IpAddr;
namespace jami { namespace upnp {
constexpr static unsigned int ADD_MAP_LIFETIME {3600};
constexpr static unsigned int REMOVE_MAP_LIFETIME {0};
constexpr static unsigned int MAX_RESTART_SEARCH_RETRY {5};
class NatPmp : public UPnPProtocol
{
public:
......@@ -66,13 +64,9 @@ public:
// Tries to add mapping.
void requestMappingAdd(IGD* igd, uint16_t port_external, uint16_t port_internal, PortType type) override;
// Adds a port mapping.
void addPortMapping(Mapping& mapping, bool renew);
// Removes a mapping.
void requestMappingRemove(const Mapping& igdMapping) override;
// Removes a port mapping.
void removePortMapping(Mapping& mapping);
// Removes all local mappings of IGD that we're added by the application.
void removeAllLocalMappings(IGD* igd) override;
......@@ -80,11 +74,14 @@ public:
private:
void searchForPmpIgd();
// Adds (or deletes) a port mapping.
void addPortMapping(const PMPIGD& pmp_igd, natpmp_t& natpmp, GlobalMapping& mapping, bool remove=false) const;
// Adds a port mapping.
void addPortMapping(Mapping& mapping, bool renew);
// Removes a port mapping.
void removePortMapping(Mapping& mapping);
//void addPortMapping(const PMPIGD& pmp_igd, natpmp_t& natpmp, GlobalMapping& mapping, bool remove=false) const;
// Deletes all port mappings.
void deleteAllPortMappings(const PMPIGD& pmp_igd, natpmp_t& natpmp, int proto) const;
void deleteAllPortMappings(int proto);
private:
NON_COPYABLE(NatPmp);
......@@ -103,7 +100,7 @@ private:
// Clears the natpmp struct.
void clearNatPmpHdl(natpmp_t& hdl);
// Gets NAT-PMP error code string.
std::string getNatPmpErrorStr(int errorCode);
const char* getNatPmpErrorStr(int errorCode);
};
}} // namespace jami::upnp
......@@ -18,16 +18,13 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "pmp_igd.h"
#include <algorithm>
namespace jami { namespace upnp {
PMPIGD::~PMPIGD()
{
tcpMappings_.clear();
udpMappings_.clear();
toRemove_.clear();
toRenew_.clear();
toAdd_.clear();
}
bool
PMPIGD::operator==(IGD& other) const
{
......@@ -47,7 +44,7 @@ void
PMPIGD::addMapToAdd(Mapping map)
{
std::lock_guard<std::mutex> lk(mapListMutex_);
toAdd_.push_back(std::move(map));
toAdd_.emplace_back(std::move(map));
}
void
PMPIGD::removeMapToAdd(const Mapping& map)
......@@ -69,8 +66,9 @@ PMPIGD::addMapToRenew(Mapping map)
return;
}
}
toRenew_.push_back(std::move(map));
toRenew_.emplace_back(std::move(map));
}
void
PMPIGD::removeMapToRenew(const Mapping& map)
{
......@@ -82,6 +80,7 @@ PMPIGD::removeMapToRenew(const Mapping& map)
}
}
}
void
PMPIGD::addMapToRemove(Mapping map)
{
......@@ -91,8 +90,9 @@ PMPIGD::addMapToRemove(Mapping map)
return;
}
}
toRemove_.push_back(std::move(map));
toRemove_.emplace_back(std::move(map));
}
void
PMPIGD::removeMapToRemove(const Mapping& map)
{
......@@ -104,6 +104,7 @@ PMPIGD::removeMapToRemove(const Mapping& map)
}
}
}
void
PMPIGD::clearMappings()
{
......@@ -113,49 +114,16 @@ PMPIGD::clearMappings()
udpMappings_.clear();
tcpMappings_.clear();
}
bool
PMPIGD::isMapUpForRenewal(const Mapping& map, time_point now)
{
std::lock_guard<std::mutex> lk(mapListMutex_);
for (auto it = toRenew_.cbegin(); it != toRenew_.cend(); it++) {
if (*it == map) {
auto& element = (*it);
if (element.renewal_ < now)
return true;
else
return false;
}
}
return false;
}
Mapping*
PMPIGD::getNextMappingToRenew()
{
std::lock_guard<std::mutex> lk(mapListMutex_);
Mapping* mapping {nullptr};
if (not toAdd_.empty()) {
return (Mapping*)&toAdd_.front();
} else {
if (not toRenew_.empty()) {
for (auto it = toRenew_.begin(); it != toRenew_.end(); it++) {
auto& element = (*it);
if (!mapping or element.renewal_ < mapping->renewal_) {
mapping = &element;
}
}
}
}
return (Mapping*)mapping;
}
time_point
PMPIGD::getRenewalTime()
{
std::unique_lock<std::mutex> lk(mapListMutex_);
lk.unlock();
const auto next = getNextMappingToRenew();
lk.lock();
auto nextTime = std::min(renewal_, next ? next->renewal_ : time_point::max());
return toRenew_.empty() ? nextTime : std::min(nextTime, time_point::min());
if (clearAll_ or not toAdd_.empty() or not toRemove_.empty())
return time_point::min();
auto nextTime = renewal_;
for (const auto& m : toRenew_)
nextTime = std::min(nextTime, m.renewal_);
return nextTime;
}
}} // namespace jami::upnp
\ No newline at end of file
......@@ -19,23 +19,21 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#pragma once
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "../igd.h"
#include "../global_mapping.h"
#include "noncopyable.h"