summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Georg <mail@jensge.org>2016-02-18 15:10:17 +0100
committerJens Georg <mail@jensge.org>2018-10-29 22:58:08 +0100
commit4ff54949e8a279ebbb29c64c9b4397db9af2d6e8 (patch)
treec57c66c74c13d4e9dfa7fed7497b4b5845fe81b9
parent4419e59f26e62640784ca4f47c768197ebf85611 (diff)
downloadgssdp-wip/ipv6.tar.gz
wip: Rewrite link-local locationswip/ipv6
Signed-off-by: Jens Georg <mail@jensge.org>
-rw-r--r--libgssdp/gssdp-client.c36
-rw-r--r--libgssdp/gssdp-client.h10
-rw-r--r--libgssdp/gssdp-resource-browser.c36
3 files changed, 80 insertions, 2 deletions
diff --git a/libgssdp/gssdp-client.c b/libgssdp/gssdp-client.c
index aa54d55..211d934 100644
--- a/libgssdp/gssdp-client.c
+++ b/libgssdp/gssdp-client.c
@@ -1049,6 +1049,42 @@ gssdp_client_clear_headers (GSSDPClient *client)
}
/**
+ * gssdp_client_get_address:
+ * @client: A #GSSDPClient
+ *
+ * Returns: (transfer full): The #GInetAddress this client works on
+ **/
+GInetAddress *
+gssdp_client_get_address (GSSDPClient *client)
+{
+ g_return_val_if_fail (GSSDP_IS_CLIENT (client), NULL);
+
+ return g_object_ref (client->priv->device.host_addr);
+}
+
+/**
+ * gssdp_client_get_index:
+ * @client: A #GSSDPClient
+ *
+ * Returns: The interface index of this client
+ **/
+guint
+gssdp_client_get_index (GSSDPClient *client)
+{
+ g_return_val_if_fail (GSSDP_IS_CLIENT (client), 0);
+
+ return client->priv->device.index;
+}
+
+GSocketFamily
+gssdp_client_get_family (GSSDPClient *client)
+{
+ g_return_val_if_fail (GSSDP_IS_CLIENT (client), G_SOCKET_FAMILY_INVALID);
+
+ return g_inet_address_get_family (client->priv->device.host_addr);
+}
+
+/**
* _gssdp_client_send_message:
* @client: A #GSSDPClient
* @dest_ip: (allow-none): The destination IP address, or %NULL to broadcast
diff --git a/libgssdp/gssdp-client.h b/libgssdp/gssdp-client.h
index 03a1866..46cf4b3 100644
--- a/libgssdp/gssdp-client.h
+++ b/libgssdp/gssdp-client.h
@@ -23,6 +23,7 @@
#define __GSSDP_CLIENT_H__
#include <glib-object.h>
+#include <gio/gio.h>
G_BEGIN_DECLS
@@ -108,6 +109,15 @@ gssdp_client_get_network (GSSDPClient *client);
gboolean
gssdp_client_get_active (GSSDPClient *client);
+GInetAddress *
+gssdp_client_get_address (GSSDPClient *client);
+
+guint
+gssdp_client_get_index (GSSDPClient *client);
+
+GSocketFamily
+gssdp_client_get_family (GSSDPClient *client);
+
void
gssdp_client_append_header (GSSDPClient *client,
const char *name,
diff --git a/libgssdp/gssdp-resource-browser.c b/libgssdp/gssdp-resource-browser.c
index 67e0856..b3ccd76 100644
--- a/libgssdp/gssdp-resource-browser.c
+++ b/libgssdp/gssdp-resource-browser.c
@@ -696,8 +696,40 @@ resource_available (GSSDPResourceBrowser *resource_browser,
destroyLocations = TRUE;
header = soup_message_headers_get_one (headers, "Location");
- if (header)
- locations = g_list_append (locations, g_strdup (header));
+ if (header) {
+ GSocketFamily family;
+ GSSDPClient *client;
+
+ client = resource_browser->priv->client;
+ family = gssdp_client_get_family (client);
+
+ if (family == G_SOCKET_FAMILY_IPV6) {
+ SoupURI *uri = soup_uri_new (header);
+ const char *host = NULL;
+ GInetAddress *addr = NULL;
+
+ host = soup_uri_get_host (uri);
+ addr = g_inet_address_new_from_string (host);
+ if (g_inet_address_get_is_link_local (addr)) {
+ char *new_host;
+ int index = 0;
+
+ index = gssdp_client_get_index (client);
+
+ new_host = g_strdup_printf ("%s%%%d",
+ host,
+ index);
+ soup_uri_set_host (uri, new_host);
+ }
+ g_object_unref (addr);
+ locations = g_list_append (locations,
+ soup_uri_to_string (uri,
+ FALSE));
+ soup_uri_free (uri);
+ } else {
+ locations = g_list_append (locations, g_strdup (header));
+ }
+ }
header = soup_message_headers_get_one (headers, "AL");
if (header) {