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
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
@@ -175,6 +175,18 @@
 }
 
 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)
 {
     observer_ = obs;
@@ -264,6 +276,12 @@
 {
     // 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 @@
     // Register the client
     void registerClient();
 
+    // Unregister the client
+    void unregisterClient();
+
     // Start search for UPNP devices
     void searchForDevices();