gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r4096 - GNUnet/src/transports/upnp


From: grothoff
Subject: [GNUnet-SVN] r4096 - GNUnet/src/transports/upnp
Date: Fri, 29 Dec 2006 02:03:36 -0800 (PST)

Author: grothoff
Date: 2006-12-29 02:03:33 -0800 (Fri, 29 Dec 2006)
New Revision: 4096

Modified:
   GNUnet/src/transports/upnp/Makefile.am
   GNUnet/src/transports/upnp/todo
   GNUnet/src/transports/upnp/upnp.c
   GNUnet/src/transports/upnp/upnp.h
   GNUnet/src/transports/upnp/util.c
   GNUnet/src/transports/upnp/util.h
   GNUnet/src/transports/upnp/xmlnode.h
Log:
update

Modified: GNUnet/src/transports/upnp/Makefile.am
===================================================================
--- GNUnet/src/transports/upnp/Makefile.am      2006-12-29 05:17:33 UTC (rev 
4095)
+++ GNUnet/src/transports/upnp/Makefile.am      2006-12-29 10:03:33 UTC (rev 
4096)
@@ -12,6 +12,7 @@
 
 libgnunetupnp_la_SOURCES = \
  error.c error.h \
+ init.c \
  util.c util.h \
  xmlnode.c xmlnode.h \
  upnp.c upnp.h 

Modified: GNUnet/src/transports/upnp/todo
===================================================================
--- GNUnet/src/transports/upnp/todo     2006-12-29 05:17:33 UTC (rev 4095)
+++ GNUnet/src/transports/upnp/todo     2006-12-29 10:03:33 UTC (rev 4096)
@@ -1,7 +1,7 @@
-1) figure out which external GNUnet API we want to have
-2) figure out how control should work
-   (replace gaim_timeout/input_add/remove with
-    GNUnet-ish constructs)
-3) adjust configure to check for libxml2
-4) integrate with transports
+1) Add code to determine internal IP
+2) change init to periodically re-add port mappings / rediscover
+   (use cron jobs for this).
+3) Look into upnp shutdown sequence!
+4) adjust configure to check for libxml2
+5) integrate with transports
 

Modified: GNUnet/src/transports/upnp/upnp.c
===================================================================
--- GNUnet/src/transports/upnp/upnp.c   2006-12-29 05:17:33 UTC (rev 4095)
+++ GNUnet/src/transports/upnp/upnp.c   2006-12-29 10:03:33 UTC (rev 4096)
@@ -29,6 +29,8 @@
 #include "upnp.h"
 #include "error.h"
 
+#include <curl/curl.h>
+
 /***************************************************************
 ** General Defines                                             *
 ****************************************************************/
@@ -61,12 +63,11 @@
 /******************************************************************
 ** Action Defines                                                 *
 *******************************************************************/
-#define HTTP_HEADER_ACTION \
-       "POST /%s HTTP/1.1\r\n" \
-       "HOST: %s:%d\r\n" \
-       "SOAPACTION: \"urn:schemas-upnp-org:service:%s#%s\"\r\n" \
+
+#define HTTP_POST_SOAP_ACTION \
+       "SOAPACTION: \"urn:schemas-upnp-org:service:%s#%s\"\r\n"        \
        "CONTENT-TYPE: text/xml ; charset=\"utf-8\"\r\n" \
-       "CONTENT-LENGTH: %" G_GSIZE_FORMAT "\r\n\r\n"
+       "CONTENT-LENGTH: %" G_GSIZE_FORMAT "\r\n\r\n%s"
 
 #define SOAP_ACTION \
        "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" \
@@ -80,7 +81,7 @@
        "</s:Envelope>"
 
 #define PORT_MAPPING_LEASE_TIME "0"
-#define PORT_MAPPING_DESCRIPTION "GAIM_UPNP_PORT_FORWARD"
+#define PORT_MAPPING_DESCRIPTION "GNUNET_UPNP_PORT_FORWARD"
 
 #define ADD_PORT_MAPPING_PARAMS \
        "<NewRemoteHost></NewRemoteHost>\r\n" \
@@ -102,881 +103,619 @@
        "<NewProtocol>%s</NewProtocol>\r\n"
 
 typedef enum {
-       GAIM_UPNP_STATUS_UNDISCOVERED = -1,
-       GAIM_UPNP_STATUS_UNABLE_TO_DISCOVER,
-       GAIM_UPNP_STATUS_DISCOVERING,
-       GAIM_UPNP_STATUS_DISCOVERED
+  GAIM_UPNP_STATUS_UNDISCOVERED = -1,
+  GAIM_UPNP_STATUS_UNABLE_TO_DISCOVER,
+  GAIM_UPNP_STATUS_DISCOVERING,
+  GAIM_UPNP_STATUS_DISCOVERED
 } GaimUPnPStatus;
 
 typedef struct {
-       GaimUPnPStatus status;
-       gchar* control_url;
-       gchar service_type[20];
-       char publicip[16];
-       char internalip[16];
-       time_t lookup_time;
+  GaimUPnPStatus status;
+  gchar* control_url;
+  const gchar * service_type;
+  char publicip[16];
 } GaimUPnPControlInfo;
 
 typedef struct {
-       guint inpa;     /* gaim_input_add handle */
-       guint tima;     /* gaim_timeout_add handle */
-       int fd;
-       struct sockaddr_in server;
-       gchar service_type[25];
-       int retry_count;
-       gchar *full_url;
+  const gchar * service_type;
+  gchar * full_url;
+  char * buf;
+  unsigned int buf_len;
+  int sock;
 } UPnPDiscoveryData;
 
-typedef struct {
-       unsigned short portmap;
-       gchar protocol[4];
-       gboolean add;
-       GaimUPnPCallback cb;
-       gpointer cb_data;
-} UPnPMappingAddRemove;
-
 static GaimUPnPControlInfo control_info = {
-       GAIM_UPNP_STATUS_UNDISCOVERED,
-       NULL, "\0", "\0", "\0", 0};
+  GAIM_UPNP_STATUS_UNDISCOVERED, 
+  NULL,
+  NULL,
+  "",
+};
 
-static GSList *discovery_callbacks = NULL;
 
-static void gaim_upnp_discover_send_broadcast(UPnPDiscoveryData *dd);
-static void lookup_public_ip(void);
-static void lookup_internal_ip(void);
+/**
+ * This is the signature used for functions that act as a callback
+ * to CURL.
+ */
+typedef size_t (*GaimUtilFetchUrlCallback)(void *url_data,
+                                          size_t size,
+                                          size_t nmemb,
+                                          gpointer user_data);
 
-static void
-fire_discovery_callbacks(gboolean success)
-{
-       while(discovery_callbacks) {
-               gpointer data;
-               GaimUPnPCallback cb = discovery_callbacks->data;
-               discovery_callbacks = g_slist_remove(discovery_callbacks, cb);
-               data = discovery_callbacks->data;
-               discovery_callbacks = g_slist_remove(discovery_callbacks, data);
-               cb(success, data);
-       }
-}
 
-static gboolean
-gaim_upnp_compare_device(const xmlnode* device, const gchar* deviceType)
-{
-       xmlnode* deviceTypeNode = xmlnode_get_child(device, "deviceType");
-       char *tmp;
-       gboolean ret;
 
-       if(deviceTypeNode == NULL) {
-               return FALSE;
-       }
-
-       tmp = xmlnode_get_data(deviceTypeNode);
-       ret = !g_ascii_strcasecmp(tmp, deviceType);
-       g_free(tmp);
-
-       return ret;
+static gboolean
+gaim_upnp_compare_device(const xmlnode* device, 
+                        const gchar* deviceType) {
+  xmlnode* deviceTypeNode = xmlnode_get_child(device, "deviceType");
+  char * tmp;
+  gboolean ret;
+  
+  if (deviceTypeNode == NULL) 
+    return FALSE;      
+  tmp = xmlnode_get_data(deviceTypeNode);
+  ret = !g_ascii_strcasecmp(tmp, deviceType);
+  g_free(tmp);  
+  return ret;
 }
 
 static gboolean
-gaim_upnp_compare_service(const xmlnode* service, const gchar* serviceType)
-{
-       xmlnode* serviceTypeNode;
-       char *tmp;
-       gboolean ret;
-
-       if(service == NULL) {
-               return FALSE;
-       }
-
-       serviceTypeNode = xmlnode_get_child(service, "serviceType");
-
-       if(serviceTypeNode == NULL) {
-               return FALSE;
-       }
-
-       tmp = xmlnode_get_data(serviceTypeNode);
-       ret = !g_ascii_strcasecmp(tmp, serviceType);
-       g_free(tmp);
-
-       return ret;
+gaim_upnp_compare_service(const xmlnode* service, 
+                         const gchar* serviceType) {
+  xmlnode * serviceTypeNode;
+  char *tmp;
+  gboolean ret;
+  
+  if (service == NULL) 
+    return FALSE;      
+  serviceTypeNode = xmlnode_get_child(service, "serviceType");
+  if(serviceTypeNode == NULL) 
+    return FALSE;
+  tmp = xmlnode_get_data(serviceTypeNode);
+  ret = !g_ascii_strcasecmp(tmp, serviceType);
+  g_free(tmp); 
+  return ret;
 }
 
 static gchar*
-gaim_upnp_parse_description_response(const gchar* httpResponse, gsize len,
-       const gchar* httpURL, const gchar* serviceType)
-{
-       gchar *xmlRoot, *baseURL, *controlURL, *service;
-       xmlnode *xmlRootNode, *serviceTypeNode, *controlURLNode, *baseURLNode;
-       char *tmp;
-
-       /* make sure we have a valid http response */
-       if(g_strstr_len(httpResponse, len, HTTP_OK) == NULL) {
-               gaim_debug_error("upnp",
-                       "parse_description_response(): Failed In HTTP_OK\n");
-               return NULL;
-       }
-
-       /* find the root of the xml document */
-       if((xmlRoot = g_strstr_len(httpResponse, len, "<root")) == NULL) {
-               gaim_debug_error("upnp",
-                       "parse_description_response(): Failed finding root\n");
-               return NULL;
-       }
-
-       /* create the xml root node */
-       if((xmlRootNode = xmlnode_from_str(xmlRoot,
-                       len - (xmlRoot - httpResponse))) == NULL) {
-               gaim_debug_error("upnp",
-                       "parse_description_response(): Could not parse xml root 
node\n");
-               return NULL;
-       }
-
-       /* get the baseURL of the device */
-       if((baseURLNode = xmlnode_get_child(xmlRootNode, "URLBase")) != NULL) {
-               baseURL = xmlnode_get_data(baseURLNode);
-       } else {
-               baseURL = g_strdup(httpURL);
-       }
-
-       /* get the serviceType child that has the service type as its data */
-
-       /* get urn:schemas-upnp-org:device:InternetGatewayDevice:1 and its 
devicelist */
-       serviceTypeNode = xmlnode_get_child(xmlRootNode, "device");
-       while(!gaim_upnp_compare_device(serviceTypeNode,
-                       "urn:schemas-upnp-org:device:InternetGatewayDevice:1") 
&&
-                       serviceTypeNode != NULL) {
-               serviceTypeNode = xmlnode_get_next_twin(serviceTypeNode);
-       }
-       if(serviceTypeNode == NULL) {
-               gaim_debug_error("upnp",
-                       "parse_description_response(): could not get 
serviceTypeNode 1\n");
-               g_free(baseURL);
-               xmlnode_free(xmlRootNode);
-               return NULL;
-       }
-       serviceTypeNode = xmlnode_get_child(serviceTypeNode, "deviceList");
-       if(serviceTypeNode == NULL) {
-               gaim_debug_error("upnp",
-                       "parse_description_response(): could not get 
serviceTypeNode 2\n");
-               g_free(baseURL);
-               xmlnode_free(xmlRootNode);
-               return NULL;
-       }
-
-       /* get urn:schemas-upnp-org:device:WANDevice:1 and its devicelist */
-       serviceTypeNode = xmlnode_get_child(serviceTypeNode, "device");
-       while(!gaim_upnp_compare_device(serviceTypeNode,
-                       "urn:schemas-upnp-org:device:WANDevice:1") &&
-                       serviceTypeNode != NULL) {
-               serviceTypeNode = xmlnode_get_next_twin(serviceTypeNode);
-       }
-       if(serviceTypeNode == NULL) {
-               gaim_debug_error("upnp",
-                       "parse_description_response(): could not get 
serviceTypeNode 3\n");
-               g_free(baseURL);
-               xmlnode_free(xmlRootNode);
-               return NULL;
-       }
-       serviceTypeNode = xmlnode_get_child(serviceTypeNode, "deviceList");
-       if(serviceTypeNode == NULL) {
-               gaim_debug_error("upnp",
-                       "parse_description_response(): could not get 
serviceTypeNode 4\n");
-               g_free(baseURL);
-               xmlnode_free(xmlRootNode);
-               return NULL;
-       }
-
-       /* get urn:schemas-upnp-org:device:WANConnectionDevice:1 and its 
servicelist */
-       serviceTypeNode = xmlnode_get_child(serviceTypeNode, "device");
-       while(serviceTypeNode && !gaim_upnp_compare_device(serviceTypeNode,
-                       "urn:schemas-upnp-org:device:WANConnectionDevice:1")) {
-               serviceTypeNode = xmlnode_get_next_twin(serviceTypeNode);
-       }
-       if(serviceTypeNode == NULL) {
-               gaim_debug_error("upnp",
-                       "parse_description_response(): could not get 
serviceTypeNode 5\n");
-               g_free(baseURL);
-               xmlnode_free(xmlRootNode);
-               return NULL;
-       }
-       serviceTypeNode = xmlnode_get_child(serviceTypeNode, "serviceList");
-       if(serviceTypeNode == NULL) {
-               gaim_debug_error("upnp",
-                       "parse_description_response(): could not get 
serviceTypeNode 6\n");
-               g_free(baseURL);
-               xmlnode_free(xmlRootNode);
-               return NULL;
-       }
-
-       /* get the serviceType variable passed to this function */
-       service = g_strdup_printf(SEARCH_REQUEST_DEVICE, serviceType);
-       serviceTypeNode = xmlnode_get_child(serviceTypeNode, "service");
-       while(!gaim_upnp_compare_service(serviceTypeNode, service) &&
-                       serviceTypeNode != NULL) {
-               serviceTypeNode = xmlnode_get_next_twin(serviceTypeNode);
-       }
-
-       g_free(service);
-       if(serviceTypeNode == NULL) {
-               gaim_debug_error("upnp",
-                       "parse_description_response(): could not get 
serviceTypeNode 7\n");
-               g_free(baseURL);
-               xmlnode_free(xmlRootNode);
-               return NULL;
-       }
-
-       /* get the controlURL of the service */
-       if((controlURLNode = xmlnode_get_child(serviceTypeNode,
-                       "controlURL")) == NULL) {
-               gaim_debug_error("upnp",
-                       "parse_description_response(): Could not find 
controlURL\n");
-               g_free(baseURL);
-               xmlnode_free(xmlRootNode);
-               return NULL;
-       }
-
-       tmp = xmlnode_get_data(controlURLNode);
-       if(baseURL && !gaim_str_has_prefix(tmp, "http://";) &&
-          !gaim_str_has_prefix(tmp, "HTTP://")) {
-               controlURL = g_strdup_printf("%s%s", baseURL, tmp);
-               g_free(tmp);
-       }else{
-               controlURL = tmp;
-       }
-       g_free(baseURL);
-       xmlnode_free(xmlRootNode);
-
-       return controlURL;
+gaim_upnp_parse_description_response(const gchar* httpResponse, 
+                                    gsize len,
+                                    const gchar* httpURL,
+                                    const gchar* serviceType) {
+  gchar *xmlRoot, *baseURL, *controlURL, *service;
+  xmlnode *xmlRootNode, *serviceTypeNode, *controlURLNode, *baseURLNode;
+  char *tmp;
+  
+  /* make sure we have a valid http response */
+  if(g_strstr_len(httpResponse, len, HTTP_OK) == NULL) {
+    gaim_debug_error("upnp",
+                    "parse_description_response(): Failed In HTTP_OK\n");
+    return NULL;
+  }
+  
+  /* find the root of the xml document */
+  if((xmlRoot = g_strstr_len(httpResponse, len, "<root")) == NULL) {
+    gaim_debug_error("upnp",
+                    "parse_description_response(): Failed finding root\n");
+    return NULL;
+  }
+  
+  /* create the xml root node */
+  if((xmlRootNode = xmlnode_from_str(xmlRoot,
+                                    len - (xmlRoot - httpResponse))) == NULL) {
+    gaim_debug_error("upnp",
+                    "parse_description_response(): Could not parse xml root 
node\n");
+    return NULL;
+  }
+  
+  /* get the baseURL of the device */
+  if((baseURLNode = xmlnode_get_child(xmlRootNode, "URLBase")) != NULL) {
+    baseURL = xmlnode_get_data(baseURLNode);
+  } else {
+    baseURL = g_strdup(httpURL);
+  }
+  
+  /* get the serviceType child that has the service type as its data */
+  
+  /* get urn:schemas-upnp-org:device:InternetGatewayDevice:1 and its 
devicelist */
+  serviceTypeNode = xmlnode_get_child(xmlRootNode, "device");
+  while(!gaim_upnp_compare_device(serviceTypeNode,
+                                 
"urn:schemas-upnp-org:device:InternetGatewayDevice:1") &&
+       serviceTypeNode != NULL) {
+    serviceTypeNode = xmlnode_get_next_twin(serviceTypeNode);
+  }
+  if(serviceTypeNode == NULL) {
+    gaim_debug_error("upnp",
+                    "parse_description_response(): could not get 
serviceTypeNode 1\n");
+    g_free(baseURL);
+    xmlnode_free(xmlRootNode);
+    return NULL;
+  }
+  serviceTypeNode = xmlnode_get_child(serviceTypeNode, "deviceList");
+  if(serviceTypeNode == NULL) {
+    gaim_debug_error("upnp",
+                    "parse_description_response(): could not get 
serviceTypeNode 2\n");
+    g_free(baseURL);
+    xmlnode_free(xmlRootNode);
+    return NULL;
+  }
+  
+  /* get urn:schemas-upnp-org:device:WANDevice:1 and its devicelist */
+  serviceTypeNode = xmlnode_get_child(serviceTypeNode, "device");
+  while(!gaim_upnp_compare_device(serviceTypeNode,
+                                 "urn:schemas-upnp-org:device:WANDevice:1") &&
+       serviceTypeNode != NULL) {
+    serviceTypeNode = xmlnode_get_next_twin(serviceTypeNode);
+  }
+  if(serviceTypeNode == NULL) {
+    gaim_debug_error("upnp",
+                    "parse_description_response(): could not get 
serviceTypeNode 3\n");
+    g_free(baseURL);
+    xmlnode_free(xmlRootNode);
+    return NULL;
+  }
+  serviceTypeNode = xmlnode_get_child(serviceTypeNode, "deviceList");
+  if(serviceTypeNode == NULL) {
+    gaim_debug_error("upnp",
+                    "parse_description_response(): could not get 
serviceTypeNode 4\n");
+    g_free(baseURL);
+    xmlnode_free(xmlRootNode);
+    return NULL;
+  }
+  
+  /* get urn:schemas-upnp-org:device:WANConnectionDevice:1 and its servicelist 
*/
+  serviceTypeNode = xmlnode_get_child(serviceTypeNode, "device");
+  while(serviceTypeNode && !gaim_upnp_compare_device(serviceTypeNode,
+                                                    
"urn:schemas-upnp-org:device:WANConnectionDevice:1")) {
+    serviceTypeNode = xmlnode_get_next_twin(serviceTypeNode);
+  }
+  if(serviceTypeNode == NULL) {
+    gaim_debug_error("upnp",
+                    "parse_description_response(): could not get 
serviceTypeNode 5\n");
+    g_free(baseURL);
+    xmlnode_free(xmlRootNode);
+    return NULL;
+  }
+  serviceTypeNode = xmlnode_get_child(serviceTypeNode, "serviceList");
+  if(serviceTypeNode == NULL) {
+    gaim_debug_error("upnp",
+                    "parse_description_response(): could not get 
serviceTypeNode 6\n");
+    g_free(baseURL);
+    xmlnode_free(xmlRootNode);
+    return NULL;
+  }
+  
+  /* get the serviceType variable passed to this function */
+  service = g_strdup_printf(SEARCH_REQUEST_DEVICE, serviceType);
+  serviceTypeNode = xmlnode_get_child(serviceTypeNode, "service");
+  while(!gaim_upnp_compare_service(serviceTypeNode, service) &&
+       serviceTypeNode != NULL) {
+    serviceTypeNode = xmlnode_get_next_twin(serviceTypeNode);
+  }
+  
+  g_free(service);
+  if(serviceTypeNode == NULL) {
+    gaim_debug_error("upnp",
+                    "parse_description_response(): could not get 
serviceTypeNode 7\n");
+    g_free(baseURL);
+    xmlnode_free(xmlRootNode);
+    return NULL;
+  }
+  
+  /* get the controlURL of the service */
+  if((controlURLNode = xmlnode_get_child(serviceTypeNode,
+                                        "controlURL")) == NULL) {
+    gaim_debug_error("upnp",
+                    "parse_description_response(): Could not find 
controlURL\n");
+    g_free(baseURL);
+    xmlnode_free(xmlRootNode);
+    return NULL;
+  }
+  
+  tmp = xmlnode_get_data(controlURLNode);
+  if(baseURL && !gaim_str_has_prefix(tmp, "http://";) &&
+     !gaim_str_has_prefix(tmp, "HTTP://")) {
+    controlURL = g_strdup_printf("%s%s", baseURL, tmp);
+    g_free(tmp);
+  } else{
+    controlURL = tmp;
+  }
+  g_free(baseURL);
+  xmlnode_free(xmlRootNode);
+  
+  return controlURL;
 }
 
-static void
-upnp_parse_description_cb(GaimUtilFetchUrlData *url_data, gpointer user_data,
-               const gchar *httpResponse, gsize len, const gchar 
*error_message)
-{
-       UPnPDiscoveryData *dd = user_data;
-       gchar *control_url = NULL;
+#define CURL_EASY_SETOPT(c, a, b) do { ret = curl_easy_setopt(c, a, b); if 
(ret != CURLE_OK) GE_LOG(NULL, GE_WARNING | GE_USER | GE_BULK, _("%s failed at 
%s:%d: `%s'\n"), "curl_easy_setopt", __FILE__, __LINE__, 
curl_easy_strerror(ret)); } while (0);
 
-       if (len > 0)
-               control_url = gaim_upnp_parse_description_response(
-                       httpResponse, len, dd->full_url, dd->service_type);
+/**
+ * Do the generic curl setup.
+ */
+static int setup_curl(const char * proxy,
+                     CURL * curl) {
+  int ret;
 
-       g_free(dd->full_url);
-
-       if(control_url == NULL) {
-               gaim_debug_error("upnp",
-                       "gaim_upnp_parse_description(): control URL is NULL\n");
-       }
-
-       control_info.status = control_url ? GAIM_UPNP_STATUS_DISCOVERED
-               : GAIM_UPNP_STATUS_UNABLE_TO_DISCOVER;
-       control_info.lookup_time = time(NULL);
-       control_info.control_url = control_url;
-       strncpy(control_info.service_type, dd->service_type,
-               sizeof(control_info.service_type));
-
-       fire_discovery_callbacks(control_url != NULL);
-
-       /* Look up the public and internal IPs */
-       if(control_url != NULL) {
-               lookup_public_ip();
-               lookup_internal_ip();
-       }
-
-       g_free(dd);
+  ret = CURLE_OK;
+  CURL_EASY_SETOPT(curl,
+                  CURLOPT_FAILONERROR,
+                  1);
+  if (strlen(proxy) > 0)
+    CURL_EASY_SETOPT(curl,
+                    CURLOPT_PROXY,
+                    proxy);
+  CURL_EASY_SETOPT(curl,
+                  CURLOPT_BUFFERSIZE,
+                  1024); /* a bit more than one HELLO */
+  CURL_EASY_SETOPT(curl,
+                  CURLOPT_CONNECTTIMEOUT,
+                  150L);
+  /* NOTE: use of CONNECTTIMEOUT without also
+     setting NOSIGNAL results in really weird
+     crashes on my system! */
+  CURL_EASY_SETOPT(curl,
+                  CURLOPT_NOSIGNAL,
+                  1);
+  if (ret != CURLE_OK)
+    return SYSERR;
+  return OK;
 }
 
-static void
-gaim_upnp_parse_description(const gchar* descriptionURL, UPnPDiscoveryData *dd)
-{
-       gchar* httpRequest;
-       gchar* descriptionXMLAddress;
-       gchar* descriptionAddress;
-       int port = 0;
+static int
+gaim_upnp_generate_action_message_and_send(const char * proxy,
+                                          const gchar* actionName,
+                                          const gchar* actionParams, 
+                                          GaimUtilFetchUrlCallback cb,
+                                          gpointer cb_data) {
+  gchar * soapMessage;
+  CURL * curl; 
+  gchar * postfields;
+  int ret;
 
-       /* parse the 4 above variables out of the descriptionURL
-          example description URL: http://192.168.1.1:5678/rootDesc.xml */
-
-       /* parse the url into address, port, path variables */
-       if(!gaim_url_parse(descriptionURL, &descriptionAddress,
-                       &port, &descriptionXMLAddress, NULL, NULL)) {
-               return;
-       }
-       if(port == 0 || port == -1) {
-               port = DEFAULT_HTTP_PORT;
-       }
-
-       /* for example...
-          GET /rootDesc.xml HTTP/1.1\r\nHost: 192.168.1.1:5678\r\n\r\n */
-       httpRequest = g_strdup_printf(
-               "GET /%s HTTP/1.1\r\n"
-               "Connection: close\r\n"
-               "Host: %s:%d\r\n\r\n",
-               descriptionXMLAddress, descriptionAddress, port);
-
-       g_free(descriptionXMLAddress);
-
-       dd->full_url = g_strdup_printf("http://%s:%d";,
-                       descriptionAddress, port);
-       g_free(descriptionAddress);
-
-       /* Remove the timeout because everything it is waiting for has
-        * successfully completed */
-       gaim_timeout_remove(dd->tima);
-       dd->tima = 0;
-
-       gaim_util_fetch_url_request(descriptionURL, TRUE, NULL, TRUE, 
httpRequest,
-                       TRUE, upnp_parse_description_cb, dd);
-
-       g_free(httpRequest);
-
+  if (0 != curl_global_init(CURL_GLOBAL_WIN32)) 
+    return SYSERR;
+  /* set the soap message */
+  soapMessage = g_strdup_printf(SOAP_ACTION, 
+                               actionName,
+                               control_info.service_type, 
+                               actionParams, 
+                               actionName);
+  postfields = g_strdup_printf(HTTP_POST_SOAP_ACTION, 
+                              control_info.service_type, 
+                              actionName,
+                              strlen(soapMessage),
+                              soapMessage);
+  g_free(soapMessage);
+  curl = curl_easy_init();
+  setup_curl(proxy, curl);
+  ret = CURLE_OK;
+  CURL_EASY_SETOPT(curl,
+                  CURLOPT_URL,
+                  control_info.control_url);
+  CURL_EASY_SETOPT(curl,
+                  CURLOPT_WRITEFUNCTION,
+                  cb);
+  CURL_EASY_SETOPT(curl,
+                  CURLOPT_WRITEDATA,
+                  cb_data);
+  CURL_EASY_SETOPT(curl,
+                  CURLOPT_POST,
+                  1);
+  CURL_EASY_SETOPT(curl,
+                  CURLOPT_POSTFIELDS,
+                  postfields);
+  if (ret == CURLE_OK)
+    ret = curl_easy_perform(curl);
+  if (ret != CURLE_OK)
+    GE_LOG(NULL,
+          GE_ERROR | GE_ADMIN | GE_DEVELOPER | GE_BULK,
+          _("%s failed at %s:%d: `%s'\n"),
+          "curl_easy_perform",
+          __FILE__,
+          __LINE__,
+          curl_easy_strerror(ret));
+  curl_easy_cleanup(curl);
+  curl_global_cleanup();
+  g_free(postfields);
+  if (ret != CURLE_OK)
+    return SYSERR;
+  return OK;
 }
 
-static void
-gaim_upnp_parse_discover_response(const gchar* buf, unsigned int buf_len,
-       UPnPDiscoveryData *dd)
-{
-       gchar* startDescURL;
-       gchar* endDescURL;
-       gchar* descURL;
 
-       if(g_strstr_len(buf, buf_len, HTTP_OK) == NULL) {
-               gaim_debug_error("upnp",
-                       "parse_discover_response(): Failed In HTTP_OK\n");
-               return;
-       }
+static size_t
+looked_up_public_ip_cb(void *url_data, 
+                      size_t size,
+                      size_t nmemb,                  
+                      gpointer user_data) {
+  UPnPDiscoveryData * dd = user_data;
+  size_t len = size * nmemb;
+  const gchar * temp;
+  const gchar * temp2;
 
-       if((startDescURL = g_strstr_len(buf, buf_len, "http://";)) == NULL) {
-               gaim_debug_error("upnp",
-                       "parse_discover_response(): Failed In finding 
http://\n";);
-               return;
-       }
-
-       endDescURL = g_strstr_len(startDescURL, buf_len - (startDescURL - buf),
-                       "\r");
-       if(endDescURL == NULL) {
-               endDescURL = g_strstr_len(startDescURL,
-                               buf_len - (startDescURL - buf), "\n");
-               if(endDescURL == NULL) {
-                       gaim_debug_error("upnp",
-                               "parse_discover_response(): Failed In 
endDescURL\n");
-                       return;
-               }
-       }
-
-       /* XXX: I'm not sure how this could ever happen */
-       if(endDescURL == startDescURL) {
-               gaim_debug_error("upnp",
-                       "parse_discover_response(): endDescURL == 
startDescURL\n");
-               return;
-       }
-
-       descURL = g_strndup(startDescURL, endDescURL - startDescURL);
-
-       gaim_upnp_parse_description(descURL, dd);
-
-       g_free(descURL);
-
+  if (len + dd->buf_len > 1024 * 1024 * 4)
+    return len; /* refuse to process - too big! */
+  GROW(dd->buf,
+       dd->buf_len,
+       dd->buf_len + len);
+  memcpy(&dd->buf[dd->buf_len - len],
+        url_data,
+        len);
+  if (dd->buf_len == 0)
+    return len;
+  /* extract the ip, or see if there is an error */
+  if ((temp = g_strstr_len(dd->buf,
+                          dd->buf_len,
+                          "<NewExternalIPAddress")) == NULL) 
+    return len;  
+  if (!(temp = g_strstr_len(temp, 
+                           dd->buf_len - (temp - dd->buf), ">"))) 
+    return len;
+  if (!(temp2 = g_strstr_len(temp, 
+                            dd->buf_len - (temp - dd->buf), "<"))) 
+    return len;
+  memset(control_info.publicip, 
+        0,
+        sizeof(control_info.publicip));
+  if (temp2 - temp >= sizeof(control_info.publicip))
+    temp2 = temp + sizeof(control_info.publicip) - 1;
+  memcpy(control_info.publicip, 
+        temp + 1,
+        temp2 - (temp + 1));
+  GE_LOG(NULL,
+        GE_INFO | GE_USER | GE_BULK,
+        _("upnp: NAT Returned IP: %s\n"),
+        control_info.publicip);
+  return len;
 }
 
-static gboolean
-gaim_upnp_discover_timeout(gpointer data)
-{
-       UPnPDiscoveryData* dd = data;
-
-       if (dd->inpa)
-               gaim_input_remove(dd->inpa);
-       dd->inpa = 0;
-       dd->tima = 0;
-
-       if (dd->retry_count < NUM_UDP_ATTEMPTS) {
-               /* TODO: We probably shouldn't be incrementing retry_count in 
two places */
-               dd->retry_count++;
-               gaim_upnp_discover_send_broadcast(dd);
-       } else {
-               if (dd->fd)
-                       close(dd->fd);
-
-               control_info.status = GAIM_UPNP_STATUS_UNABLE_TO_DISCOVER;
-               control_info.lookup_time = time(NULL);
-               control_info.service_type[0] = '\0';
-               g_free(control_info.control_url);
-               control_info.control_url = NULL;
-
-               fire_discovery_callbacks(FALSE);
-
-               g_free(dd);
-       }
-
-       return FALSE;
+/**
+ * Process downloaded bits of service description.
+ */
+static size_t
+upnp_parse_description_cb(void * httpResponse,
+                         size_t size,
+                         size_t nmemb,
+                         void * user_data) {
+  UPnPDiscoveryData * dd = user_data;
+  gsize len = size * nmemb;
+  gchar * control_url = NULL;
+  
+  if (len + dd->buf_len > 1024 * 1024 * 4)
+    return len; /* refuse to process - too big! */
+  GROW(dd->buf,
+       dd->buf_len,
+       dd->buf_len + len);
+  memcpy(&dd->buf[dd->buf_len - len],
+        httpResponse,
+        len);
+  if (dd->buf_len > 0)
+    control_url = gaim_upnp_parse_description_response(dd->buf,
+                                                      dd->buf_len,
+                                                      dd->full_url,
+                                                      dd->service_type);
+  control_info.status = control_url ? GAIM_UPNP_STATUS_DISCOVERED
+    : GAIM_UPNP_STATUS_UNABLE_TO_DISCOVER;
+  FREENONNULL(control_info.control_url);
+  control_info.control_url = control_url;
+  control_info.service_type = dd->service_type;
+  return len;
 }
 
-static void
-gaim_upnp_discover_udp_read(gpointer data, gint sock, GaimInputCondition cond)
-{
-       int len;
-       UPnPDiscoveryData *dd = data;
-       gchar buf[65536];
-
-       do {
-               len = recv(dd->fd, buf,
-                       sizeof(buf) - 1, 0);
-
-               if(len > 0) {
-                       buf[len] = '\0';
-                       break;
-               } else if(errno != EINTR) {
-                       /* We'll either get called again, or time out */
-                       return;
-               }
-       } while (errno == EINTR);
-
-       gaim_input_remove(dd->inpa);
-       dd->inpa = 0;
-
-       close(dd->fd);
-       dd->fd = 0;
-
-       /* parse the response, and see if it was a success */
-       gaim_upnp_parse_discover_response(buf, len, dd);
-
-       /* We'll either time out or continue successfully */
+static int
+gaim_upnp_parse_description(char * proxy,
+                           UPnPDiscoveryData * dd) {
+  CURL * curl; 
+  int ret;
+  
+  if (0 != curl_global_init(CURL_GLOBAL_WIN32)) 
+    return SYSERR;
+  curl = curl_easy_init();
+  setup_curl(proxy, curl);
+  ret = CURLE_OK;
+  CURL_EASY_SETOPT(curl,
+                  CURLOPT_URL,
+                  dd->full_url);
+  CURL_EASY_SETOPT(curl,
+                  CURLOPT_WRITEFUNCTION,
+                  &upnp_parse_description_cb);
+  CURL_EASY_SETOPT(curl,
+                  CURLOPT_WRITEDATA,
+                  dd);
+  ret = curl_easy_perform(curl);
+  if (ret != CURLE_OK)
+    GE_LOG(NULL,
+          GE_ERROR | GE_ADMIN | GE_DEVELOPER | GE_BULK,
+          _("%s failed at %s:%d: `%s'\n"),
+          "curl_easy_perform",
+          __FILE__,
+          __LINE__,
+          curl_easy_strerror(ret));
+  curl_easy_cleanup(curl);
+  curl_global_cleanup();
+  if (control_info.control_url == NULL)
+    return SYSERR;
+  return OK;
 }
 
-static void
-gaim_upnp_discover_send_broadcast(UPnPDiscoveryData *dd)
-{
-       gchar *sendMessage = NULL;
-       gsize totalSize;
-       gboolean sentSuccess;
+int
+gaim_upnp_discover(struct GE_Context * ectx,
+                  struct GC_Configuration * cfg) {
+  char * proxy;
+  struct hostent* hp;
+  struct sockaddr_in server;
+  int retry_count;
+  gchar * sendMessage;
+  gsize totalSize;
+  gboolean sentSuccess;
+  gchar buf[65536];
+  int buf_len;
+  const gchar * startDescURL;
+  const gchar * endDescURL;
+  int ret;
+  UPnPDiscoveryData dd;
 
-       /* because we are sending over UDP, if there is a failure
-          we should retry the send NUM_UDP_ATTEMPTS times. Also,
-          try different requests for WANIPConnection and WANPPPConnection*/
-       for(; dd->retry_count < NUM_UDP_ATTEMPTS; dd->retry_count++) {
-               sentSuccess = FALSE;
+  memset(&dd,
+        0, 
+        sizeof(UPnPDiscoveryData));
+  if (control_info.status == GAIM_UPNP_STATUS_DISCOVERING) 
+    return NO;
+  dd.sock = SOCKET(AF_INET, SOCK_DGRAM, 0);
+  if (dd.sock == -1) 
+    return SYSERR;
+  hp = gethostbyname(HTTPMU_HOST_ADDRESS);
+  if (hp == NULL) {
+    CLOSE(dd.sock);
+    return SYSERR; 
+  } 
+  memset(&server,
+        0, 
+        sizeof(struct sockaddr));
+  server.sin_family = AF_INET;
+  memcpy(&server.sin_addr,
+        hp->h_addr_list[0],
+        hp->h_length);
+  server.sin_port = htons(HTTPMU_HOST_PORT);  
+  control_info.status = GAIM_UPNP_STATUS_DISCOVERING;
+  
+  /* because we are sending over UDP, if there is a failure
+     we should retry the send NUM_UDP_ATTEMPTS times. Also,
+     try different requests for WANIPConnection and WANPPPConnection*/
+  for (retry_count=0;retry_count<NUM_UDP_ATTEMPTS;retry_count++) {
+    sentSuccess = FALSE;    
+    if((retry_count % 2) == 0) 
+      dd.service_type = WAN_IP_CONN_SERVICE;
+    else 
+      dd.service_type = WAN_PPP_CONN_SERVICE;    
+    sendMessage = g_strdup_printf(SEARCH_REQUEST_STRING, 
+                                 dd.service_type);
+    totalSize = strlen(sendMessage);
+    do {
+      if (SENDTO(dd.sock,
+                sendMessage, 
+                totalSize, 
+                0,
+                (struct sockaddr*) &server,
+                sizeof(struct sockaddr_in)) == totalSize) {
+       sentSuccess = TRUE;
+       break;
+      }
+    } while ( ((errno == EINTR) || (errno == EAGAIN)) &&
+             (GNUNET_SHUTDOWN_TEST() == NO));
+    g_free(sendMessage);    
+    if (sentSuccess) {
+      gaim_timeout_add(DISCOVERY_TIMEOUT,
+                      gaim_upnp_discover_timeout, 
+                      &dd);
+      break;
+    }
+  }
+  if (sentSuccess == FALSE) {
+    CLOSE(dd.sock);
+    return SYSERR;
+  }
 
-               if((dd->retry_count % 2) == 0) {
-                       strncpy(dd->service_type, WAN_IP_CONN_SERVICE, 
sizeof(dd->service_type));
-               } else {
-                       strncpy(dd->service_type, WAN_PPP_CONN_SERVICE, 
sizeof(dd->service_type));
-               }
+  /* try to read response */
+  do {
+    buf_len = recv(dd.sock,
+                  buf,
+                  sizeof(buf) - 1, 
+                  0);   
+    if (buf_len > 0) {
+      buf[buf_len] = '\0';
+      break;
+    } else if (errno != EINTR) {
+      continue;
+    }
+  } while ( (errno == EINTR) &&
+           (GNUNET_SHUTDOWN_TEST() == NO) );
+  CLOSE(dd.sock);
 
-               sendMessage = g_strdup_printf(SEARCH_REQUEST_STRING, 
dd->service_type);
-
-               totalSize = strlen(sendMessage);
-
-               do {
-                       if(sendto(dd->fd, sendMessage, totalSize, 0,
-                                       (struct sockaddr*) &(dd->server),
-                                       sizeof(struct sockaddr_in)
-                                       ) == totalSize) {
-                               sentSuccess = TRUE;
-                               break;
-                       }
-               } while (errno == EINTR || errno == EAGAIN);
-
-               g_free(sendMessage);
-
-               if(sentSuccess) {
-                       dd->tima = gaim_timeout_add(DISCOVERY_TIMEOUT,
-                               gaim_upnp_discover_timeout, dd);
-                       dd->inpa = gaim_input_add(dd->fd, GAIM_INPUT_READ,
-                               gaim_upnp_discover_udp_read, dd);
-
-                       return;
-               }
-       }
-
-       /* We have already done all our retries. Make sure that the callback
-        * doesn't get called before the original function returns */
-       gaim_timeout_add(10, gaim_upnp_discover_timeout, dd);
+  /* parse the response, and see if it was a success */
+  if (g_strstr_len(buf, buf_len, HTTP_OK) == NULL) 
+    return SYSERR; 
+  if ( (startDescURL = g_strstr_len(buf, buf_len, "http://";)) == NULL) 
+    return SYSERR;  
+  
+  endDescURL = g_strstr_len(startDescURL,
+                           buf_len - (startDescURL - buf),
+                           "\r");
+  if (endDescURL == NULL) 
+    endDescURL = g_strstr_len(startDescURL,
+                             buf_len - (startDescURL - buf), "\n");
+  if(endDescURL == NULL) 
+    return SYSERR;  
+  if (endDescURL == startDescURL) 
+    return SYSERR;    
+  dd.full_url = g_strndup(startDescURL,
+                         endDescURL - startDescURL); 
+  proxy = NULL; /* FIXME */
+  ret = gaim_upnp_parse_description(proxy,
+                                   &dd);  
+  g_free(dd.full_url);
+  GROW(dd.buf,
+       dd.buf_len,
+       0);
+  if (ret == OK) {
+    ret = gaim_upnp_generate_action_message_and_send(proxy,
+                                                    "GetExternalIPAddress", 
+                                                    "",
+                                                    looked_up_public_ip_cb, 
+                                                    &dd);
+    GROW(dd.buf,
+        dd.buf_len,
+        0);
+  }
+  return ret;
 }
 
-void
-gaim_upnp_discover(GaimUPnPCallback cb, gpointer cb_data)
-{
-       /* Socket Setup Variables */
-       int sock;
-       struct hostent* hp;
-
-       /* UDP RECEIVE VARIABLES */
-       UPnPDiscoveryData *dd;
-
-       if (control_info.status == GAIM_UPNP_STATUS_DISCOVERING) {
-               if (cb) {
-                       discovery_callbacks = g_slist_append(
-                                       discovery_callbacks, cb);
-                       discovery_callbacks = g_slist_append(
-                                       discovery_callbacks, cb_data);
-               }
-               return;
-       }
-
-       dd = g_new0(UPnPDiscoveryData, 1);
-       if (cb) {
-               discovery_callbacks = g_slist_append(discovery_callbacks, cb);
-               discovery_callbacks = g_slist_append(discovery_callbacks,
-                               cb_data);
-       }
-
-       /* Set up the sockets */
-       sock = socket(AF_INET, SOCK_DGRAM, 0);
-       if(sock == -1) {
-               gaim_debug_error("upnp",
-                       "gaim_upnp_discover(): Failed In sock creation\n");
-               /* Short circuit the retry attempts */
-               dd->retry_count = NUM_UDP_ATTEMPTS;
-               gaim_timeout_add(10, gaim_upnp_discover_timeout, dd);
-               return;
-       }
-
-       dd->fd = sock;
-
-       /* TODO: Non-blocking! */
-       if((hp = gethostbyname(HTTPMU_HOST_ADDRESS)) == NULL) {
-               gaim_debug_error("upnp",
-                       "gaim_upnp_discover(): Failed In gethostbyname\n");
-               /* Short circuit the retry attempts */
-               dd->retry_count = NUM_UDP_ATTEMPTS;
-               gaim_timeout_add(10, gaim_upnp_discover_timeout, dd);
-               return;
-       }
-
-       memset(&(dd->server), 0, sizeof(struct sockaddr));
-       dd->server.sin_family = AF_INET;
-       memcpy(&(dd->server.sin_addr), hp->h_addr_list[0], hp->h_length);
-       dd->server.sin_port = htons(HTTPMU_HOST_PORT);
-
-       control_info.status = GAIM_UPNP_STATUS_DISCOVERING;
-
-       gaim_upnp_discover_send_broadcast(dd);
-}
-
-static void
-gaim_upnp_generate_action_message_and_send(const gchar* actionName,
-               const gchar* actionParams, GaimUtilFetchUrlCallback cb,
-               gpointer cb_data)
-{
-
-       gchar* soapMessage;
-       gchar* totalSendMessage;
-       gchar* pathOfControl;
-       gchar* addressOfControl;
-       int port = 0;
-
-       /* parse the url into address, port, path variables */
-       if(!gaim_url_parse(control_info.control_url, &addressOfControl,
-                       &port, &pathOfControl, NULL, NULL)) {
-               gaim_debug_error("upnp",
-                       "generate_action_message_and_send(): Failed In Parse 
URL\n");
-               /* XXX: This should probably be async */
-               if(cb)
-                       cb(NULL, cb_data, NULL, 0, NULL);
-       }
-       if(port == 0 || port == -1) {
-               port = DEFAULT_HTTP_PORT;
-       }
-
-       /* set the soap message */
-       soapMessage = g_strdup_printf(SOAP_ACTION, actionName,
-               control_info.service_type, actionParams, actionName);
-
-       /* set the HTTP Header, and append the body to it */
-       totalSendMessage = g_strdup_printf(HTTP_HEADER_ACTION "%s",
-               pathOfControl, addressOfControl, port,
-               control_info.service_type, actionName,
-               strlen(soapMessage), soapMessage);
-       g_free(pathOfControl);
-       g_free(soapMessage);
-
-       gaim_util_fetch_url_request(control_info.control_url, FALSE, NULL, TRUE,
-                       totalSendMessage, TRUE, cb, cb_data);
-
-       g_free(totalSendMessage);
-       g_free(addressOfControl);
-}
-
 const gchar *
-gaim_upnp_get_public_ip()
-{
-       if (control_info.status == GAIM_UPNP_STATUS_DISCOVERED
-                       && control_info.publicip
-                       && strlen(control_info.publicip) > 0)
-               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 < GAIM_UPNP_STATUS_DISCOVERING
-                       && (time(NULL) - control_info.lookup_time) > 300)
-               gaim_upnp_discover(NULL, NULL);
-
-       return NULL;
+gaim_upnp_get_public_ip() {
+  if (control_info.status == GAIM_UPNP_STATUS_DISCOVERED
+      && control_info.publicip
+      && strlen(control_info.publicip) > 0)
+    return control_info.publicip;
+  return NULL;
 }
 
-static void
-looked_up_public_ip_cb(GaimUtilFetchUrlData *url_data, gpointer user_data,
-               const gchar *httpResponse, gsize len, const gchar 
*error_message)
-{
-       gchar* temp, *temp2;
-
-       if ((error_message != NULL) || (httpResponse == NULL))
-               return;
-
-       /* extract the ip, or see if there is an error */
-       if((temp = g_strstr_len(httpResponse, len,
-                       "<NewExternalIPAddress")) == NULL) {
-               gaim_debug_error("upnp",
-                       "looked_up_public_ip_cb(): Failed Finding 
<NewExternalIPAddress\n");
-               return;
-       }
-       if(!(temp = g_strstr_len(temp, len - (temp - httpResponse), ">"))) {
-               gaim_debug_error("upnp",
-                       "looked_up_public_ip_cb(): Failed In Finding >\n");
-               return;
-       }
-       if(!(temp2 = g_strstr_len(temp, len - (temp - httpResponse), "<"))) {
-               gaim_debug_error("upnp",
-                       "looked_up_public_ip_cb(): Failed In Finding <\n");
-               return;
-       }
-       *temp2 = '\0';
-
-       strncpy(control_info.publicip, temp + 1,
-                       sizeof(control_info.publicip));
-
-       gaim_debug_info("upnp", "NAT Returned IP: %s\n", control_info.publicip);
+int
+gaim_upnp_change_port_mapping(struct GE_Context * ectx,
+                             struct GC_Configuration * cfg,
+                             int do_add,
+                             unsigned short portmap, 
+                             const gchar* protocol) {
+  const gchar * action_name;
+  gchar * action_params;
+  const gchar * internal_ip;
+  char * proxy;
+  int ret;
+    
+  if (control_info.status != GAIM_UPNP_STATUS_DISCOVERED) 
+    return NO; 
+  if (do_add) {
+    internal_ip = gaim_upnp_get_internal_ip();
+    if(internal_ip == NULL) {
+      gaim_debug_error("upnp",
+                      "gaim_upnp_set_port_mapping(): couldn't get local ip\n");
+      return NO;
+    }
+    action_name = "AddPortMapping";
+    action_params = g_strdup_printf(ADD_PORT_MAPPING_PARAMS,
+                                   portmap, 
+                                   protocol,
+                                   portmap,
+                                   internal_ip);
+  } else {
+    action_name = "DeletePortMapping";
+    action_params = g_strdup_printf(DELETE_PORT_MAPPING_PARAMS,
+                                   portmap, 
+                                   protocol);
+  }  
+  proxy = NULL; /* FIXME! */
+  ret = gaim_upnp_generate_action_message_and_send(proxy,
+                                                  action_name,
+                                                  action_params,
+                                                  NULL,
+                                                  NULL);
+  
+  g_free(action_params);
+  return ret; 
 }
-
-static void
-lookup_public_ip()
-{
-       gaim_upnp_generate_action_message_and_send("GetExternalIPAddress", "",
-                       looked_up_public_ip_cb, NULL);
-}
-
-/* TODO: This could be exported */
-static const gchar *
-gaim_upnp_get_internal_ip()
-{
-       if (control_info.status == GAIM_UPNP_STATUS_DISCOVERED
-                       && control_info.internalip
-                       && strlen(control_info.internalip) > 0)
-               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 < GAIM_UPNP_STATUS_DISCOVERING
-                       && (time(NULL) - control_info.lookup_time) > 300)
-               gaim_upnp_discover(NULL, NULL);
-
-       return NULL;
-}
-
-#if 0
-static void
-looked_up_internal_ip_cb(gpointer data, gint source, const gchar 
*error_message)
-{
-       if (source) {
-               strncpy(control_info.internalip,
-                       gaim_network_get_local_system_ip(source),
-                       sizeof(control_info.internalip));
-               gaim_debug_info("upnp", "Local IP: %s\n",
-                               control_info.internalip);
-               close(source);
-       } else
-               gaim_debug_info("upnp", "Unable to look up local IP\n");
-
-}
-#endif
-
-static void
-lookup_internal_ip()
-{
-#if 0
-       gchar* addressOfControl;
-       int port = 0;
-
-       if(!gaim_url_parse(control_info.control_url, &addressOfControl, &port,
-                       NULL, NULL, NULL)) {
-               gaim_debug_error("upnp",
-                       "lookup_internal_ip(): Failed In Parse URL\n");
-               return;
-       }
-       if(port == 0 || port == -1) {
-               port = DEFAULT_HTTP_PORT;
-       }
-
-       if(gaim_proxy_connect(NULL, NULL, addressOfControl, port,
-                       looked_up_internal_ip_cb, NULL) == NULL)
-       {
-               gaim_debug_error("upnp", "Get Local IP Connect Failed: Address: 
%s @@@ Port %d\n",
-                       addressOfControl, port);
-       }
-
-       g_free(addressOfControl);
-#endif
-}
-
-static void
-done_port_mapping_cb(GaimUtilFetchUrlData *url_data, gpointer user_data,
-               const gchar *httpResponse, gsize len, const gchar 
*error_message)
-{
-       UPnPMappingAddRemove *ar = user_data;
-
-       gboolean success = TRUE;
-
-       /* determine if port mapping was a success */
-       if ((error_message != NULL) || (httpResponse == NULL) ||
-               (g_strstr_len(httpResponse, len, HTTP_OK) == NULL))
-       {
-               gaim_debug_error("upnp",
-                       "gaim_upnp_set_port_mapping(): Failed HTTP_OK\n%s\n",
-                       httpResponse ? httpResponse : "(null)");
-               success =  FALSE;
-       } else
-               gaim_debug_info("upnp", "Successfully completed port mapping 
operation\n");
-
-       if (ar->cb)
-               ar->cb(success, ar->cb_data);
-       g_free(ar);
-}
-
-static void
-do_port_mapping_cb(gboolean has_control_mapping, gpointer data)
-{
-       UPnPMappingAddRemove *ar = data;
-
-       if (has_control_mapping) {
-               gchar action_name[25];
-               gchar *action_params;
-               if(ar->add) {
-                       const gchar *internal_ip;
-                       /* get the internal IP */
-                       if(!(internal_ip = gaim_upnp_get_internal_ip())) {
-                               gaim_debug_error("upnp",
-                                       "gaim_upnp_set_port_mapping(): couldn't 
get local ip\n");
-                               /* UGLY */
-                               if (ar->cb)
-                                       ar->cb(FALSE, ar->cb_data);
-                               g_free(ar);
-                               return;
-                       }
-                       strncpy(action_name, "AddPortMapping",
-                                       sizeof(action_name));
-                       action_params = g_strdup_printf(
-                                       ADD_PORT_MAPPING_PARAMS,
-                                       ar->portmap, ar->protocol, ar->portmap,
-                                       internal_ip);
-               } else {
-                       strncpy(action_name, "DeletePortMapping", 
sizeof(action_name));
-                       action_params = g_strdup_printf(
-                               DELETE_PORT_MAPPING_PARAMS,
-                               ar->portmap, ar->protocol);
-               }
-
-               gaim_upnp_generate_action_message_and_send(action_name,
-                               action_params, done_port_mapping_cb, ar);
-
-               g_free(action_params);
-               return;
-       }
-
-
-       if (ar->cb)
-               ar->cb(FALSE, ar->cb_data);
-       g_free(ar);
-}
-
-static gboolean
-fire_port_mapping_failure_cb(gpointer data)
-{
-       do_port_mapping_cb(FALSE, data);
-       return FALSE;
-}
-
-void
-gaim_upnp_set_port_mapping(unsigned short portmap, const gchar* protocol,
-               GaimUPnPCallback cb, gpointer cb_data)
-{
-       UPnPMappingAddRemove *ar;
-
-       ar = g_new0(UPnPMappingAddRemove, 1);
-       ar->cb = cb;
-       ar->cb_data = cb_data;
-       ar->add = TRUE;
-       ar->portmap = portmap;
-       strncpy(ar->protocol, protocol, sizeof(ar->protocol));
-
-       /* If we're waiting for a discovery, add to the callbacks list */
-       if(control_info.status == GAIM_UPNP_STATUS_DISCOVERING) {
-               /* TODO: This will fail because when this cb is triggered,
-                * the internal IP lookup won't be complete */
-               discovery_callbacks = g_slist_append(
-                               discovery_callbacks, do_port_mapping_cb);
-               discovery_callbacks = g_slist_append(
-                               discovery_callbacks, ar);
-               return;
-       }
-
-       /* If we haven't had a successful UPnP discovery, check if 5 minutes has
-        * elapsed since the last try, try again */
-       if(control_info.status == GAIM_UPNP_STATUS_UNDISCOVERED ||
-                       (control_info.status == 
GAIM_UPNP_STATUS_UNABLE_TO_DISCOVER
-                        && (time(NULL) - control_info.lookup_time) > 300)) {
-               gaim_upnp_discover(do_port_mapping_cb, ar);
-               return;
-       } else if(control_info.status == GAIM_UPNP_STATUS_UNABLE_TO_DISCOVER) {
-               if (cb) {
-                       /* Asynchronously trigger a failed response */
-                       gaim_timeout_add(10, fire_port_mapping_failure_cb, ar);
-               } else {
-                       /* No need to do anything if nobody expects a response*/
-                       g_free(ar);
-               }
-               return;
-       }
-
-       do_port_mapping_cb(TRUE, ar);
-}
-
-void
-gaim_upnp_remove_port_mapping(unsigned short portmap, const char* protocol,
-               GaimUPnPCallback cb, gpointer cb_data)
-{
-       UPnPMappingAddRemove *ar;
-
-       ar = g_new0(UPnPMappingAddRemove, 1);
-       ar->cb = cb;
-       ar->cb_data = cb_data;
-       ar->add = FALSE;
-       ar->portmap = portmap;
-       strncpy(ar->protocol, protocol, sizeof(ar->protocol));
-
-       /* If we're waiting for a discovery, add to the callbacks list */
-       if(control_info.status == GAIM_UPNP_STATUS_DISCOVERING) {
-               discovery_callbacks = g_slist_append(
-                               discovery_callbacks, do_port_mapping_cb);
-               discovery_callbacks = g_slist_append(
-                               discovery_callbacks, ar);
-               return;
-       }
-
-       /* If we haven't had a successful UPnP discovery, check if 5 minutes has
-        * elapsed since the last try, try again */
-       if(control_info.status == GAIM_UPNP_STATUS_UNDISCOVERED ||
-                       (control_info.status == 
GAIM_UPNP_STATUS_UNABLE_TO_DISCOVER
-                        && (time(NULL) - control_info.lookup_time) > 300)) {
-               gaim_upnp_discover(do_port_mapping_cb, ar);
-               return;
-       } else if(control_info.status == GAIM_UPNP_STATUS_UNABLE_TO_DISCOVER) {
-               if (cb) {
-                       /* Asynchronously trigger a failed response */
-                       gaim_timeout_add(10, fire_port_mapping_failure_cb, ar);
-               } else {
-                       /* No need to do anything if nobody expects a response*/
-                       g_free(ar);
-               }
-               return;
-       }
-
-       do_port_mapping_cb(TRUE, ar);
-}

Modified: GNUnet/src/transports/upnp/upnp.h
===================================================================
--- GNUnet/src/transports/upnp/upnp.h   2006-12-29 05:17:33 UTC (rev 4095)
+++ GNUnet/src/transports/upnp/upnp.h   2006-12-29 10:03:33 UTC (rev 4096)
@@ -26,44 +26,29 @@
 #ifndef _GAIM_UPNP_H_
 #define _GAIM_UPNP_H_
 
+#include <libxml/parser.h>
+#include <string.h>
+#include <glib.h>
+#include "gnunet_util.h"
+#include "gnunet_util_cron.h"
 
 #ifdef __cplusplus
 extern "C" {
+#if 0 /* keep Emacsens' auto-indent happy */
+}
 #endif
+#endif
 
-/**************************************************************************/
-/** @name UPnP API                                                        */
-/**************************************************************************/
-/address@hidden/
-
-/* typedef struct _GaimUPnPRequestData GaimUPnPRequestData; */
-
-typedef void (*GaimUPnPCallback) (gboolean success, gpointer data);
-
 /**
  * Sends a discovery request to search for a UPnP enabled IGD that
- * contains the WANIPConnection service that will allow us to recieve the
+ * 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.
- *
- * @param cb an optional callback function to be notified when the UPnP
- *           discovery is complete
- * @param cb_data Extra data to be passed to the callback
  */
-void gaim_upnp_discover(GaimUPnPCallback cb, gpointer cb_data);
+int gaim_upnp_discover(struct GE_Context * ectx,
+                      struct GC_Configuration * cfg);
 
-#if 0
 /**
- * Retrieve the current UPnP control info, if there is any available.
- * This will only be filled in if gaim_upnp_discover() had been called,
- * and finished discovering.
- *
- * @return The control URL for the IGD we'll use to use the IGD services
- */
-const GaimUPnPControlInfo* gaim_upnp_get_control_info(void);
-#endif
-
-/**
  * 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
@@ -71,7 +56,7 @@
  *
  * @return The IP address of the network, or NULL if something went wrong
  */
-const gchar* gaim_upnp_get_public_ip(void);
+const gchar * gaim_upnp_get_public_ip(void);
 
 /**
  * Maps Ports in a UPnP enabled IGD that sits on the local network to
@@ -80,30 +65,20 @@
  *
  * @param portmap The port to map to this client
  * @param protocol The protocol to map, either "TCP" or "UDP"
+ * @param do_add TRUE/YES to add, FALSE/NO to remove
  * @param cb an optional callback function to be notified when the mapping
  *           addition is complete
  * @param cb_data Extra data to be passed to the callback
  */
-void gaim_upnp_set_port_mapping(unsigned short portmap, const gchar* protocol,
-               GaimUPnPCallback cb, gpointer cb_data);
+int gaim_upnp_change_port_mapping(struct GE_Context * ectx,
+                                 struct GC_Configuration * cfg,
+                                 int do_add,
+                                 unsigned short portmap,
+                                 const gchar* protocol);
 
-/**
- * Deletes a port mapping in a UPnP enabled IGD that sits on the local network
- * to this gaim 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
- *
- * @param portmap The port to delete the mapping for
- * @param protocol The protocol to map to. Either "TCP" or "UDP"
- * @param cb an optional callback function to be notified when the mapping
- *           removal is complete
- * @param cb_data Extra data to be passed to the callback
- */
-void gaim_upnp_remove_port_mapping(unsigned short portmap,
-               const gchar* protocol, GaimUPnPCallback cb, gpointer cb_data);
-
-/address@hidden/
-
+#if 0 /* keep Emacsens' auto-indent happy */
+{
+#endif
 #ifdef __cplusplus
 }
 #endif

Modified: GNUnet/src/transports/upnp/util.c
===================================================================
--- GNUnet/src/transports/upnp/util.c   2006-12-29 05:17:33 UTC (rev 4095)
+++ GNUnet/src/transports/upnp/util.c   2006-12-29 10:03:33 UTC (rev 4096)
@@ -100,91 +100,7 @@
 }
 
 
-/**************************************************************************
- * URI/URL Functions
- **************************************************************************/
 gboolean
-gaim_url_parse(const char *url, char **ret_host, int *ret_port,
-                          char **ret_path, char **ret_user, char **ret_passwd)
-{
-       char scan_info[255];
-       char port_str[6];
-       int f;
-       const char *at, *slash;
-       const char *turl;
-       char host[256], path[256], user[256], passwd[256];
-       int port = 0;
-       /* hyphen at end includes it in control set */
-       static char addr_ctrl[] = "A-Za-z0-9.-";
-       static char port_ctrl[] = "0-9";
-       static char page_ctrl[] = "A-Za-z0-9.~_/:*!@&%%?=+^-";
-       static char user_ctrl[] = "A-Za-z0-9.~_/*!&%%?=+^-";
-       static char passwd_ctrl[] = "A-Za-z0-9.~_/*!&%%?=+^-";
-
-       g_return_val_if_fail(url != NULL, FALSE);
-
-       if ((turl = strstr(url, "http://";)) != NULL ||
-               (turl = strstr(url, "HTTP://")) != NULL)
-       {
-               turl += 7;
-               url = turl;
-       }
-
-       /* parse out authentication information if supplied */
-       /* Only care about @ char BEFORE the first / */
-       at = strchr(url, '@');
-       slash = strchr(url, '/');
-       if ((at != NULL) &&
-                       (((slash != NULL) && (strlen(at) > strlen(slash))) ||
-                       (slash == NULL))) {
-               g_snprintf(scan_info, sizeof(scan_info),
-                                       "%%255[%s]:%%255[%s]^@", user_ctrl, 
passwd_ctrl);
-               f = sscanf(url, scan_info, user, passwd);
-
-               if (f ==1 ) {
-                       /* No passwd, possibly just username supplied */
-                       g_snprintf(scan_info, sizeof(scan_info),
-                                               "%%255[%s]^@", user_ctrl);
-                       f = sscanf(url, scan_info, user);
-                       *passwd = '\0';
-               }
-
-               url = at+1; /* move pointer after the @ char */
-       } else {
-               *user = '\0';
-               *passwd = '\0';
-       }
-
-       g_snprintf(scan_info, sizeof(scan_info),
-                          "%%255[%s]:%%5[%s]/%%255[%s]", addr_ctrl, port_ctrl, 
page_ctrl);
-
-       f = sscanf(url, scan_info, host, port_str, path);
-
-       if (f == 1)
-       {
-               g_snprintf(scan_info, sizeof(scan_info),
-                                  "%%255[%s]/%%255[%s]",
-                                  addr_ctrl, page_ctrl);
-               f = sscanf(url, scan_info, host, path);
-               g_snprintf(port_str, sizeof(port_str), "80");
-       }
-
-       if (f == 1)
-               *path = '\0';
-
-       sscanf(port_str, "%d", &port);
-
-       if (ret_host != NULL) *ret_host = g_strdup(host);
-       if (ret_port != NULL) *ret_port = port;
-       if (ret_path != NULL) *ret_path = g_strdup(path);
-       if (ret_user != NULL) *ret_user = g_strdup(user);
-       if (ret_passwd != NULL) *ret_passwd = g_strdup(passwd);
-
-       return TRUE;
-}
-
-
-gboolean
 gaim_str_has_prefix(const char *s, const char *p)
 {
 #if GLIB_CHECK_VERSION(2,2,0)
@@ -197,26 +113,4 @@
 #endif
 }
 
-/**
- * Fetches the data from a URL, and passes it to a callback function.
- *
- * @param url        The URL.
- * @param full       TRUE if this is the full URL, or FALSE if it's a
- *                   partial URL.
- * @param user_agent The user agent field to use, or NULL.
- * @param http11     TRUE if HTTP/1.1 should be used to download the file.
- * @param request    A HTTP request to send to the server instead of the
- *                   standard GET
- * @param include_headers
- *                   If TRUE, include the HTTP headers in the response.
- * @param callback   The callback function.
- * @param data       The user data to pass to the callback function.
- */
-GaimUtilFetchUrlData *gaim_util_fetch_url_request(const gchar *url,
-               gboolean full, const gchar *user_agent, gboolean http11,
-               const gchar *request, gboolean include_headers,
-                                                 GaimUtilFetchUrlCallback 
callback, gpointer data) {
-  /* FIXME: implement using libcurl? */
-  return NULL;
-}
 

Modified: GNUnet/src/transports/upnp/util.h
===================================================================
--- GNUnet/src/transports/upnp/util.h   2006-12-29 05:17:33 UTC (rev 4095)
+++ GNUnet/src/transports/upnp/util.h   2006-12-29 10:03:33 UTC (rev 4096)
@@ -36,30 +36,7 @@
 extern "C" {
 #endif
 
-
-typedef struct _GaimUtilFetchUrlData GaimUtilFetchUrlData;
-
-
 /**
- * This is the signature used for functions that act as the callback
- * to gaim_util_fetch_url() or gaim_util_fetch_url_request().
- *
- * @param url_data      The same value that was returned when you called
- *                      gaim_fetch_url() or gaim_fetch_url_request().
- * @param user_data     The user data that your code passed into either
- *                      gaim_util_fetch_url() or gaim_util_fetch_url_request().
- * @param url_text      This will be NULL on error.  Otherwise this
- *                      will contain the contents of the URL.
- * @param len           0 on error, otherwise this is the length of buf.
- * @param error_message If something went wrong then this will contain
- *                      a descriptive error message, and buf will be
- *                      NULL and len will be 0.
- */
-typedef void (*GaimUtilFetchUrlCallback)(GaimUtilFetchUrlData *url_data, 
gpointer user_data, const gchar *url_text, gsize len, const gchar 
*error_message);
-
-
-
-/**
  * Unescapes HTML entities to their literal characters.
  * For example "&amp;" is replaced by '&' and so on.
  * Actually only "&amp;", "&quot;", "&lt;" and "&gt;" are currently
@@ -71,25 +48,7 @@
  */
 char *gaim_unescape_html(const char *html);
 
-
 /**
- * Parses a URL, returning its host, port, file path, username and password.
- *
- * The returned data must be freed.
- *
- * @param url      The URL to parse.
- * @param ret_host The returned host.
- * @param ret_port The returned port.
- * @param ret_path The returned path.
- * @param ret_user The returned username.
- * @param ret_passwd The returned password.
- */
-gboolean gaim_url_parse(const char *url, char **ret_host, int *ret_port,
-                                               char **ret_path, char 
**ret_user, char **ret_passwd);
-
-
-
-/**
  * Compares two strings to see if the first contains the second as
  * a proper prefix.
  *
@@ -100,27 +59,6 @@
  */
 gboolean gaim_str_has_prefix(const char *s, const char *p);
 
-/**
- * Fetches the data from a URL, and passes it to a callback function.
- *
- * @param url        The URL.
- * @param full       TRUE if this is the full URL, or FALSE if it's a
- *                   partial URL.
- * @param user_agent The user agent field to use, or NULL.
- * @param http11     TRUE if HTTP/1.1 should be used to download the file.
- * @param request    A HTTP request to send to the server instead of the
- *                   standard GET
- * @param include_headers
- *                   If TRUE, include the HTTP headers in the response.
- * @param callback   The callback function.
- * @param data       The user data to pass to the callback function.
- */
-GaimUtilFetchUrlData *gaim_util_fetch_url_request(const gchar *url,
-               gboolean full, const gchar *user_agent, gboolean http11,
-               const gchar *request, gboolean include_headers,
-               GaimUtilFetchUrlCallback callback, gpointer data);
-
-
 #ifdef __cplusplus
 }
 #endif

Modified: GNUnet/src/transports/upnp/xmlnode.h
===================================================================
--- GNUnet/src/transports/upnp/xmlnode.h        2006-12-29 05:17:33 UTC (rev 
4095)
+++ GNUnet/src/transports/upnp/xmlnode.h        2006-12-29 10:03:33 UTC (rev 
4096)
@@ -25,14 +25,14 @@
 #ifndef _GAIM_XMLNODE_H_
 #define _GAIM_XMLNODE_H_
 
+#include <libxml/parser.h>
+#include <string.h>
+#include <glib.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-#include <libxml/parser.h>
-#include <string.h>
-#include <glib.h>
-
 /**
  * The valid types for an xmlnode
  */





reply via email to

[Prev in Thread] Current Thread [Next in Thread]