[gssdp/wip/master/ipv6: 4/7] wip: send v6 discovery



commit c21efed8d64ca5f5eb1aab0515068aeb7b0dc389
Author: Jens Georg <mail jensge org>
Date:   Thu Feb 18 08:07:53 2016 +0100

    wip: send v6 discovery
    
    Signed-off-by: Jens Georg <mail jensge org>

 libgssdp/gssdp-client-private.h   |  3 +++
 libgssdp/gssdp-client.c           | 27 ++++++++++++++++++++++++---
 libgssdp/gssdp-protocol.h         |  8 +++++---
 libgssdp/gssdp-resource-browser.c | 16 +++++++++++++++-
 libgssdp/gssdp-resource-group.c   | 30 +++++++++++++++++++++++++++++-
 libgssdp/gssdp-socket-source.c    | 17 ++++++++++-------
 tests/test-functional.c           |  3 ++-
 tests/test-regression.c           |  2 ++
 8 files changed, 90 insertions(+), 16 deletions(-)
---
diff --git a/libgssdp/gssdp-client-private.h b/libgssdp/gssdp-client-private.h
index 8f998cd..ad668e2 100644
--- a/libgssdp/gssdp-client-private.h
+++ b/libgssdp/gssdp-client-private.h
@@ -39,6 +39,9 @@ _gssdp_client_send_message (GSSDPClient       *client,
                             const char        *message,
                             _GSSDPMessageType  type);
 
+G_GNUC_INTERNAL const char *
+_gssdp_client_get_mcast_group (GSSDPClient    *client);
+
 G_END_DECLS
 
 #endif /* GSSDP_CLIENT_PRIVATE_H */
diff --git a/libgssdp/gssdp-client.c b/libgssdp/gssdp-client.c
index e072db8..8465cb0 100644
--- a/libgssdp/gssdp-client.c
+++ b/libgssdp/gssdp-client.c
@@ -955,8 +955,9 @@ _gssdp_client_send_message (GSSDPClient      *client,
                 return;
 
         /* Broadcast if @dest_ip is NULL */
-        if (dest_ip == NULL)
-                dest_ip = SSDP_ADDR;
+        if (dest_ip == NULL) {
+                dest_ip = _gssdp_client_get_mcast_group (client);
+        }
 
         /* Use default port if no port was explicitly specified */
         if (dest_port == 0)
@@ -992,6 +993,27 @@ _gssdp_client_send_message (GSSDPClient      *client,
         g_object_unref (inet_address);
 }
 
+const char*
+_gssdp_client_get_mcast_group (GSSDPClient *client)
+{
+        GSocketFamily family;
+        GSSDPClientPrivate *priv = gssdp_client_get_instance_private (client);
+
+        family = g_inet_address_get_family (priv->device.host_addr);
+        if (family == G_SOCKET_FAMILY_IPV4)
+                return SSDP_ADDR;
+        else {
+                /* IPv6 */
+                /* According to Annex.A, we need to check the scope of the
+                 * address to use the proper multicast group */
+                if (g_inet_address_get_is_link_local (priv->device.host_addr)) {
+                            return SSDP_V6_LL;
+                } else {
+                            return SSDP_V6_SL;
+                }
+        }
+}
+
 /*
  * Generates the default server ID
  */
@@ -1443,4 +1465,3 @@ init_network_info (GSSDPClient *client, GError **error)
 
         return ret;
 }
-
diff --git a/libgssdp/gssdp-protocol.h b/libgssdp/gssdp-protocol.h
index d13c69c..842091b 100644
--- a/libgssdp/gssdp-protocol.h
+++ b/libgssdp/gssdp-protocol.h
@@ -25,12 +25,14 @@
 G_BEGIN_DECLS
 
 #define SSDP_ADDR "239.255.255.250"
+#define SSDP_V6_LL "FF02::C"
+#define SSDP_V6_SL "FF05::C"
 #define SSDP_PORT 1900
 #define SSDP_PORT_STR "1900"
 
 #define SSDP_DISCOVERY_REQUEST                      \
         "M-SEARCH * HTTP/1.1\r\n"                   \
-        "Host: " SSDP_ADDR ":" SSDP_PORT_STR "\r\n" \
+        "Host: %s:" SSDP_PORT_STR "\r\n" \
         "Man: \"ssdp:discover\"\r\n"                \
         "ST: %s\r\n"                                \
         "MX: %d\r\n"                                \
@@ -50,7 +52,7 @@ G_BEGIN_DECLS
 
 #define SSDP_ALIVE_MESSAGE                          \
         "NOTIFY * HTTP/1.1\r\n"                     \
-        "Host: " SSDP_ADDR ":" SSDP_PORT_STR "\r\n" \
+        "Host: %s:" SSDP_PORT_STR "\r\n" \
         "Cache-Control: max-age=%d\r\n"             \
         "Location: %s\r\n"                          \
         "%s"                                        \
@@ -61,7 +63,7 @@ G_BEGIN_DECLS
 
 #define SSDP_BYEBYE_MESSAGE                         \
         "NOTIFY * HTTP/1.1\r\n"                     \
-        "Host: " SSDP_ADDR ":" SSDP_PORT_STR "\r\n" \
+        "Host: %s:" SSDP_PORT_STR "\r\n" \
         "NTS: ssdp:byebye\r\n"                     \
         "NT: %s\r\n"                                \
         "USN: %s\r\n"
diff --git a/libgssdp/gssdp-resource-browser.c b/libgssdp/gssdp-resource-browser.c
index c5cbe92..467cc0d 100644
--- a/libgssdp/gssdp-resource-browser.c
+++ b/libgssdp/gssdp-resource-browser.c
@@ -1123,10 +1123,23 @@ static void
 send_discovery_request (GSSDPResourceBrowser *resource_browser)
 {
         GSSDPResourceBrowserPrivate *priv;
-        char *message;
+        char *message = NULL;
+        const char *group = NULL;
+        char *dest = NULL;
+
+        priv = gssdp_resource_browser_get_instance_private (resource_browser);
+        group = _gssdp_client_get_mcast_group (priv->client);
+
+        /* FIXME: Check for IPv6 - ugly and remove strcpys */
+        if (strchr (group, ':')) {
+            dest = g_strdup_printf ("[%s]", group);
+        } else {
+            dest = g_strdup (group);
+        }
 
         priv = gssdp_resource_browser_get_instance_private (resource_browser);
         message = g_strdup_printf (SSDP_DISCOVERY_REQUEST,
+                                   dest,
                                    priv->target,
                                    priv->mx,
                                    g_get_prgname () ? g_get_prgname () : "");
@@ -1137,6 +1150,7 @@ send_discovery_request (GSSDPResourceBrowser *resource_browser)
                                     message,
                                     _GSSDP_DISCOVERY_REQUEST);
 
+        g_free (dest);
         g_free (message);
 }
 
diff --git a/libgssdp/gssdp-resource-group.c b/libgssdp/gssdp-resource-group.c
index 1f9e9b0..0301ca8 100644
--- a/libgssdp/gssdp-resource-group.c
+++ b/libgssdp/gssdp-resource-group.c
@@ -1059,6 +1059,8 @@ resource_alive (Resource *resource)
         GSSDPClient *client;
         guint max_age;
         char *al, *message;
+        const char *group;
+        char *dest;
 
         priv = gssdp_resource_group_get_instance_private
                                         (resource->resource_group);
@@ -1073,7 +1075,15 @@ resource_alive (Resource *resource)
 
         al = construct_al (resource);
 
+        /* FIXME: UGLY V6 stuff */
+        group = _gssdp_client_get_mcast_group (client);
+        if (strchr (group, ':') != NULL)
+                dest = g_strdup_printf ("[%s]", group);
+        else
+                dest = g_strdup (group);
+
         message = g_strdup_printf (SSDP_ALIVE_MESSAGE,
+                                   dest,
                                    max_age,
                                    (char *) resource->locations->data,
                                    al ? al : "",
@@ -1083,6 +1093,7 @@ resource_alive (Resource *resource)
 
         queue_message (resource->resource_group, message);
 
+        g_free (dest);
         g_free (al);
 }
 
@@ -1092,14 +1103,31 @@ resource_alive (Resource *resource)
 static void
 resource_byebye (Resource *resource)
 {
-        char *message;
+        char *message = NULL;
+        const char *group = NULL;
+        char *host = NULL;
+        GSSDPResourceGroupPrivate *priv = NULL;
+        GSSDPClient *client = NULL;
+
+        priv = gssdp_resource_group_get_instance_private (resource->resource_group);
+        client = priv->client;
+
+        /* FIXME: UGLY V6 stuff */
+        group = _gssdp_client_get_mcast_group (client);
+        if (strchr (group, ':') != NULL)
+                host = g_strdup_printf ("[%s]", group);
+        else
+                host = g_strdup (group);
 
         /* Queue message */
         message = g_strdup_printf (SSDP_BYEBYE_MESSAGE,
+                                   host,
                                    resource->target,
                                    resource->usn);
 
         queue_message (resource->resource_group, message);
+
+        g_free (host);
 }
 
 /*
diff --git a/libgssdp/gssdp-socket-source.c b/libgssdp/gssdp-socket-source.c
index 571ace6..c449b97 100644
--- a/libgssdp/gssdp-socket-source.c
+++ b/libgssdp/gssdp-socket-source.c
@@ -27,6 +27,7 @@
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif /* HAVE_CONFIG_H */
+#include <gio/gio.h>
 
 #include "gssdp-socket-functions.h"
 #include "gssdp-socket-source.h"
@@ -189,17 +190,19 @@ gssdp_socket_source_do_init (GInitable                   *initable,
         if (family == G_SOCKET_FAMILY_IPV4)
                 group = g_inet_address_new_from_string (SSDP_ADDR);
         else {
-                g_set_error_literal (error,
-                                     GSSDP_ERROR,
-                                     GSSDP_ERROR_FAILED,
-                                     "IPv6 address");
-
-                goto error;
+                /* IPv6 */
+                /* According to Annex.A, we need to check the scope of the
+                 * address to use the proper multicast group */
+                if (g_inet_address_get_is_link_local (priv->address)) {
+                            group = g_inet_address_new_from_string (SSDP_V6_LL);
+                } else {
+                            group = g_inet_address_new_from_string (SSDP_V6_SL);
+                }
         }
 
 
         /* Create socket */
-        priv->socket = g_socket_new (G_SOCKET_FAMILY_IPV4,
+        priv->socket = g_socket_new (family,
                                      G_SOCKET_TYPE_DATAGRAM,
                                      G_SOCKET_PROTOCOL_UDP,
                                      &inner_error);
diff --git a/tests/test-functional.c b/tests/test-functional.c
index 6c779a8..81d6e6d 100644
--- a/tests/test-functional.c
+++ b/tests/test-functional.c
@@ -72,6 +72,7 @@ create_alive_message (const char *nt)
                 usn = g_strconcat (UUID_1, "::", nt, NULL);
 
         msg = g_strdup_printf (SSDP_ALIVE_MESSAGE "\r\n",
+                               SSDP_ADDR,
                                1800,
                                "http://127.0.0.1:1234";,
                                "",
@@ -93,7 +94,7 @@ create_byebye_message (const char *nt)
         else
                 usn = g_strconcat (UUID_1, "::", nt, NULL);
 
-        msg = g_strdup_printf (SSDP_BYEBYE_MESSAGE "\r\n", nt, usn);
+        msg = g_strdup_printf (SSDP_BYEBYE_MESSAGE "\r\n", SSDP_ADDR, nt, usn);
         g_free (usn);
 
         return msg;
diff --git a/tests/test-regression.c b/tests/test-regression.c
index 52b4b7e..79b01f9 100644
--- a/tests/test-regression.c
+++ b/tests/test-regression.c
@@ -72,6 +72,7 @@ create_alive_message (const char *nt, int max_life)
                 usn = g_strconcat (UUID_1, "::", nt, NULL);
 
         msg = g_strdup_printf (SSDP_ALIVE_MESSAGE "\r\n",
+                               SSDP_ADDR,
                                max_life,
                                "http://127.0.0.1:1234";,
                                "",
@@ -269,6 +270,7 @@ create_alive_message_bgo724030 (const char *location)
         char *msg;
 
         msg = g_strdup_printf (SSDP_ALIVE_MESSAGE "\r\n",
+                               SSDP_ADDR,
                                5,
                                location,
                                "",


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