[Top][All Lists]
[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 "&" is replaced by '&' and so on.
* Actually only "&", """, "<" and ">" 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
*/
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r4096 - GNUnet/src/transports/upnp,
grothoff <=