[gssdp/wip/master/ipv6: 5/7] wip: ipv6 opts



commit 924d98c374bfd8785ac879aa5a45e2d112fd3811
Author: Jens Georg <mail jensge org>
Date:   Thu Feb 18 10:00:21 2016 +0100

    wip: ipv6 opts

 libgssdp/gssdp-client.c           |  6 ++++++
 libgssdp/gssdp-socket-functions.c | 28 ++++++++++++++++--------
 libgssdp/gssdp-socket-functions.h |  1 +
 libgssdp/gssdp-socket-source.c    | 45 ++++++++++++++++++++++++++++++++++-----
 libgssdp/gssdp-socket-source.h    |  1 +
 5 files changed, 67 insertions(+), 14 deletions(-)
---
diff --git a/libgssdp/gssdp-client.c b/libgssdp/gssdp-client.c
index 8465cb0..9d41615 100644
--- a/libgssdp/gssdp-client.c
+++ b/libgssdp/gssdp-client.c
@@ -196,6 +196,7 @@ gssdp_client_initable_init (GInitable                   *initable,
                                          priv->device.host_addr,
                                          priv->socket_ttl,
                                          priv->device.iface_name,
+                                         priv->device.index,
                                          &internal_error);
         if (priv->request_socket == NULL) {
                 goto errors;
@@ -211,6 +212,7 @@ gssdp_client_initable_init (GInitable                   *initable,
                                          priv->device.host_addr,
                                          priv->socket_ttl,
                                          priv->device.iface_name,
+                                         priv->device.index,
                                          &internal_error);
         if (priv->multicast_socket == NULL) {
             goto errors;
@@ -232,6 +234,7 @@ gssdp_client_initable_init (GInitable                   *initable,
                                          "ttl", priv->socket_ttl,
                                          "port", priv->msearch_port,
                                          "device-name", priv->device.iface_name,
+                                         "index", priv->device.index,
                                          NULL));
 
         if (priv->search_socket != NULL) {
@@ -1326,6 +1329,7 @@ request_socket_source_cb (G_GNUC_UNUSED GIOChannel  *source,
                                         priv->device.host_addr,
                                         priv->socket_ttl,
                                         gssdp_client_get_interface (client),
+                                        priv->device.index,
                                         &error);
         if (request_socket != NULL) {
                 g_clear_object (&priv->request_socket);
@@ -1362,6 +1366,7 @@ multicast_socket_source_cb (G_GNUC_UNUSED GIOChannel  *source,
                                         priv->device.host_addr,
                                         priv->socket_ttl,
                                         gssdp_client_get_interface (client),
+                                        priv->device.index,
                                         &error);
         if (multicast_socket != NULL) {
                 g_clear_object (&priv->multicast_socket);
@@ -1398,6 +1403,7 @@ search_socket_source_cb (G_GNUC_UNUSED GIOChannel  *source,
                                         priv->device.host_addr,
                                         priv->socket_ttl,
                                         gssdp_client_get_interface (client),
+                                        priv->device.index,
                                         &error);
         if (search_socket != NULL) {
                 g_clear_object (&priv->search_socket);
diff --git a/libgssdp/gssdp-socket-functions.c b/libgssdp/gssdp-socket-functions.c
index c142e4b..6311f4c 100644
--- a/libgssdp/gssdp-socket-functions.c
+++ b/libgssdp/gssdp-socket-functions.c
@@ -96,20 +96,30 @@ gssdp_socket_option_set (GSocket    *socket,
 gboolean
 gssdp_socket_mcast_interface_set (GSocket      *socket,
                                   GInetAddress *iface_address,
+                                  gint          index,
                                   GError      **error) {
 
         const guint8 *address;
         gsize native_size;
 
-        address = g_inet_address_to_bytes (iface_address);
-        native_size = g_inet_address_get_native_size (iface_address);
-
-        return gssdp_socket_option_set (socket,
-                                        IPPROTO_IP,
-                                        IP_MULTICAST_IF,
-                                        (char *) address,
-                                        native_size,
-                                        error);
+        if (g_inet_address_get_family (iface_address) == G_SOCKET_FAMILY_IPV6) {
+                return gssdp_socket_option_set (socket,
+                                                IPPROTO_IPV6,
+                                                IPV6_MULTICAST_IF,
+                                                (char *)&index,
+                                                sizeof (index),
+                                                error);
+        } else {
+                address = g_inet_address_to_bytes (iface_address);
+                native_size = g_inet_address_get_native_size (iface_address);
+
+                return gssdp_socket_option_set (socket,
+                                                IPPROTO_IP,
+                                                IP_MULTICAST_IF,
+                                                (char *) address,
+                                                native_size,
+                                                error);
+        }
 }
 
 #define __GSSDP_UNUSED(x) (void)(x)
diff --git a/libgssdp/gssdp-socket-functions.h b/libgssdp/gssdp-socket-functions.h
index aaf2f24..7be7a46 100644
--- a/libgssdp/gssdp-socket-functions.h
+++ b/libgssdp/gssdp-socket-functions.h
@@ -27,6 +27,7 @@
 G_GNUC_INTERNAL gboolean
 gssdp_socket_mcast_interface_set (GSocket       *socket,
                                   GInetAddress  *iface_address,
+                                  gint           index,
                                   GError       **error);
 G_GNUC_INTERNAL gboolean
 gssdp_socket_reuse_address       (GSocket *socket,
diff --git a/libgssdp/gssdp-socket-source.c b/libgssdp/gssdp-socket-source.c
index c449b97..de27394 100644
--- a/libgssdp/gssdp-socket-source.c
+++ b/libgssdp/gssdp-socket-source.c
@@ -51,6 +51,7 @@ struct _GSSDPSocketSourcePrivate {
 
         GInetAddress         *address;
         char                 *device_name;
+        guint                 index;
         guint                 ttl;
         guint                 port;
 };
@@ -74,7 +75,8 @@ enum {
     PROP_ADDRESS,
     PROP_TTL,
     PROP_PORT,
-    PROP_IFA_NAME
+    PROP_IFA_NAME,
+    PROP_IFA_IDX
 };
 
 static void
@@ -137,6 +139,9 @@ gssdp_socket_source_set_property (GObject          *object,
         case PROP_PORT:
                 priv->port = g_value_get_uint (value);
                 break;
+        case PROP_IFA_IDX:
+                priv->index = g_value_get_uint (value);
+                break;
         default:
                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
                 break;
@@ -153,6 +158,7 @@ gssdp_socket_source_new (GSSDPSocketSourceType type,
                          GInetAddress         *address,
                          guint                 ttl,
                          const char           *device_name,
+                         guint                 index,
                          GError              **error)
 {
         return g_initable_new (GSSDP_TYPE_SOCKET_SOURCE,
@@ -166,6 +172,8 @@ gssdp_socket_source_new (GSSDPSocketSourceType type,
                                ttl,
                                "device-name",
                                device_name,
+                               "index",
+                               index,
                                NULL);
 }
 
@@ -181,6 +189,7 @@ gssdp_socket_source_do_init (GInitable                   *initable,
         GError *inner_error = NULL;
         GSocketFamily family;
         gboolean success = FALSE;
+        gboolean link_local = FALSE;
 
         self = GSSDP_SOCKET_SOURCE (initable);
         priv = gssdp_socket_source_get_instance_private (self);
@@ -195,6 +204,7 @@ gssdp_socket_source_do_init (GInitable                   *initable,
                  * 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);
+                            link_local = TRUE;
                 } else {
                             group = g_inet_address_new_from_string (SSDP_V6_SL);
                 }
@@ -243,6 +253,7 @@ gssdp_socket_source_do_init (GInitable                   *initable,
 
                 if (!gssdp_socket_mcast_interface_set (priv->socket,
                                                        priv->address,
+                                                       (guint32) priv->index,
                                                        &inner_error)) {
                         g_propagate_prefixed_error (
                                         error,
@@ -256,8 +267,11 @@ gssdp_socket_source_do_init (GInitable                   *initable,
                 bind_address = g_inet_socket_address_new (iface_address,
                                                           SSDP_PORT);
 #else
-                bind_address = g_inet_socket_address_new (group,
-                                                          SSDP_PORT);
+                bind_address = g_object_new (G_TYPE_INET_SOCKET_ADDRESS,
+                                             "address", group,
+                                             "port", SSDP_PORT,
+                                             "scope-id", priv->index,
+                                             NULL);
 #endif
         } else {
                 guint port = SSDP_PORT;
@@ -267,8 +281,17 @@ gssdp_socket_source_do_init (GInitable                   *initable,
                 if (priv->type == GSSDP_SOCKET_SOURCE_TYPE_SEARCH)
                         port = priv->port;
 
-                bind_address = g_inet_socket_address_new (priv->address,
-                                                          port);
+                if (link_local) {
+                    bind_address = g_object_new (G_TYPE_INET_SOCKET_ADDRESS,
+                                                 "address", priv->address,
+                                                 "port", port,
+                                                 "scope-id", priv->index,
+                                                 NULL);
+                } else {
+                    bind_address = g_inet_socket_address_new (priv->address,
+                                                              port);
+                }
+
         }
 
         /* Normally g_socket_bind does this, but it is disabled on
@@ -491,4 +514,16 @@ gssdp_socket_source_class_init (GSSDPSocketSourceClass *klass)
                          0,
                          G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
                          G_PARAM_STATIC_STRINGS));
+
+        g_object_class_install_property
+                (object_class,
+                 PROP_IFA_IDX,
+                 g_param_spec_uint
+                        ("index",
+                         "Interface index",
+                         "Interface index of the network device",
+                         0, G_MAXUINT16,
+                         0,
+                         G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
+                         G_PARAM_STATIC_STRINGS));
 }
diff --git a/libgssdp/gssdp-socket-source.h b/libgssdp/gssdp-socket-source.h
index 979ffcc..69433e8 100644
--- a/libgssdp/gssdp-socket-source.h
+++ b/libgssdp/gssdp-socket-source.h
@@ -49,6 +49,7 @@ gssdp_socket_source_new        (GSSDPSocketSourceType  type,
                                 GInetAddress          *address,
                                 guint                  ttl,
                                 const char            *device_name,
+                                guint                  index,
                                 GError               **error);
 
 G_GNUC_INTERNAL GSocket*


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