From d7976982d24867c6faaf8103504ec8a10d932fa0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois-Simon=20Fauteux-Chapleau?=
 <francois-simon.fauteux-chapleau@savoirfairelinux.com>
Date: Fri, 26 Apr 2024 16:06:23 -0400
Subject: [PATCH] pupnp: unregister libupnp client handle when clearing IGDs

The PUPnP::clearIgds function is called when the UPnP context is
stopped. We don't want to keep receiving and processing IGD events after
that point, so we need to unregister our libupnp "client handle".

GitLab: #29
Change-Id: I017e6ec8aea1423d63381c9e5b3952cff7dfeb2e
---
 src/upnp/protocol/pupnp/pupnp.cpp | 18 ++++++++++++++++++
 src/upnp/protocol/pupnp/pupnp.h   |  3 +++
 2 files changed, 21 insertions(+)

diff --git a/src/upnp/protocol/pupnp/pupnp.cpp b/src/upnp/protocol/pupnp/pupnp.cpp
index 2c81e67..f0f45f4 100644
--- a/src/upnp/protocol/pupnp/pupnp.cpp
+++ b/src/upnp/protocol/pupnp/pupnp.cpp
@@ -174,6 +174,18 @@ PUPnP::registerClient()
     }
 }
 
+void
+PUPnP::unregisterClient()
+{
+    int upnp_err = UpnpUnRegisterClient(ctrlptHandle_);
+    if (upnp_err != UPNP_E_SUCCESS) {
+        if (logger_) logger_->error("PUPnP: Failed to unregister client: {}", UpnpGetErrorMessage(upnp_err));
+    } else {
+        if (logger_) logger_->debug("PUPnP: Successfully unregistered client");
+        clientRegistered_ = false;
+    }
+}
+
 void
 PUPnP::setObserver(UpnpMappingObserver* obs)
 {
@@ -264,6 +276,12 @@ PUPnP::clearIgds()
 {
     // JAMI_DBG("PUPnP: clearing IGDs and devices lists");
 
+    // We need to unregister the client to make sure that we don't keep receiving and
+    // processing IGD-related events unnecessarily, see:
+    //     https://git.jami.net/savoirfairelinux/dhtnet/-/issues/29
+    if (clientRegistered_)
+        unregisterClient();
+
     searchForIgdTimer_.cancel();
 
     igdSearchCounter_ = 0;
diff --git a/src/upnp/protocol/pupnp/pupnp.h b/src/upnp/protocol/pupnp/pupnp.h
index 03086dd..5bba6dc 100644
--- a/src/upnp/protocol/pupnp/pupnp.h
+++ b/src/upnp/protocol/pupnp/pupnp.h
@@ -124,6 +124,9 @@ private:
     // Register the client
     void registerClient();
 
+    // Unregister the client
+    void unregisterClient();
+
     // Start search for UPNP devices
     void searchForDevices();
 
-- 
GitLab