Remove the upnp API

Sun, 23 Oct 2022 22:31:02 -0500

author
Gary Kramlich <grim@reaperworld.com>
date
Sun, 23 Oct 2022 22:31:02 -0500
changeset 41828
023b57b090f6
parent 41827
c0c9eeca7d4b
child 41829
13997c67710d

Remove the upnp API

We already know that GUPnP isn't going to work for us and have started
traversity to fill that gap. So in the meantime, we can just get rid of the
existing UPnP API.

Testing Done:
Compiled

Reviewed at https://reviews.imfreedom.org/r/1959/

libpurple/meson.build file | annotate | diff | comparison | revisions
libpurple/network.c file | annotate | diff | comparison | revisions
libpurple/upnp.c file | annotate | diff | comparison | revisions
libpurple/upnp.h file | annotate | diff | comparison | revisions
meson.build file | annotate | diff | comparison | revisions
pidgin/prefs/pidginnetworkprefs.c file | annotate | diff | comparison | revisions
po/POTFILES.in file | annotate | diff | comparison | revisions
subprojects/gupnp-igd-1.0.wrap file | annotate | diff | comparison | revisions
--- a/libpurple/meson.build	Sun Oct 23 22:21:46 2022 -0500
+++ b/libpurple/meson.build	Sun Oct 23 22:31:02 2022 -0500
@@ -101,7 +101,6 @@
 	'signals.c',
 	'status.c',
 	'stun.c',
-	'upnp.c',
 	'util.c',
 	'version.c',
 	'xfer.c',
@@ -210,7 +209,6 @@
 	'status.h',
 	'stun.h',
 	'tests.h',
-	'upnp.h',
 	'util.h',
 	'xfer.h',
 	'xmlnode.h',
@@ -323,9 +321,9 @@
                     install : true,
                     version : PURPLE_LIB_VERSION,
                     dependencies : # static_link_libs
-                        [dnsapi, ws2_32, glib, gio, gplugin_dep, gupnp,
-                         gupnp_igd, libsoup, libxml, gdk_pixbuf, gstreamer,
-                         gstreamer_app, json, sqlite3, math])
+                        [dnsapi, ws2_32, glib, gio, gplugin_dep, libsoup,
+                         libxml, gdk_pixbuf, gstreamer, gstreamer_app, json,
+                         sqlite3, math])
 
 install_headers(purple_coreheaders,
                 subdir : purple_include_base)
--- a/libpurple/network.c	Sun Oct 23 22:21:46 2022 -0500
+++ b/libpurple/network.c	Sun Oct 23 22:31:02 2022 -0500
@@ -46,7 +46,6 @@
 #include "network.h"
 #include "prefs.h"
 #include "stun.h"
-#include "upnp.h"
 
 static gboolean force_online = FALSE;
 
@@ -134,12 +133,6 @@
 		return;
 	}
 
-	/* Attempt to get the IP from a NAT device using UPnP */
-	ip = purple_upnp_get_public_ip();
-	if (ip != NULL) {
-		return;
-	}
-
 	/* Attempt to get the IP from a NAT device using NAT-PMP */
 	ip = purple_pmp_get_public_ip();
 	if (ip != NULL) {
@@ -167,12 +160,6 @@
 			return g_strdup(stun->publicip);
 		}
 
-		/* Attempt to get the IP from a NAT device using UPnP */
-		ip = purple_upnp_get_public_ip();
-		if (ip != NULL) {
-			return g_strdup(ip);
-		}
-
 		/* Attempt to get the IP from a NAT device using NAT-PMP */
 		ip = purple_pmp_get_public_ip();
 		if (ip != NULL) {
@@ -325,11 +312,7 @@
 	purple_prefs_add_int   ("/purple/network/ports_range_start", 1024);
 	purple_prefs_add_int   ("/purple/network/ports_range_end", 2048);
 
-	if(purple_prefs_get_bool("/purple/network/map_ports") || purple_prefs_get_bool("/purple/network/auto_ip"))
-		purple_upnp_discover(NULL, NULL);
-
 	purple_pmp_init();
-	purple_upnp_init();
 
 	purple_network_set_stun_server(
 		purple_prefs_get_string("/purple/network/stun_server"));
@@ -342,9 +325,4 @@
 {
 	g_free(stun_ip);
 	g_free(turn_ip);
-
-	/* TODO: clean up remaining port mappings, note calling
-	 purple_upnp_remove_port_mapping from here doesn't quite work... */
-
-	purple_upnp_uninit();
 }
--- a/libpurple/upnp.c	Sun Oct 23 22:21:46 2022 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,587 +0,0 @@
-/* purple
- *
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here.  Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
- */
-#include <gio/gio.h>
-
-#include <libgupnp/gupnp-context-manager.h>
-#include <libgupnp/gupnp-control-point.h>
-#include <libgupnp/gupnp-service-info.h>
-#include <libgupnp/gupnp-service-proxy.h>
-#include <libgupnp-igd/gupnp-simple-igd.h>
-
-#include "upnp.h"
-
-#include "glibcompat.h"
-#include "soupcompat.h"
-
-#include "debug.h"
-#include "eventloop.h"
-#include "network.h"
-#include "proxy.h"
-#include "purplegio.h"
-#include "signals.h"
-#include "util.h"
-#include "xmlnode.h"
-
-/***************************************************************
-** General Defines                                             *
-****************************************************************/
-#define PORT_MAPPING_LEASE_TIME 0
-#define PORT_MAPPING_DESCRIPTION "PURPLE_UPNP_PORT_FORWARD"
-
-typedef enum {
-	PURPLE_UPNP_STATUS_UNDISCOVERED = -1,
-	PURPLE_UPNP_STATUS_UNABLE_TO_DISCOVER,
-	PURPLE_UPNP_STATUS_DISCOVERING,
-	PURPLE_UPNP_STATUS_DISCOVERED
-} PurpleUPnPStatus;
-
-typedef struct {
-	PurpleUPnPStatus status;
-	gchar *control_url;
-	gchar *service_type;
-	char publicip[16];
-	char internalip[16];
-	gint64 lookup_time;
-} PurpleUPnPControlInfo;
-
-typedef struct {
-	unsigned short portmap;
-	gchar protocol[4];
-	gboolean add;
-	PurpleUPnPCallback cb;
-	gpointer cb_data;
-	gboolean success;
-	guint tima; /* g_timeout_add handle */
-} PurpleUPnPMappingAddRemove;
-
-static PurpleUPnPControlInfo control_info = {
-	PURPLE_UPNP_STATUS_UNDISCOVERED,
-	NULL, "\0", "\0", "\0", 0};
-
-static GUPnPContextManager *manager = NULL;
-static GUPnPSimpleIgd *simple_igd = NULL;
-static GSList *discovery_callbacks = NULL;
-
-static void lookup_internal_ip(void);
-
-static gboolean
-fire_ar_cb_async_and_free(gpointer data)
-{
-	PurpleUPnPMappingAddRemove *ar = data;
-	if (ar) {
-		if (ar->cb)
-			ar->cb(ar->success, ar->cb_data);
-		g_free(ar);
-	}
-
-	return FALSE;
-}
-
-static void
-fire_discovery_callbacks(gboolean success)
-{
-	while(discovery_callbacks) {
-		gpointer data;
-		PurpleUPnPCallback cb = discovery_callbacks->data;
-		discovery_callbacks = g_slist_delete_link(discovery_callbacks, discovery_callbacks);
-		data = discovery_callbacks->data;
-		discovery_callbacks = g_slist_delete_link(discovery_callbacks, discovery_callbacks);
-		cb(success, data);
-	}
-}
-
-static void
-upnp_service_proxy_call_action_cb(GObject *source, GAsyncResult *result,
-                                  G_GNUC_UNUSED gpointer data)
-{
-	GError *error = NULL;
-	char *ip = NULL;
-	GUPnPServiceProxyAction *action = NULL;
-
-	action = gupnp_service_proxy_call_action_finish(GUPNP_SERVICE_PROXY(source),
-	                                                result, &error);
-	if (error != NULL) {
-		control_info.publicip[0] = '\0';
-
-		purple_debug_error("upnp",
-		                   "Failed to call GetExternalIPAddress action: %s",
-		                   error->message);
-		g_error_free(error);
-		return;
-	}
-
-	gupnp_service_proxy_action_get_result(action, &error,
-	                                      "NewExternalIPAddress",
-	                                      G_TYPE_STRING, &ip, NULL);
-	if (error == NULL) {
-		g_strlcpy(control_info.publicip, ip, sizeof(control_info.publicip));
-
-		purple_debug_info("upnp", "NAT Returned IP: %s", control_info.publicip);
-		g_free(ip);
-	} else {
-		control_info.publicip[0] = '\0';
-
-		purple_debug_error("upnp",
-		                   "Failed to get result from GetExternalIPAddress: %s",
-		                   error->message);
-		g_error_free(error);
-	}
-
-	gupnp_service_proxy_action_unref(action);
-}
-
-static void
-upnp_service_proxy_available_cb(G_GNUC_UNUSED GUPnPControlPoint *cp,
-                                GUPnPServiceProxy *proxy,
-                                G_GNUC_UNUSED gpointer data)
-{
-	gchar *control_url = NULL;
-	const gchar *service_type = NULL;
-
-	control_url = gupnp_service_info_get_control_url(GUPNP_SERVICE_INFO(proxy));
-	service_type = gupnp_service_info_get_service_type(GUPNP_SERVICE_INFO(proxy));
-	purple_debug_info("upnp",
-	                  "Service proxy available for %s on control URL %s",
-	                  service_type,
-	                  control_url);
-
-	control_info.lookup_time = g_get_monotonic_time();
-	control_info.control_url = control_url;
-	control_info.service_type = g_strdup(service_type);
-
-	if(control_url) {
-		GUPnPServiceProxyAction *action = NULL;
-
-		control_info.status = PURPLE_UPNP_STATUS_DISCOVERED;
-		fire_discovery_callbacks(TRUE);
-
-		lookup_internal_ip();
-		action = gupnp_service_proxy_action_new("GetExternalIPAddress", NULL);
-		gupnp_service_proxy_call_action_async(proxy, action, NULL,
-		                                      upnp_service_proxy_call_action_cb,
-		                                      NULL);
-	} else {
-		control_info.status = PURPLE_UPNP_STATUS_UNABLE_TO_DISCOVER;
-		fire_discovery_callbacks(FALSE);
-	}
-}
-
-static void
-upnp_context_unavailable_cb(G_GNUC_UNUSED GUPnPContextManager *manager,
-                            GUPnPContext *context, G_GNUC_UNUSED gpointer data)
-{
-	purple_debug_info("upnp",
-	                  "UPnP context no longer available for interface %s",
-	                  gssdp_client_get_interface(GSSDP_CLIENT(context)));
-
-	/* Delete these to prevent them owning refs back on the context. */
-	g_object_set_data(G_OBJECT(context), "WANIPConnection", NULL);
-	g_object_set_data(G_OBJECT(context), "WANPPPConnection", NULL);
-}
-
-static void
-upnp_context_available_cb(G_GNUC_UNUSED GUPnPContextManager *manager,
-                          GUPnPContext *context, G_GNUC_UNUSED gpointer data)
-{
-	GUPnPControlPoint *cp;
-
-	purple_debug_info("upnp", "UPnP context now available for interface %s",
-	                  gssdp_client_get_interface(GSSDP_CLIENT(context)));
-
-	cp = gupnp_control_point_new(context,
-	                             "urn:schemas-upnp-org:service:WANIPConnection:1");
-	g_signal_connect(cp, "service-proxy-available",
-	                 G_CALLBACK(upnp_service_proxy_available_cb), NULL);
-	gssdp_resource_browser_set_active(GSSDP_RESOURCE_BROWSER(cp), TRUE);
-	g_object_set_data_full(G_OBJECT(context), "WANIPConnection", cp,
-	                       g_object_unref);
-
-	cp = gupnp_control_point_new(context,
-	                             "urn:schemas-upnp-org:service:WANPPPConnection:1");
-	g_signal_connect(cp, "service-proxy-available",
-	                 G_CALLBACK(upnp_service_proxy_available_cb), NULL);
-	gssdp_resource_browser_set_active(GSSDP_RESOURCE_BROWSER(cp), TRUE);
-	g_object_set_data_full(G_OBJECT(context), "WANPPPConnection", cp,
-	                       g_object_unref);
-}
-
-void
-purple_upnp_discover(PurpleUPnPCallback cb, gpointer cb_data)
-{
-	if (cb) {
-		discovery_callbacks = g_slist_append(discovery_callbacks, cb);
-		discovery_callbacks = g_slist_append(discovery_callbacks, cb_data);
-	}
-
-	if (control_info.status == PURPLE_UPNP_STATUS_DISCOVERING) {
-		return;
-	}
-
-	purple_debug_info("upnp",
-	                  "Starting discovery on all available interfaces");
-
-	g_clear_object(&manager);
-	manager = gupnp_context_manager_create(0);
-	g_signal_connect(manager, "context-available",
-	                 G_CALLBACK(upnp_context_available_cb), NULL);
-	g_signal_connect(manager, "context-unavailable",
-	                 G_CALLBACK(upnp_context_unavailable_cb), NULL);
-
-	control_info.status = PURPLE_UPNP_STATUS_DISCOVERING;
-}
-
-const gchar *
-purple_upnp_get_public_ip()
-{
-	if (control_info.status == PURPLE_UPNP_STATUS_DISCOVERED
-			&& *control_info.publicip)
-		return control_info.publicip;
-
-	/* Trigger another UPnP discovery if 5 minutes have elapsed since the
-	 * last one, and it wasn't successful */
-	if (control_info.status < PURPLE_UPNP_STATUS_DISCOVERING &&
-	    (g_get_monotonic_time() - control_info.lookup_time) >
-	            300 * G_USEC_PER_SEC) {
-		purple_upnp_discover(NULL, NULL);
-	}
-
-	return NULL;
-}
-
-/* TODO: This could be exported */
-static const gchar *
-purple_upnp_get_internal_ip(void)
-{
-	if (control_info.status == PURPLE_UPNP_STATUS_DISCOVERED
-			&& *control_info.internalip)
-		return control_info.internalip;
-
-	/* Trigger another UPnP discovery if 5 minutes have elapsed since the
-	 * last one, and it wasn't successful */
-	if (control_info.status < PURPLE_UPNP_STATUS_DISCOVERING &&
-	    (g_get_monotonic_time() - control_info.lookup_time) >
-	            300 * G_USEC_PER_SEC) {
-		purple_upnp_discover(NULL, NULL);
-	}
-
-	return NULL;
-}
-
-static void
-looked_up_internal_ip_cb(GObject *source, GAsyncResult *result,
-                         G_GNUC_UNUSED gpointer user_data)
-{
-	GSocketConnection *conn;
-	GSocketAddress *addr;
-	GInetSocketAddress *inetsockaddr;
-	GError *error = NULL;
-
-	conn = g_socket_client_connect_to_host_finish(G_SOCKET_CLIENT(source),
-	                                              result, &error);
-	if (conn == NULL) {
-		purple_debug_error("upnp", "Unable to look up local IP: %s",
-		                   error->message);
-		g_clear_error(&error);
-		return;
-	}
-
-	g_strlcpy(control_info.internalip, "0.0.0.0",
-	          sizeof(control_info.internalip));
-
-	addr = g_socket_connection_get_local_address(conn, &error);
-	if ((inetsockaddr = G_INET_SOCKET_ADDRESS(addr)) != NULL) {
-		GInetAddress *inetaddr =
-		        g_inet_socket_address_get_address(inetsockaddr);
-		if (g_inet_address_get_family(inetaddr) == G_SOCKET_FAMILY_IPV4 &&
-		    !g_inet_address_get_is_loopback(inetaddr))
-		{
-			gchar *ip = g_inet_address_to_string(inetaddr);
-			g_strlcpy(control_info.internalip, ip,
-			          sizeof(control_info.internalip));
-			g_free(ip);
-		}
-	} else {
-		purple_debug_error(
-		        "upnp", "Unable to get local address of connection: %s",
-		        error ? error->message : "unknown socket address type");
-		g_clear_error(&error);
-	}
-	g_object_unref(addr);
-
-	purple_debug_info("upnp", "Local IP: %s", control_info.internalip);
-	g_object_unref(conn);
-}
-
-static void
-lookup_internal_ip(void)
-{
-	gchar *host;
-	gint port;
-	GSocketClient *client;
-	GError *error = NULL;
-
-	if (!g_uri_split_network(control_info.control_url, G_URI_FLAGS_NONE, NULL,
-	                         &host, &port, &error))
-	{
-		purple_debug_error("upnp",
-			"lookup_internal_ip(): Failed In Parse URL: %s",
-			error->message);
-		return;
-	}
-
-	client = purple_gio_socket_client_new(NULL, &error);
-	if (client == NULL) {
-		purple_debug_error("upnp", "Get Local IP Connect to %s:%d Failed: %s",
-		                   host, port, error->message);
-		g_clear_error(&error);
-		g_free(host);
-		return;
-	}
-
-	purple_debug_info("upnp", "Attempting connection to %s:%u\n", host, port);
-	g_socket_client_connect_to_host_async(client, host, port, NULL,
-	                                      looked_up_internal_ip_cb, NULL);
-
-	g_object_unref(client);
-	g_free(host);
-}
-
-static void
-upnp_mapped_external_port_cb(GUPnPSimpleIgd *igd, const gchar *protocol,
-                             G_GNUC_UNUSED const gchar *external_ip,
-                             G_GNUC_UNUSED const gchar *replaces_external_ip,
-                             guint16 external_port,
-                             G_GNUC_UNUSED const gchar *local_ip,
-                             guint16 local_port,
-                             G_GNUC_UNUSED const gchar *description,
-                             gpointer data)
-{
-	PurpleUPnPMappingAddRemove *ar = data;
-
-	if(!purple_strequal(ar->protocol, protocol)) {
-		return;
-	}
-	if(external_port != ar->portmap) {
-		return;
-	}
-
-	purple_debug_info("upnp", "Successfully completed port mapping operation");
-
-	ar->success = TRUE;
-	ar->tima = g_timeout_add(0, fire_ar_cb_async_and_free, ar);
-
-	g_signal_handlers_disconnect_by_data(igd, ar);
-}
-
-static void
-upnp_error_mapping_port_cb(GUPnPSimpleIgd *igd, GError *error,
-                           const gchar *protocol,
-                           guint16 external_port,
-                           G_GNUC_UNUSED const gchar *local_ip,
-                           G_GNUC_UNUSED guint16 local_port,
-                           G_GNUC_UNUSED const gchar *description,
-                           gpointer data)
-{
-	PurpleUPnPMappingAddRemove *ar = data;
-
-	if(!purple_strequal(ar->protocol, protocol)) {
-		return;
-	}
-	if(external_port != ar->portmap) {
-		return;
-	}
-
-	purple_debug_error("upnp", "purple_upnp_set_port_mapping(): Failed: %s",
-	                   error->message);
-
-	ar->success = FALSE;
-	ar->tima = g_timeout_add(0, fire_ar_cb_async_and_free, ar);
-
-	g_signal_handlers_disconnect_by_data(igd, ar);
-}
-
-static void
-do_port_mapping_cb(gboolean has_control_mapping, gpointer data)
-{
-	PurpleUPnPMappingAddRemove *ar = data;
-
-	if (!has_control_mapping) {
-		ar->success = FALSE;
-		ar->tima = g_timeout_add(0, fire_ar_cb_async_and_free, ar);
-		return;
-	}
-
-	if(ar->add) {
-		const gchar *internal_ip;
-		/* get the internal IP */
-		if(!(internal_ip = purple_upnp_get_internal_ip())) {
-			purple_debug_error("upnp",
-				"purple_upnp_set_port_mapping(): couldn't get local ip\n");
-			ar->success = FALSE;
-			ar->tima = g_timeout_add(0, fire_ar_cb_async_and_free, ar);
-			return;
-		}
-
-		if(simple_igd == NULL) {
-			simple_igd = gupnp_simple_igd_new();
-		}
-
-		gupnp_simple_igd_add_port(simple_igd, ar->protocol, ar->portmap,
-		                          internal_ip, ar->portmap,
-		                          PORT_MAPPING_LEASE_TIME,
-		                          PORT_MAPPING_DESCRIPTION);
-	} else {
-		if(simple_igd == NULL) {
-			simple_igd = gupnp_simple_igd_new();
-		}
-
-		gupnp_simple_igd_remove_port(simple_igd, ar->protocol, ar->portmap);
-	}
-
-	g_signal_connect(simple_igd, "mapped-external-port",
-	                 G_CALLBACK(upnp_mapped_external_port_cb), ar);
-	g_signal_connect(simple_igd, "error-mapping-port",
-	                 G_CALLBACK(upnp_error_mapping_port_cb), ar);
-}
-
-static gboolean
-fire_port_mapping_failure_cb(gpointer data)
-{
-	PurpleUPnPMappingAddRemove *ar = data;
-
-	ar->tima = 0;
-	do_port_mapping_cb(FALSE, data);
-	return FALSE;
-}
-
-void
-purple_upnp_set_port_mapping(unsigned short portmap, const gchar *protocol,
-                             PurpleUPnPCallback cb, gpointer cb_data)
-{
-	PurpleUPnPMappingAddRemove *ar;
-
-	ar = g_new0(PurpleUPnPMappingAddRemove, 1);
-	ar->cb = cb;
-	ar->cb_data = cb_data;
-	ar->add = TRUE;
-	ar->portmap = portmap;
-	g_strlcpy(ar->protocol, protocol, sizeof(ar->protocol));
-
-	switch(control_info.status) {
-		case PURPLE_UPNP_STATUS_UNABLE_TO_DISCOVER:
-			if (g_get_monotonic_time() - control_info.lookup_time >
-				300 * G_USEC_PER_SEC) {
-				/* If we haven't had a successful UPnP discovery, check if 5 minutes
-				 * has elapsed since the last try, try again */
-				purple_upnp_discover(do_port_mapping_cb, ar);
-			} else if (cb) {
-				/* Asynchronously trigger a failed response */
-				ar->tima = g_timeout_add(10, fire_port_mapping_failure_cb, ar);
-			} else {
-				/* No need to do anything if nobody expects a response*/
-				g_free(ar);
-				ar = NULL;
-			}
-			break;
-
-		case PURPLE_UPNP_STATUS_UNDISCOVERED:
-		case PURPLE_UPNP_STATUS_DISCOVERING:
-			purple_upnp_discover(do_port_mapping_cb, ar);
-			break;
-
-		case PURPLE_UPNP_STATUS_DISCOVERED:
-		default:
-			do_port_mapping_cb(TRUE, ar);
-			break;
-	}
-}
-
-void
-purple_upnp_remove_port_mapping(unsigned short portmap, const char *protocol,
-                                PurpleUPnPCallback cb, gpointer cb_data)
-{
-	PurpleUPnPMappingAddRemove *ar;
-
-	ar = g_new0(PurpleUPnPMappingAddRemove, 1);
-	ar->cb = cb;
-	ar->cb_data = cb_data;
-	ar->add = FALSE;
-	ar->portmap = portmap;
-	g_strlcpy(ar->protocol, protocol, sizeof(ar->protocol));
-
-	switch(control_info.status) {
-		case PURPLE_UPNP_STATUS_UNABLE_TO_DISCOVER:
-			if (g_get_monotonic_time() - control_info.lookup_time >
-				300 * G_USEC_PER_SEC) {
-				/* If we haven't had a successful UPnP discovery, check if 5 minutes
-				 * has elapsed since the last try, try again */
-				purple_upnp_discover(do_port_mapping_cb, ar);
-			} else if (cb) {
-				/* Asynchronously trigger a failed response */
-				ar->tima = g_timeout_add(10, fire_port_mapping_failure_cb, ar);
-			} else {
-				/* No need to do anything if nobody expects a response*/
-				g_free(ar);
-				ar = NULL;
-			}
-			break;
-
-		case PURPLE_UPNP_STATUS_DISCOVERING:
-		case PURPLE_UPNP_STATUS_UNDISCOVERED:
-			purple_upnp_discover(do_port_mapping_cb, ar);
-			break;
-
-		case PURPLE_UPNP_STATUS_DISCOVERED:
-		default:
-			do_port_mapping_cb(TRUE, ar);
-			break;
-	}
-}
-
-static void
-purple_upnp_network_config_changed_cb(GNetworkMonitor *monitor, gboolean available, gpointer data)
-{
-	/* Reset the control_info to default values */
-	control_info.status = PURPLE_UPNP_STATUS_UNDISCOVERED;
-	g_clear_pointer(&control_info.control_url, g_free);
-	g_clear_pointer(&control_info.service_type, g_free);
-	control_info.publicip[0] = '\0';
-	control_info.internalip[0] = '\0';
-	control_info.lookup_time = 0;
-}
-
-void
-purple_upnp_init()
-{
-	g_signal_connect(g_network_monitor_get_default(),
-	                 "network-changed",
-	                 G_CALLBACK(purple_upnp_network_config_changed_cb),
-	                 NULL);
-}
-
-void
-purple_upnp_uninit(void)
-{
-	g_clear_object(&simple_igd);
-	g_clear_pointer(&control_info.control_url, g_free);
-	g_clear_pointer(&control_info.service_type, g_free);
-	g_clear_object(&manager);
-}
--- a/libpurple/upnp.h	Sun Oct 23 22:21:46 2022 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +0,0 @@
-/*
- * Purple - Internet Messaging Library
- * Copyright (C) Pidgin Developers <devel@pidgin.im>
- *
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here.  Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <https://www.gnu.org/licenses/>.
- */
-
-#if !defined(PURPLE_GLOBAL_HEADER_INSIDE) && !defined(PURPLE_COMPILATION)
-# error "only <purple.h> may be included directly"
-#endif
-
-#ifndef PURPLE_UPNP_H
-#define PURPLE_UPNP_H
-
-G_BEGIN_DECLS
-
-/**************************************************************************/
-/* UPnP API                                                               */
-/**************************************************************************/
-
-typedef void (*PurpleUPnPCallback) (gboolean success, gpointer data);
-
-
-/**
- * purple_upnp_init:
- *
- * Initialize UPnP
- */
-void purple_upnp_init(void);
-
-/**
- * purple_upnp_uninit:
- *
- * Shuts down UPnP
- */
-void purple_upnp_uninit(void);
-
-/**
- * purple_upnp_discover:
- * @cb: (scope async): An optional callback function to be notified when the
- *      UPnP discovery is complete.
- * @cb_data: (closure): Extra data to be passed to the callback.
- *
- * Sends a discovery request to search for a UPnP enabled IGD that
- * contains the WANIPConnection service that will allow us to receive the
- * public IP address of the IGD, and control it for forwarding ports.
- * The result will be cached for further use.
- */
-void purple_upnp_discover(PurpleUPnPCallback cb, gpointer cb_data);
-
-/**
- * purple_upnp_get_public_ip:
- *
- * Gets the IP address from a UPnP enabled IGD that sits on the local
- * network, so when getting the network IP, instead of returning the
- * local network IP, the public IP is retrieved.  This is a cached value from
- * the time of the UPnP discovery.
- *
- * Returns: The IP address of the network, or NULL if something went wrong
- */
-const gchar* purple_upnp_get_public_ip(void);
-
-/**
- * purple_upnp_set_port_mapping:
- * @portmap: The port to map to this client
- * @protocol: The protocol to map, either "TCP" or "UDP"
- * @cb: (scope async): An optional callback function to be notified when the
- *      mapping addition is complete.
- * @cb_data: (closure): Extra data to be passed to the callback.
- *
- * Maps Ports in a UPnP enabled IGD that sits on the local network to
- * this purple client. Essentially, this function takes care of the port
- * forwarding so things like file transfers can work behind NAT firewalls
- */
-void purple_upnp_set_port_mapping(unsigned short portmap, const gchar *protocol, PurpleUPnPCallback cb, gpointer cb_data);
-
-/**
- * purple_upnp_remove_port_mapping:
- * @portmap: The port to delete the mapping for
- * @protocol: The protocol to map to. Either "TCP" or "UDP"
- * @cb: (scope async): An optional callback function to be notified when the
- *      mapping removal is complete.
- * @cb_data: (closure): Extra data to be passed to the callback.
- *
- * Deletes a port mapping in a UPnP enabled IGD that sits on the local network
- * to this purple client. Essentially, this function takes care of deleting the
- * port forwarding after they have completed a connection so another client on
- * the local network can take advantage of the port forwarding
- */
-void purple_upnp_remove_port_mapping(unsigned short portmap, const gchar *protocol, PurpleUPnPCallback cb, gpointer cb_data);
-
-G_END_DECLS
-
-#endif /* PURPLE_UPNP_H */
--- a/meson.build	Sun Oct 23 22:21:46 2022 -0500
+++ b/meson.build	Sun Oct 23 22:31:02 2022 -0500
@@ -282,16 +282,7 @@
 
 json = dependency('json-glib-1.0', version : '>= 0.14.0')
 
-#######################################################################
-# Check for gUPnP (required)
-#######################################################################
-
-gupnp = dependency('gupnp-1.2', version : '>= 1.2.0')
-gupnp_igd = dependency('gupnp-igd-1.0',
-	version : '>= 1.2.0',
-	allow_fallback : get_option('build-dependencies'))
-
-#######################################################################
+######################################################################
 # Check for libsoup (required)
 #######################################################################
 
--- a/pidgin/prefs/pidginnetworkprefs.c	Sun Oct 23 22:21:46 2022 -0500
+++ b/pidgin/prefs/pidginnetworkprefs.c	Sun Oct 23 22:31:02 2022 -0500
@@ -116,14 +116,10 @@
 		if ((stun != NULL) && (stun->status == PURPLE_STUN_STATUS_DISCOVERED)) {
 			ip = stun->publicip;
 		} else {
-			/* Attempt to get the IP from a NAT device using UPnP */
-			ip = purple_upnp_get_public_ip();
+			/* Attempt to get the IP from a NAT device using NAT-PMP */
+			ip = purple_pmp_get_public_ip();
 			if (ip == NULL) {
-				/* Attempt to get the IP from a NAT device using NAT-PMP */
-				ip = purple_pmp_get_public_ip();
-				if (ip == NULL) {
-					ip = "0.0.0.0";
-				}
+				ip = "0.0.0.0";
 			}
 		}
 	} else {
--- a/po/POTFILES.in	Sun Oct 23 22:21:46 2022 -0500
+++ b/po/POTFILES.in	Sun Oct 23 22:31:02 2022 -0500
@@ -306,7 +306,6 @@
 libpurple/tests/test_util.c
 libpurple/tests/test_whiteboard_manager.c
 libpurple/tests/test_xmlnode.c
-libpurple/upnp.c
 libpurple/util.c
 libpurple/version.c
 libpurple/win32/libc_interface.c
--- a/subprojects/gupnp-igd-1.0.wrap	Sun Oct 23 22:21:46 2022 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-[wrap-file]
-directory = gupnp-igd-1.2.0
-source_url = https://download.gnome.org/sources/gupnp-igd/1.2/gupnp-igd-1.2.0.tar.xz
-source_filename = gupnp-igd-1.2.0.tar.xz
-source_hash = 4b5120098aa13edd27818ba9ee4d7fe961bf540bf50d056ff703c61545e02be1
-
-[provide]
-dependency_names = gupnp-igd-1.0
-gupnp-igd-1.0 = gupnp_igd
-

mercurial