* Code in this file is originally based on the miniupnp library.
* Copyright (c) 2005-2009, Thomas BERNARD. All rights reserved.
*
- * Original licence:
+ * Original license:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
#define DESCRIPTION_BUFSIZE 2048
#define CURL_EASY_SETOPT(c, a, b) do { ret = curl_easy_setopt(c, a, b); if (ret != CURLE_OK) GNUNET_log(GNUNET_ERROR_TYPE_WARNING, _("%s failed at %s:%d: `%s'\n"), "curl_easy_setopt", __FILE__, __LINE__, curl_easy_strerror(ret)); } while (0)
#define PRINT_SOCKET_ERROR(a) GNUNET_log_from(GNUNET_ERROR_TYPE_WARNING, "UPnP", _("%s failed at %s:%d: '%s'\n"), a, __FILE__, __LINE__, strerror (errno));
-
+#define PRINT_SOCKET_ERROR_STR(a, b) GNUNET_log_from(GNUNET_ERROR_TYPE_WARNING, "UPnP", _("%s failed at %s:%d: '%s' on `%s'\n"), a, __FILE__, __LINE__, strerror (errno), b);
/**
* Callback function called when download is finished.
}
static void
-task_download (struct download_cls *cls,
+task_download (void *cls,
const struct GNUNET_SCHEDULER_TaskContext *tc);
/**
rtime,
grs,
gws,
- (GNUNET_SCHEDULER_Task) & task_download, cls);
+ & task_download, cls);
GNUNET_NETWORK_fdset_destroy (gws);
GNUNET_NETWORK_fdset_destroy (grs);
}
* @param tc task context
*/
static void
-task_download (struct download_cls *cls,
+task_download (void *cls,
const struct GNUNET_SCHEDULER_TaskContext *tc)
{
-
+ struct download_cls *dc = cls;
int running;
struct CURLMsg *msg;
CURLMcode mret;
#if DEBUG_UPNP
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "UPnP",
"Shutdown requested while trying to download device description from `%s'\n",
- cls->url);
+ dc->url);
#endif
- cls->caller_cb (NULL, cls->caller_cls);
- download_clean_up (cls);
+ dc->caller_cb (NULL, dc->caller_cls);
+ download_clean_up (dc);
return;
}
- if (GNUNET_TIME_absolute_get_remaining (cls->end_time).rel_value == 0)
+ if (GNUNET_TIME_absolute_get_remaining (dc->end_time).rel_value == 0)
{
GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, "UPnP",
_
("Timeout trying to download UPnP device description from '%s'\n"),
- cls->url);
- cls->caller_cb (NULL, cls->caller_cls);
- download_clean_up (cls);
+ dc->url);
+ dc->caller_cb (NULL, dc->caller_cls);
+ download_clean_up (dc);
return;
}
do
{
running = 0;
- mret = curl_multi_perform (cls->multi, &running);
+ mret = curl_multi_perform (dc->multi, &running);
if (running == 0)
{
do
{
- msg = curl_multi_info_read (cls->multi, &running);
+ msg = curl_multi_info_read (dc->multi, &running);
GNUNET_break (msg != NULL);
if (msg == NULL)
break;
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
_("%s failed for `%s' at %s:%d: `%s'\n"),
"curl_multi_perform",
- cls->url,
+ dc->url,
__FILE__,
__LINE__,
curl_easy_strerror (msg->data.result));
- cls->caller_cb (NULL, cls->caller_cls);
+ dc->caller_cb (NULL, dc->caller_cls);
}
else
{
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "UPnP",
_
("Download of device description `%s' completed.\n"),
- cls->url);
- cls->caller_cb (GNUNET_strdup (cls->download_buffer),
- cls->caller_cls);
+ dc->url);
+ dc->caller_cb (GNUNET_strdup (dc->download_buffer),
+ dc->caller_cls);
}
- download_clean_up (cls);
+ download_clean_up (dc);
return;
}
while ((running > 0));
_("%s failed at %s:%d: `%s'\n"),
"curl_multi_perform", __FILE__, __LINE__,
curl_multi_strerror (mret));
- download_clean_up (cls);
- cls->caller_cb (NULL, cls->caller_cls);
+ download_clean_up (dc);
+ dc->caller_cb (NULL, dc->caller_cls);
}
- download_prepare (cls);
+ download_prepare (dc);
}
*
* @param url URL of the file to download
* @param caller_cb user function to call when done
- * @caller_cls closure to pass to caller_cb
+ * @param caller_cls closure to pass to caller_cb
*/
void
download_device_description (char *url, download_cb caller_cb,
/**
- * Construct control URL for device from its description URL and
- * UPNP_IGD_Data_ information. This involves resolving relative paths
+ * Construct control URL and service type for device from its description URL
+ * and UPNP_IGD_Data_ information. This involves resolving relative paths
* and choosing between Common Interface Config and interface-specific
* paths.
*
* @param desc_url URL to the description file of the device
* @param data IGD information obtained from the description file
- * @returns a URL to control the IGD device, or the empty string
- * in case of failure
+ * @param control_url place to store a URL to control the IGD device (will be
+ * the empty string in case of failure)
+ * @param service_type place to store the service type corresponding to control_url
+ * (will be the empty string in case of failure)
*/
-static char *
-format_control_urls (const char *desc_url, struct UPNP_IGD_Data_ *data)
+static void
+format_control_urls (const char *desc_url, struct UPNP_IGD_Data_ *data, char **control_url, char **service_type)
{
const char *ref_url;
int is_desc_file;
}
if (data->control_url[0] != '\0')
- return get_absolute_url (ref_url, is_desc_file, data->control_url);
+ {
+ *control_url = get_absolute_url (ref_url, is_desc_file, data->control_url);
+ *service_type = GNUNET_strdup (data->service_type);
+ }
else if (data->control_url_CIF[0] != '\0')
- return get_absolute_url (ref_url, is_desc_file, data->control_url_CIF);
+ {
+ *control_url = get_absolute_url (ref_url, is_desc_file, data->control_url_CIF);
+ *service_type = GNUNET_strdup (data->service_type_CIF);
+ }
else
- return GNUNET_strdup ("");
+ {
+ /* If no suitable URL-service type pair was found, set both to empty
+ * to avoid pretending things will work */
+ *control_url = GNUNET_strdup ("");
+ *service_type = GNUNET_strdup ("");
+ }
}
static void get_valid_igd (struct UPNP_discover_cls *cls);
* Then, schedule UPnP command to check whether device is connected.
*
* @param desc UPnP IGD description (in XML)
- * @data closure from UPNP_discover()
+ * @param data closure from UPNP_discover()
*/
static void
get_valid_igd_receive (char *desc, void *data)
memset (igd_data, 0, sizeof (struct UPNP_IGD_Data_));
UPNP_IGD_parse_desc_ (desc, strlen (desc), igd_data);
- cls->current_dev->control_url =
- format_control_urls (cls->current_dev->desc_url, igd_data);
-
- if (igd_data->service_type != '\0')
- cls->current_dev->service_type = GNUNET_strdup (igd_data->service_type);
- else if (igd_data->service_type_CIF != '\0')
- cls->current_dev->service_type =
- GNUNET_strdup (igd_data->service_type_CIF);
- else
- cls->current_dev->service_type = GNUNET_strdup ("");
+ format_control_urls (cls->current_dev->desc_url, igd_data,
+ &cls->current_dev->control_url,
+ &cls->current_dev->service_type);
cls->current_dev->data = igd_data;
"urn:schemas-upnp-org:device:InternetGatewayDevice:1",
"urn:schemas-upnp-org:service:WANIPConnection:1",
"urn:schemas-upnp-org:service:WANPPPConnection:1",
- "upnp:rootdevice",
NULL
};
* and get their descriptions.
*
* @param data closure from UPNP_discover()
- * @buf content of the reply
- * @available number of bytes stored in buf
- * @addr address of the sender
- * @addrlen size of addr
- * @param errCode value of errno
+ * @param tc task context
*/
static void
discover_recv (void *data, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
if (multicastif)
{
+#ifndef MINGW
if_index = if_nametoindex (multicastif);
+#else
+ // FIXME
+ if_index = 0;
+#endif
if (!if_index)
- PRINT_SOCKET_ERROR ("if_nametoindex");
+ PRINT_SOCKET_ERROR_STR ("if_nametoindex", multicastif);
if (GNUNET_NETWORK_socket_setsockopt
(sudp, IPPROTO_IPV6, IPV6_MULTICAST_IF, &if_index,