[glib] GInetSocketAddress: add IPv6 flowinfo and scope_id fields
- From: Dan Winship <danw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] GInetSocketAddress: add IPv6 flowinfo and scope_id fields
- Date: Mon, 16 Jan 2012 18:41:03 +0000 (UTC)
commit bf7408c30bac5b0a20202be5aaa850dd0ca1e671
Author: Dan Winship <danw gnome org>
Date: Thu Dec 29 09:42:25 2011 -0500
GInetSocketAddress: add IPv6 flowinfo and scope_id fields
struct sin6_addr has two additional fields that struct sin_addr
doesn't. Add support for those to GInetSocketAddress, and make sure
they don't get lost when converting between glib and native types.
https://bugzilla.gnome.org/show_bug.cgi?id=635554
docs/reference/gio/gio-sections.txt | 2 +
gio/ginetsocketaddress.c | 109 +++++++++++++++++++++++++++++++++-
gio/ginetsocketaddress.h | 12 ++--
gio/gio.symbols | 2 +
gio/gsocketaddress.c | 7 ++-
gio/tests/socket.c | 40 +++++++++++++
6 files changed, 162 insertions(+), 10 deletions(-)
---
diff --git a/docs/reference/gio/gio-sections.txt b/docs/reference/gio/gio-sections.txt
index 96b8b32..5f50e24 100644
--- a/docs/reference/gio/gio-sections.txt
+++ b/docs/reference/gio/gio-sections.txt
@@ -1594,6 +1594,8 @@ GInetSocketAddress
g_inet_socket_address_new
g_inet_socket_address_get_address
g_inet_socket_address_get_port
+g_inet_socket_address_get_flowinfo
+g_inet_socket_address_get_scope_id
<SUBSECTION Standard>
GInetSocketAddressClass
GInetSocketAddressPrivate
diff --git a/gio/ginetsocketaddress.c b/gio/ginetsocketaddress.c
index 071c49f..490c311 100644
--- a/gio/ginetsocketaddress.c
+++ b/gio/ginetsocketaddress.c
@@ -51,13 +51,17 @@ G_DEFINE_TYPE (GInetSocketAddress, g_inet_socket_address, G_TYPE_SOCKET_ADDRESS)
enum {
PROP_0,
PROP_ADDRESS,
- PROP_PORT
+ PROP_PORT,
+ PROP_FLOWINFO,
+ PROP_SCOPE_ID
};
struct _GInetSocketAddressPrivate
{
GInetAddress *address;
guint16 port;
+ guint32 flowinfo;
+ guint32 scope_id;
};
static void
@@ -98,6 +102,16 @@ g_inet_socket_address_get_property (GObject *object,
g_value_set_uint (value, address->priv->port);
break;
+ case PROP_FLOWINFO:
+ g_return_if_fail (g_inet_address_get_family (address->priv->address) == G_SOCKET_FAMILY_IPV6);
+ g_value_set_uint (value, address->priv->flowinfo);
+ break;
+
+ case PROP_SCOPE_ID:
+ g_return_if_fail (g_inet_address_get_family (address->priv->address) == G_SOCKET_FAMILY_IPV6);
+ g_value_set_uint (value, address->priv->scope_id);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -121,6 +135,17 @@ g_inet_socket_address_set_property (GObject *object,
address->priv->port = (guint16) g_value_get_uint (value);
break;
+ case PROP_FLOWINFO:
+ /* We can't test that address->priv->address is IPv6 here,
+ * since this property might get set before PROP_ADDRESS.
+ */
+ address->priv->flowinfo = g_value_get_uint (value);
+ break;
+
+ case PROP_SCOPE_ID:
+ address->priv->scope_id = g_value_get_uint (value);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -202,6 +227,8 @@ g_inet_socket_address_to_native (GSocketAddress *address,
memset (sock, 0, sizeof (*sock));
sock->sin6_family = AF_INET6;
sock->sin6_port = g_htons (addr->priv->port);
+ sock->sin6_flowinfo = g_htonl (addr->priv->flowinfo);
+ sock->sin6_scope_id = g_htonl (addr->priv->scope_id);
memcpy (&(sock->sin6_addr.s6_addr), g_inet_address_to_bytes (addr->priv->address), sizeof (sock->sin6_addr));
return TRUE;
}
@@ -249,6 +276,42 @@ g_inet_socket_address_class_init (GInetSocketAddressClass *klass)
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
+
+ /**
+ * GInetSocketAddress:flowinfo:
+ *
+ * The <literal>sin6_flowinfo</literal> field, for IPv6 addresses.
+ *
+ * Since: 2.32
+ */
+ g_object_class_install_property (gobject_class, PROP_FLOWINFO,
+ g_param_spec_uint ("flowinfo",
+ P_("Flow info"),
+ P_("IPv6 flow info"),
+ 0,
+ G_MAXUINT32,
+ 0,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * GInetSocketAddress:scope_id:
+ *
+ * The <literal>sin6_scope_id</literal> field, for IPv6 addresses.
+ *
+ * Since: 2.32
+ */
+ g_object_class_install_property (gobject_class, PROP_SCOPE_ID,
+ g_param_spec_uint ("scope-id",
+ P_("Scope ID"),
+ P_("IPv6 scope ID"),
+ 0,
+ G_MAXUINT32,
+ 0,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
}
static void
@@ -257,9 +320,6 @@ g_inet_socket_address_init (GInetSocketAddress *address)
address->priv = G_TYPE_INSTANCE_GET_PRIVATE (address,
G_TYPE_INET_SOCKET_ADDRESS,
GInetSocketAddressPrivate);
-
- address->priv->address = NULL;
- address->priv->port = 0;
}
/**
@@ -319,3 +379,44 @@ g_inet_socket_address_get_port (GInetSocketAddress *address)
return address->priv->port;
}
+
+
+/**
+ * g_inet_socket_address_get_flowinfo:
+ * @address: a %G_SOCKET_FAMILY_IPV6 #GInetSocketAddress
+ *
+ * Gets the <literal>sin6_flowinfo</literal> field from @address,
+ * which must be an IPv6 address.
+ *
+ * Return value: the flowinfo field
+ *
+ * Since: 2.32
+ */
+guint32
+g_inet_socket_address_get_flowinfo (GInetSocketAddress *address)
+{
+ g_return_val_if_fail (G_IS_INET_SOCKET_ADDRESS (address), 0);
+ g_return_val_if_fail (g_inet_address_get_family (address->priv->address) == G_SOCKET_FAMILY_IPV6, 0);
+
+ return address->priv->flowinfo;
+}
+
+/**
+ * g_inet_address_get_scope_id:
+ * @address: a %G_SOCKET_FAMILY_IPV6 #GInetAddress
+ *
+ * Gets the <literal>sin6_scope_id</literal> field from @address,
+ * which must be an IPv6 address.
+ *
+ * Return value: the scope id field
+ *
+ * Since: 2.32
+ */
+guint32
+g_inet_socket_address_get_scope_id (GInetSocketAddress *address)
+{
+ g_return_val_if_fail (G_IS_INET_SOCKET_ADDRESS (address), 0);
+ g_return_val_if_fail (g_inet_address_get_family (address->priv->address) == G_SOCKET_FAMILY_IPV6, 0);
+
+ return address->priv->scope_id;
+}
diff --git a/gio/ginetsocketaddress.h b/gio/ginetsocketaddress.h
index b455ac5..94caec8 100644
--- a/gio/ginetsocketaddress.h
+++ b/gio/ginetsocketaddress.h
@@ -55,14 +55,16 @@ struct _GInetSocketAddressClass
GSocketAddressClass parent_class;
};
-GType g_inet_socket_address_get_type (void) G_GNUC_CONST;
+GType g_inet_socket_address_get_type (void) G_GNUC_CONST;
-GSocketAddress *g_inet_socket_address_new (GInetAddress *address,
- guint16 port);
+GSocketAddress *g_inet_socket_address_new (GInetAddress *address,
+ guint16 port);
-GInetAddress * g_inet_socket_address_get_address (GInetSocketAddress *address);
+GInetAddress * g_inet_socket_address_get_address (GInetSocketAddress *address);
+guint16 g_inet_socket_address_get_port (GInetSocketAddress *address);
-guint16 g_inet_socket_address_get_port (GInetSocketAddress *address);
+guint32 g_inet_socket_address_get_flowinfo (GInetSocketAddress *address);
+guint32 g_inet_socket_address_get_scope_id (GInetSocketAddress *address);
G_END_DECLS
diff --git a/gio/gio.symbols b/gio/gio.symbols
index 94391d5..8e62cf2 100644
--- a/gio/gio.symbols
+++ b/gio/gio.symbols
@@ -842,7 +842,9 @@ g_inet_address_mask_get_type
g_inet_address_mask_matches
g_inet_address_mask_equal
g_inet_socket_address_get_address
+g_inet_socket_address_get_flowinfo
g_inet_socket_address_get_port
+g_inet_socket_address_get_scope_id
g_inet_socket_address_get_type
g_inet_socket_address_new
#ifdef G_OS_UNIX
diff --git a/gio/gsocketaddress.c b/gio/gsocketaddress.c
index 477f720..83414fc 100644
--- a/gio/gsocketaddress.c
+++ b/gio/gsocketaddress.c
@@ -256,7 +256,12 @@ g_socket_address_new_from_native (gpointer native,
iaddr = g_inet_address_new_from_bytes ((guint8 *) &(addr->sin6_addr), AF_INET6);
}
- sockaddr = g_inet_socket_address_new (iaddr, g_ntohs (addr->sin6_port));
+ sockaddr = g_object_new (G_TYPE_INET_SOCKET_ADDRESS,
+ "address", iaddr,
+ "port", g_ntohs (addr->sin6_port),
+ "flowinfo", g_ntohl (addr->sin6_flowinfo),
+ "scope_id", g_ntohl (addr->sin6_scope_id),
+ NULL);
g_object_unref (iaddr);
return sockaddr;
}
diff --git a/gio/tests/socket.c b/gio/tests/socket.c
index d2919b8..bdd445a 100644
--- a/gio/tests/socket.c
+++ b/gio/tests/socket.c
@@ -499,6 +499,45 @@ test_ipv6_v4mapped (void)
}
#endif
+static void
+test_sockaddr (void)
+{
+ struct sockaddr_in6 sin6, gsin6;
+ GSocketAddress *saddr;
+ GInetSocketAddress *isaddr;
+ GInetAddress *iaddr;
+ GError *error = NULL;
+
+ memset (&sin6, 0, sizeof (sin6));
+ sin6.sin6_family = AF_INET6;
+ sin6.sin6_addr = in6addr_loopback;
+ sin6.sin6_port = g_htons (42);
+ sin6.sin6_scope_id = g_htonl (17);
+ sin6.sin6_flowinfo = g_htonl (1729);
+
+ saddr = g_socket_address_new_from_native (&sin6, sizeof (sin6));
+ g_assert (G_IS_INET_SOCKET_ADDRESS (saddr));
+
+ isaddr = G_INET_SOCKET_ADDRESS (saddr);
+ iaddr = g_inet_socket_address_get_address (isaddr);
+ g_assert_cmpint (g_inet_address_get_family (iaddr), ==, G_SOCKET_FAMILY_IPV6);
+ g_assert (g_inet_address_get_is_loopback (iaddr));
+
+ g_assert_cmpint (g_inet_socket_address_get_port (isaddr), ==, 42);
+ g_assert_cmpint (g_inet_socket_address_get_scope_id (isaddr), ==, 17);
+ g_assert_cmpint (g_inet_socket_address_get_flowinfo (isaddr), ==, 1729);
+
+ g_socket_address_to_native (saddr, &gsin6, sizeof (gsin6), &error);
+ g_assert_no_error (error);
+
+ g_assert (memcmp (&sin6.sin6_addr, &gsin6.sin6_addr, sizeof (struct in6_addr)) == 0);
+ g_assert_cmpint (sin6.sin6_port, ==, gsin6.sin6_port);
+ g_assert_cmpint (sin6.sin6_scope_id, ==, gsin6.sin6_scope_id);
+ g_assert_cmpint (sin6.sin6_flowinfo, ==, gsin6.sin6_flowinfo);
+
+ g_object_unref (saddr);
+}
+
#ifdef G_OS_UNIX
static void
test_unix_from_fd (void)
@@ -654,6 +693,7 @@ main (int argc,
#if defined (IPPROTO_IPV6) && defined (IPV6_V6ONLY)
g_test_add_func ("/socket/ipv6_v4mapped", test_ipv6_v4mapped);
#endif
+ g_test_add_func ("/socket/address", test_sockaddr);
#ifdef G_OS_UNIX
g_test_add_func ("/socket/unix-from-fd", test_unix_from_fd);
g_test_add_func ("/socket/unix-connection", test_unix_connection);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]