X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gio%2Fgsocketaddress.c;h=676d94a3fe729d4f55859ddd583ff5325dfd019d;hb=7e5e3e142f856ac80e83a9a5110b51aa4b5b0821;hp=f5458d4ec80fde0b810550c0c4f04839008e2216;hpb=9a3d18d2a652f9f1567e09bdb1055e6cb462f710;p=platform%2Fupstream%2Fglib.git diff --git a/gio/gsocketaddress.c b/gio/gsocketaddress.c index f5458d4..676d94a 100644 --- a/gio/gsocketaddress.c +++ b/gio/gsocketaddress.c @@ -13,9 +13,7 @@ * 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, write to the - * Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307, USA. + * Public License along with this library; if not, see . * * Authors: Christian Kellner * Samuel Cormier-Iijima @@ -23,11 +21,14 @@ #include #include +#include #include "gsocketaddress.h" #include "ginetaddress.h" #include "ginetsocketaddress.h" #include "gnetworkingprivate.h" +#include "gproxyaddress.h" +#include "gproxyaddressenumerator.h" #include "gsocketaddressenumerator.h" #include "gsocketconnectable.h" #include "glibintl.h" @@ -37,25 +38,24 @@ #include "gunixsocketaddress.h" #endif -#include "gioalias.h" /** * SECTION:gsocketaddress - * @short_description: Abstract base class representing endpoints for - * socket communication + * @short_description: Abstract base class representing endpoints + * for socket communication + * @include: gio/gio.h * - * #GSocketAddress is the equivalent of struct sockaddr - * in the BSD sockets API. This is an abstract class; use - * #GInetSocketAddress for internet sockets, or #GUnixSocketAddress - * for UNIX domain sockets. - **/ + * #GSocketAddress is the equivalent of struct sockaddr in the BSD + * sockets API. This is an abstract class; use #GInetSocketAddress + * for internet sockets, or #GUnixSocketAddress for UNIX domain sockets. + */ /** * GSocketAddress: * - * A socket endpoint address, corresponding to struct sockaddr + * A socket endpoint address, corresponding to struct sockaddr * or one of its subtypes. - **/ + */ enum { @@ -63,8 +63,9 @@ enum PROP_FAMILY }; -static void g_socket_address_connectable_iface_init (GSocketConnectableIface *iface); -static GSocketAddressEnumerator *g_socket_address_connectable_enumerate (GSocketConnectable *connectable); +static void g_socket_address_connectable_iface_init (GSocketConnectableIface *iface); +static GSocketAddressEnumerator *g_socket_address_connectable_enumerate (GSocketConnectable *connectable); +static GSocketAddressEnumerator *g_socket_address_connectable_proxy_enumerate (GSocketConnectable *connectable); G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GSocketAddress, g_socket_address, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (G_TYPE_SOCKET_CONNECTABLE, @@ -76,7 +77,7 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GSocketAddress, g_socket_address, G_TYPE_OBJEC * * Gets the socket family type of @address. * - * Returns: the socket family type of @address. + * Returns: the socket family type of @address * * Since: 2.22 */ @@ -114,17 +115,19 @@ g_socket_address_class_init (GSocketAddressClass *klass) g_object_class_install_property (gobject_class, PROP_FAMILY, g_param_spec_enum ("family", - _("Address family"), - _("The family of the socket address"), + P_("Address family"), + P_("The family of the socket address"), G_TYPE_SOCKET_FAMILY, G_SOCKET_FAMILY_INVALID, - G_PARAM_READABLE | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NAME)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); } static void g_socket_address_connectable_iface_init (GSocketConnectableIface *connectable_iface) { connectable_iface->enumerate = g_socket_address_connectable_enumerate; + connectable_iface->proxy_enumerate = g_socket_address_connectable_proxy_enumerate; } static void @@ -137,12 +140,12 @@ g_socket_address_init (GSocketAddress *address) * g_socket_address_get_native_size: * @address: a #GSocketAddress * - * Gets the size of @address's native struct sockaddr. + * Gets the size of @address's native struct sockaddr. * You can use this to allocate memory to pass to * g_socket_address_to_native(). * - * Returns: the size of the native struct sockaddr that - * @address represents + * Returns: the size of the native struct sockaddr that + * @address represents * * Since: 2.22 */ @@ -158,39 +161,43 @@ g_socket_address_get_native_size (GSocketAddress *address) * g_socket_address_to_native: * @address: a #GSocketAddress * @dest: a pointer to a memory location that will contain the native - * struct sockaddr. + * struct sockaddr * @destlen: the size of @dest. Must be at least as large as - * g_socket_address_get_native_size(). + * g_socket_address_get_native_size() + * @error: #GError for error reporting, or %NULL to ignore + * + * Converts a #GSocketAddress to a native struct sockaddr, which can + * be passed to low-level functions like connect() or bind(). * - * Converts a #GSocketAddress to a native struct - * sockaddr, which can be passed to low-level functions like - * connect() or bind(). + * If not enough space is available, a %G_IO_ERROR_NO_SPACE error + * is returned. If the address type is not known on the system + * then a %G_IO_ERROR_NOT_SUPPORTED error is returned. * - * Returns: %TRUE if @dest was filled in, %FALSE if @address is invalid - * or @destlen is too small. + * Returns: %TRUE if @dest was filled in, %FALSE on error * * Since: 2.22 */ gboolean -g_socket_address_to_native (GSocketAddress *address, - gpointer dest, - gsize destlen) +g_socket_address_to_native (GSocketAddress *address, + gpointer dest, + gsize destlen, + GError **error) { g_return_val_if_fail (G_IS_SOCKET_ADDRESS (address), FALSE); - return G_SOCKET_ADDRESS_GET_CLASS (address)->to_native (address, dest, destlen); + return G_SOCKET_ADDRESS_GET_CLASS (address)->to_native (address, dest, destlen, error); } /** * g_socket_address_new_from_native: - * @native: a pointer to a struct sockaddr + * @native: a pointer to a struct sockaddr * @len: the size of the memory location pointed to by @native * * Creates a #GSocketAddress subclass corresponding to the native - * struct sockaddr @native. + * struct sockaddr @native. * - * Returns: a new #GSocketAddress if @native could successfully be converted, - * otherwise %NULL. + * Returns: a new #GSocketAddress if @native could successfully + * be converted, otherwise %NULL * * Since: 2.22 */ @@ -211,9 +218,13 @@ g_socket_address_new_from_native (gpointer native, if (family == AF_INET) { struct sockaddr_in *addr = (struct sockaddr_in *) native; - GInetAddress *iaddr = g_inet_address_new_from_bytes ((guint8 *) &(addr->sin_addr), AF_INET); + GInetAddress *iaddr; GSocketAddress *sockaddr; + if (len < sizeof (*addr)) + return NULL; + + iaddr = g_inet_address_new_from_bytes ((guint8 *) &(addr->sin_addr), AF_INET); sockaddr = g_inet_socket_address_new (iaddr, g_ntohs (addr->sin_port)); g_object_unref (iaddr); return sockaddr; @@ -222,10 +233,32 @@ g_socket_address_new_from_native (gpointer native, if (family == AF_INET6) { struct sockaddr_in6 *addr = (struct sockaddr_in6 *) native; - GInetAddress *iaddr = g_inet_address_new_from_bytes ((guint8 *) &(addr->sin6_addr), AF_INET6); + GInetAddress *iaddr; GSocketAddress *sockaddr; - sockaddr = g_inet_socket_address_new (iaddr, g_ntohs (addr->sin6_port)); + if (len < sizeof (*addr)) + return NULL; + + if (IN6_IS_ADDR_V4MAPPED (&(addr->sin6_addr))) + { + struct sockaddr_in sin_addr; + + sin_addr.sin_family = AF_INET; + sin_addr.sin_port = addr->sin6_port; + memcpy (&(sin_addr.sin_addr.s_addr), addr->sin6_addr.s6_addr + 12, 4); + iaddr = g_inet_address_new_from_bytes ((guint8 *) &(sin_addr.sin_addr), AF_INET); + } + else + { + iaddr = g_inet_address_new_from_bytes ((guint8 *) &(addr->sin6_addr), AF_INET6); + } + + sockaddr = g_object_new (G_TYPE_INET_SOCKET_ADDRESS, + "address", iaddr, + "port", g_ntohs (addr->sin6_port), + "flowinfo", addr->sin6_flowinfo, + "scope_id", addr->sin6_scope_id, + NULL); g_object_unref (iaddr); return sockaddr; } @@ -234,8 +267,35 @@ g_socket_address_new_from_native (gpointer native, if (family == AF_UNIX) { struct sockaddr_un *addr = (struct sockaddr_un *) native; - - return g_unix_socket_address_new (addr->sun_path); + gint path_len = len - G_STRUCT_OFFSET (struct sockaddr_un, sun_path); + + if (path_len == 0) + { + return g_unix_socket_address_new_with_type ("", 0, + G_UNIX_SOCKET_ADDRESS_ANONYMOUS); + } + else if (addr->sun_path[0] == 0) + { + if (!g_unix_socket_address_abstract_names_supported ()) + { + return g_unix_socket_address_new_with_type ("", 0, + G_UNIX_SOCKET_ADDRESS_ANONYMOUS); + } + else if (len < sizeof (*addr)) + { + return g_unix_socket_address_new_with_type (addr->sun_path + 1, + path_len - 1, + G_UNIX_SOCKET_ADDRESS_ABSTRACT); + } + else + { + return g_unix_socket_address_new_with_type (addr->sun_path + 1, + path_len - 1, + G_UNIX_SOCKET_ADDRESS_ABSTRACT_PADDED); + } + } + else + return g_unix_socket_address_new (addr->sun_path); } #endif @@ -257,6 +317,7 @@ typedef struct { } GSocketAddressAddressEnumeratorClass; +static GType _g_socket_address_address_enumerator_get_type (void); G_DEFINE_TYPE (GSocketAddressAddressEnumerator, _g_socket_address_address_enumerator, G_TYPE_SOCKET_ADDRESS_ENUMERATOR) static void @@ -317,5 +378,39 @@ g_socket_address_connectable_enumerate (GSocketConnectable *connectable) return (GSocketAddressEnumerator *)sockaddr_enum; } -#define __G_SOCKET_ADDRESS_C__ -#include "gioaliasdef.c" +static GSocketAddressEnumerator * +g_socket_address_connectable_proxy_enumerate (GSocketConnectable *connectable) +{ + GSocketAddressEnumerator *addr_enum = NULL; + + g_assert (connectable != NULL); + + if (G_IS_INET_SOCKET_ADDRESS (connectable) && + !G_IS_PROXY_ADDRESS (connectable)) + { + GInetAddress *addr; + guint port; + gchar *uri; + gchar *ip; + + g_object_get (connectable, "address", &addr, "port", &port, NULL); + + ip = g_inet_address_to_string (addr); + uri = _g_uri_from_authority ("none", ip, port, NULL); + + addr_enum = g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR, + "connectable", connectable, + "uri", uri, + NULL); + + g_object_unref (addr); + g_free (ip); + g_free (uri); + } + else + { + addr_enum = g_socket_address_connectable_enumerate (connectable); + } + + return addr_enum; +}