diff --git a/src/upnp/protocol/pupnp/pupnp.cpp b/src/upnp/protocol/pupnp/pupnp.cpp index c6779a5ad1256e8e2f6ef7b09fa74701fc2fd6e8..2be07ee59da7e51e921ad27b351d9bd07426b63d 100644 --- a/src/upnp/protocol/pupnp/pupnp.cpp +++ b/src/upnp/protocol/pupnp/pupnp.cpp @@ -94,6 +94,9 @@ errorOnResponse(IXML_Document* doc) return false; } + +// UPNP class implementation + PUPnP::PUPnP() { if (not initUpnpLib()) @@ -168,6 +171,7 @@ PUPnP::~PUPnP() removeAllLocalMappings(it); } validIgdList_.clear(); + clientRegistered_ = false; UpnpUnRegisterClient(ctrlptHandle_); } @@ -646,8 +650,10 @@ PUPnP::eventTypeToString(Upnp_EventType eventType) int PUPnP::ctrlPtCallback(Upnp_EventType event_type, const void* event, void* user_data) { - if (auto pupnp = static_cast<PUPnP*>(user_data)) + if (auto pupnp = static_cast<PUPnP*>(user_data)) { + std::lock_guard<std::mutex> lk(pupnp->ctrlptMutex_); return pupnp->handleCtrlPtUPnPEvents(event_type, event); + } JAMI_WARN("PUPnP: Control point callback without PUPnP"); return 0; @@ -786,6 +792,10 @@ PUPnP::processDiscoverySubscriptionExpired(const std::string& eventSubUrl) int PUPnP::handleCtrlPtUPnPEvents(Upnp_EventType event_type, const void* event) { + // Ignore if not registered + if (not PUPnP::clientRegistered_) + return UPNP_E_SUCCESS; + switch (event_type) { // "ALIVE" events are processed as "SEARCH RESULT". It might be usefull // if "SEARCH RESULT" was missed. diff --git a/src/upnp/protocol/pupnp/pupnp.h b/src/upnp/protocol/pupnp/pupnp.h index cdcb8594c49a62e16bd39240559f36757be6d49b..648b15f138e68dd54827693d78047fa3f1871047 100644 --- a/src/upnp/protocol/pupnp/pupnp.h +++ b/src/upnp/protocol/pupnp/pupnp.h @@ -214,6 +214,10 @@ private: static const char* eventTypeToString(Upnp_EventType eventType); private: + // Indicates of the client is registered. Since at most only one instance + // of this class is created, using a static is unambiguous. + std::atomic_bool clientRegistered_ {false}; + std::weak_ptr<PUPnP> weak() { return std::static_pointer_cast<PUPnP>(shared_from_this()); } NON_COPYABLE(PUPnP); @@ -235,8 +239,7 @@ private: std::mutex ctrlptMutex_; // Mutex for client handle protection. UpnpClient_Handle ctrlptHandle_ {-1}; // Control point handle. - std::atomic_bool clientRegistered_ {false}; // Indicates of the client is registered. - std::atomic_bool searchForIgd_ {false}; // Variable to signal thread for a search. + std::atomic_bool searchForIgd_ {false}; // Variable to signal thread for a search. }; } // namespace upnp