From f8273f39a1fa5e961c30e96fa2a82d728736be09 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Mon, 1 Jun 2015 10:01:26 +0200 Subject: [PATCH] Add GNativeSocketAddress for handling "other" addresses Instead of just dropping address types that we're not specifically handling we return a GNativeSocketAddress which is just a dummy container for the stuct sockaddr. https://bugzilla.gnome.org/show_bug.cgi?id=750203 --- docs/reference/gio/gio-sections.txt | 20 ++++ gio/Makefile.am | 2 + gio/giotypes.h | 1 + gio/gnativesocketaddress.c | 160 ++++++++++++++++++++++++++++ gio/gnativesocketaddress.h | 65 +++++++++++ gio/gsocketaddress.c | 3 +- 6 files changed, 250 insertions(+), 1 deletion(-) create mode 100644 gio/gnativesocketaddress.c create mode 100644 gio/gnativesocketaddress.h diff --git a/docs/reference/gio/gio-sections.txt b/docs/reference/gio/gio-sections.txt index e0466b8de..4a2c942b7 100644 --- a/docs/reference/gio/gio-sections.txt +++ b/docs/reference/gio/gio-sections.txt @@ -1825,6 +1825,26 @@ G_TYPE_UNIX_SOCKET_ADDRESS_TYPE g_unix_socket_address_get_type +
+gnativesocketaddress +GNativeSocketAddress +GNativeSocketAddress +GNativeSocketAddressType +g_native_socket_address_new + +GNativeSocketAddressClass +GNativeSocketAddressPrivate +G_IS_NATIVE_SOCKET_ADDRESS +G_IS_NATIVE_SOCKET_ADDRESS_CLASS +G_TYPE_NATIVE_SOCKET_ADDRESS +G_NATIVE_SOCKET_ADDRESS +G_NATIVE_SOCKET_ADDRESS_CLASS +G_NATIVE_SOCKET_ADDRESS_GET_CLASS +G_TYPE_NATIVE_SOCKET_ADDRESS_TYPE + +g_native_socket_address_get_type +
+
gresolver GResolver diff --git a/gio/Makefile.am b/gio/Makefile.am index 44ade08f5..757f9241c 100644 --- a/gio/Makefile.am +++ b/gio/Makefile.am @@ -400,6 +400,8 @@ libgio_2_0_la_SOURCES = \ gmountoperation.c \ gnativevolumemonitor.c \ gnativevolumemonitor.h \ + gnativesocketaddress.c \ + gnativesocketaddress.h \ gnetworkaddress.c \ gnetworking.c \ gnetworkingprivate.h \ diff --git a/gio/giotypes.h b/gio/giotypes.h index 53f8cc950..372e67cb3 100644 --- a/gio/giotypes.h +++ b/gio/giotypes.h @@ -103,6 +103,7 @@ typedef struct _GIcon GIcon; /* Dummy typedef */ typedef struct _GInetAddress GInetAddress; typedef struct _GInetAddressMask GInetAddressMask; typedef struct _GInetSocketAddress GInetSocketAddress; +typedef struct _GNativeSocketAddress GNativeSocketAddress; typedef struct _GInputStream GInputStream; typedef struct _GInitable GInitable; typedef struct _GIOModule GIOModule; diff --git a/gio/gnativesocketaddress.c b/gio/gnativesocketaddress.c new file mode 100644 index 000000000..b63001de2 --- /dev/null +++ b/gio/gnativesocketaddress.c @@ -0,0 +1,160 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2008 Christian Kellner, Samuel Cormier-Iijima + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Christian Kellner + * Samuel Cormier-Iijima + */ + +#include +#include +#include + +#include "gnativesocketaddress.h" +#include "gnetworkingprivate.h" +#include "gioerror.h" +#include "glibintl.h" + + +/** + * SECTION:gnativesocketaddress + * @short_description: Native GSocketAddress + * @include: gio/gio.h + * + * An socket address of some unknown native type. + */ + +/** + * GNativeSocketAddress: + * + * An socket address, corresponding to a general struct + * sockadd address of a type not otherwise handled by glib. + */ + +struct _GNativeSocketAddressPrivate +{ + struct sockaddr *sockaddr; + struct sockaddr_storage storage; + gsize sockaddr_len; +}; + +G_DEFINE_TYPE_WITH_PRIVATE (GNativeSocketAddress, g_native_socket_address, G_TYPE_SOCKET_ADDRESS) + +static void +g_native_socket_address_dispose (GObject *object) +{ + GNativeSocketAddress *address = G_NATIVE_SOCKET_ADDRESS (object); + + if (address->priv->sockaddr != (struct sockaddr *)&address->priv->storage) + g_free (address->priv->sockaddr); + + G_OBJECT_CLASS (g_native_socket_address_parent_class)->dispose (object); +} + +static GSocketFamily +g_native_socket_address_get_family (GSocketAddress *address) +{ + GNativeSocketAddress *addr; + + g_return_val_if_fail (G_IS_NATIVE_SOCKET_ADDRESS (address), 0); + + addr = G_NATIVE_SOCKET_ADDRESS (address); + + return addr->priv->sockaddr->sa_family; +} + +static gssize +g_native_socket_address_get_native_size (GSocketAddress *address) +{ + GNativeSocketAddress *addr; + + g_return_val_if_fail (G_IS_NATIVE_SOCKET_ADDRESS (address), 0); + + addr = G_NATIVE_SOCKET_ADDRESS (address); + + return addr->priv->sockaddr_len; +} + +static gboolean +g_native_socket_address_to_native (GSocketAddress *address, + gpointer dest, + gsize destlen, + GError **error) +{ + GNativeSocketAddress *addr; + + g_return_val_if_fail (G_IS_NATIVE_SOCKET_ADDRESS (address), FALSE); + + addr = G_NATIVE_SOCKET_ADDRESS (address); + + if (destlen < addr->priv->sockaddr_len) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NO_SPACE, + _("Not enough space for socket address")); + return FALSE; + } + + memcpy (dest, addr->priv->sockaddr, addr->priv->sockaddr_len); + return TRUE; +} + +static void +g_native_socket_address_class_init (GNativeSocketAddressClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GSocketAddressClass *gsocketaddress_class = G_SOCKET_ADDRESS_CLASS (klass); + + gobject_class->dispose = g_native_socket_address_dispose; + + gsocketaddress_class->get_family = g_native_socket_address_get_family; + gsocketaddress_class->to_native = g_native_socket_address_to_native; + gsocketaddress_class->get_native_size = g_native_socket_address_get_native_size; +} + +static void +g_native_socket_address_init (GNativeSocketAddress *address) +{ + address->priv = g_native_socket_address_get_instance_private (address); +} + +/** + * g_native_socket_address_new: + * @address: a #GNativeAddress + * @port: a port number + * + * Creates a new #GNativeSocketAddress for @address and @port. + * + * Returns: a new #GNativeSocketAddress + * + * Since: 2.46 + */ +GSocketAddress * +g_native_socket_address_new (gpointer native, + gsize len) +{ + GNativeSocketAddress *addr; + + addr = g_object_new (G_TYPE_NATIVE_SOCKET_ADDRESS, NULL); + + if (len <= sizeof(addr->priv->storage)) + addr->priv->sockaddr = (struct sockaddr*)&addr->priv->storage; + else + addr->priv->sockaddr = g_malloc (len); + + memcpy (addr->priv->sockaddr, native, len); + addr->priv->sockaddr_len = len; + return G_SOCKET_ADDRESS (addr); +} diff --git a/gio/gnativesocketaddress.h b/gio/gnativesocketaddress.h new file mode 100644 index 000000000..74d18870e --- /dev/null +++ b/gio/gnativesocketaddress.h @@ -0,0 +1,65 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2008 Christian Kellner, Samuel Cormier-Iijima + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see . + * + * Authors: Christian Kellner + * Samuel Cormier-Iijima + */ + +#ifndef __G_NATIVE_SOCKET_ADDRESS_H__ +#define __G_NATIVE_SOCKET_ADDRESS_H__ + +#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define G_TYPE_NATIVE_SOCKET_ADDRESS (g_native_socket_address_get_type ()) +#define G_NATIVE_SOCKET_ADDRESS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_NATIVE_SOCKET_ADDRESS, GNativeSocketAddress)) +#define G_NATIVE_SOCKET_ADDRESS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_NATIVE_SOCKET_ADDRESS, GNativeSocketAddressClass)) +#define G_IS_NATIVE_SOCKET_ADDRESS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_NATIVE_SOCKET_ADDRESS)) +#define G_IS_NATIVE_SOCKET_ADDRESS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_NATIVE_SOCKET_ADDRESS)) +#define G_NATIVE_SOCKET_ADDRESS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_NATIVE_SOCKET_ADDRESS, GNativeSocketAddressClass)) + +typedef struct _GNativeSocketAddressClass GNativeSocketAddressClass; +typedef struct _GNativeSocketAddressPrivate GNativeSocketAddressPrivate; + +struct _GNativeSocketAddress +{ + GSocketAddress parent_instance; + + /*< private >*/ + GNativeSocketAddressPrivate *priv; +}; + +struct _GNativeSocketAddressClass +{ + GSocketAddressClass parent_class; +}; + +GLIB_AVAILABLE_IN_2_46 +GType g_native_socket_address_get_type (void) G_GNUC_CONST; + +GLIB_AVAILABLE_IN_2_46 +GSocketAddress *g_native_socket_address_new (gpointer native, + gsize len); + +G_END_DECLS + +#endif /* __G_NATIVE_SOCKET_ADDRESS_H__ */ diff --git a/gio/gsocketaddress.c b/gio/gsocketaddress.c index 676d94a3f..d0caf3385 100644 --- a/gio/gsocketaddress.c +++ b/gio/gsocketaddress.c @@ -26,6 +26,7 @@ #include "gsocketaddress.h" #include "ginetaddress.h" #include "ginetsocketaddress.h" +#include "gnativesocketaddress.h" #include "gnetworkingprivate.h" #include "gproxyaddress.h" #include "gproxyaddressenumerator.h" @@ -299,7 +300,7 @@ g_socket_address_new_from_native (gpointer native, } #endif - return NULL; + return g_native_socket_address_new (native, len); }