diff libpurple/network.c @ 15855:9b875f0ecb86

nat-pmp is now functional with a compatible router. I'm not enabling this code yet because it hasn't been tested with a router which doesn't support nat-pmp.
author Evan Schoenberg <evan.s@dreskin.net>
date Thu, 22 Mar 2007 12:51:33 +0000
parents 32c366eeeb99
children efdd557ed187
line wrap: on
line diff
--- a/libpurple/network.c	Tue Mar 20 15:21:05 2007 +0000
+++ b/libpurple/network.c	Thu Mar 22 12:51:33 2007 +0000
@@ -47,6 +47,8 @@
 #include "stun.h"
 #include "upnp.h"
 
+/* #define ENABLE_NAT_PMP */
+
 #ifdef ENABLE_NAT_PMP
 #include "nat-pmp.h"
 #endif
@@ -79,9 +81,6 @@
 	PurpleNetworkListenCallback cb;
 	gpointer cb_data;
 	UPnPMappingAddRemove *mapping_data;
-#ifdef ENABLE_NAT_PMP
-	gboolean has_pmp_mapping;
-#endif
 };
 
 #ifdef HAVE_LIBNM
@@ -251,6 +250,20 @@
 	purple_network_listen_cancel(listen_data);
 }
 
+static gboolean
+purple_network_finish_pmp_map_cb(gpointer data)
+{
+	PurpleNetworkListenData *listen_data;
+	
+	listen_data = data;
+	
+	if (listen_data->cb)
+		listen_data->cb(listen_data->listenfd, listen_data->cb_data);
+
+	purple_network_listen_cancel(listen_data);
+
+	return FALSE;
+}
 
 static PurpleNetworkListenData *
 purple_network_do_listen(unsigned short port, int socket_type, PurpleNetworkListenCallback cb, gpointer cb_data)
@@ -348,15 +361,22 @@
 
 #ifdef ENABLE_NAT_PMP
 	/* Attempt a NAT-PMP Mapping, which will return immediately */
-	listen_data->has_pmp_mapping = (purple_pmp_create_map(((socket_type == SOCK_STREAM) ? PURPLE_PMP_TYPE_TCP : PURPLE_PMP_TYPE_UDP),
-														actual_port, actual_port, PURPLE_PMP_LIFETIME) != NULL);	
+	if (purple_pmp_create_map(((socket_type == SOCK_STREAM) ? PURPLE_PMP_TYPE_TCP : PURPLE_PMP_TYPE_UDP),
+							  actual_port, actual_port, PURPLE_PMP_LIFETIME) != NULL)
+	{
+		purple_debug_info("network", "Created NAT-PMP mapping on port %i",actual_port);
+		/* We want to return listen_data now, and on the next run loop trigger the cb and destroy listen_data */
+		purple_timeout_add(0, purple_network_finish_pmp_map_cb, listen_data);
+	}
+	else
 #endif
-	
-	/* Attempt a UPnP Mapping */
-	listen_data->mapping_data = purple_upnp_set_port_mapping(
-					actual_port,
-					(socket_type == SOCK_STREAM) ? "TCP" : "UDP",
-					purple_network_set_upnp_port_mapping_cb, listen_data);
+	{
+		/* Attempt a UPnP Mapping */
+		listen_data->mapping_data = purple_upnp_set_port_mapping(
+						 actual_port,
+						 (socket_type == SOCK_STREAM) ? "TCP" : "UDP",
+						 purple_network_set_upnp_port_mapping_cb, listen_data);
+	}
 
 	return listen_data;
 }
@@ -398,12 +418,6 @@
 	if (listen_data->mapping_data != NULL)
 		purple_upnp_cancel_port_mapping(listen_data->mapping_data);
 
-#ifdef ENABLE_NAT_PMP
-	if (listen_data->has_pmp_mapping)
-		purple_pmp_destroy_map(((listen_data->socket_type == SOCK_STREAM) ? PURPLE_PMP_TYPE_TCP : PURPLE_PMP_TYPE_UDP),
-							 purple_network_get_port_from_fd(listen_data->listenfd));
-#endif
-
 	g_free(listen_data);
 }