| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  | /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* GIO - GLib Input, Output and Streaming Library
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Copyright (C) 2008 Red Hat, Inc. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 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 | 
					
						
							| 
									
										
										
										
											2017-05-27 18:21:30 +02:00
										 |  |  |  * version 2.1 of the License, or (at your option) any later version. | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |  * | 
					
						
							|  |  |  |  * 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 | 
					
						
							| 
									
										
										
										
											2014-01-23 12:58:29 +01:00
										 |  |  |  * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
 | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "config.h"
 | 
					
						
							|  |  |  | #include <glib.h>
 | 
					
						
							|  |  |  | #include "glibintl.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "gnetworkservice.h"
 | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  | #include "gcancellable.h"
 | 
					
						
							|  |  |  | #include "ginetaddress.h"
 | 
					
						
							|  |  |  | #include "ginetsocketaddress.h"
 | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  | #include "gioerror.h"
 | 
					
						
							|  |  |  | #include "gnetworkaddress.h"
 | 
					
						
							| 
									
										
										
										
											2010-09-10 08:51:21 -04:00
										 |  |  | #include "gnetworkingprivate.h"
 | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  | #include "gresolver.h"
 | 
					
						
							| 
									
										
										
										
											2012-08-02 15:48:22 -04:00
										 |  |  | #include "gtask.h"
 | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  | #include "gsocketaddressenumerator.h"
 | 
					
						
							|  |  |  | #include "gsocketconnectable.h"
 | 
					
						
							|  |  |  | #include "gsrvtarget.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <stdlib.h>
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * SECTION:gnetworkservice | 
					
						
							| 
									
										
										
										
											2009-05-28 00:30:21 -04:00
										 |  |  |  * @short_description: A GSocketConnectable for resolving SRV records | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |  * @include: gio/gio.h | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Like #GNetworkAddress does with hostnames, #GNetworkService | 
					
						
							|  |  |  |  * provides an easy way to resolve a SRV record, and then attempt to | 
					
						
							|  |  |  |  * connect to one of the hosts that implements that service, handling | 
					
						
							|  |  |  |  * service priority/weighting, multiple IP addresses, and multiple | 
					
						
							|  |  |  |  * address families. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * See #GSrvTarget for more information about SRV records, and see | 
					
						
							| 
									
										
										
										
											2018-10-17 13:23:21 -05:00
										 |  |  |  * #GSocketConnectable for an example of using the connectable | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |  * interface. | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * GNetworkService: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * A #GSocketConnectable for resolving a SRV record and connecting to | 
					
						
							|  |  |  |  * that service. | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | struct _GNetworkServicePrivate | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |   gchar *service, *protocol, *domain, *scheme; | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |   GList *targets; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | enum { | 
					
						
							|  |  |  |   PROP_0, | 
					
						
							|  |  |  |   PROP_SERVICE, | 
					
						
							|  |  |  |   PROP_PROTOCOL, | 
					
						
							|  |  |  |   PROP_DOMAIN, | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |   PROP_SCHEME | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void g_network_service_set_property (GObject      *object, | 
					
						
							|  |  |  |                                             guint         prop_id, | 
					
						
							|  |  |  |                                             const GValue *value, | 
					
						
							|  |  |  |                                             GParamSpec   *pspec); | 
					
						
							|  |  |  | static void g_network_service_get_property (GObject      *object, | 
					
						
							|  |  |  |                                             guint         prop_id, | 
					
						
							|  |  |  |                                             GValue       *value, | 
					
						
							|  |  |  |                                             GParamSpec   *pspec); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  | static void                      g_network_service_connectable_iface_init       (GSocketConnectableIface *iface); | 
					
						
							|  |  |  | static GSocketAddressEnumerator *g_network_service_connectable_enumerate        (GSocketConnectable      *connectable); | 
					
						
							|  |  |  | static GSocketAddressEnumerator *g_network_service_connectable_proxy_enumerate  (GSocketConnectable      *connectable); | 
					
						
							| 
									
										
										
										
											2015-10-04 15:24:24 +01:00
										 |  |  | static gchar                    *g_network_service_connectable_to_string        (GSocketConnectable      *connectable); | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | G_DEFINE_TYPE_WITH_CODE (GNetworkService, g_network_service, G_TYPE_OBJECT, | 
					
						
							| 
									
										
										
										
											2013-06-11 00:29:58 +01:00
										 |  |  |                          G_ADD_PRIVATE (GNetworkService) | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |                          G_IMPLEMENT_INTERFACE (G_TYPE_SOCKET_CONNECTABLE, | 
					
						
							|  |  |  |                                                 g_network_service_connectable_iface_init)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | g_network_service_finalize (GObject *object) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GNetworkService *srv = G_NETWORK_SERVICE (object); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   g_free (srv->priv->service); | 
					
						
							|  |  |  |   g_free (srv->priv->protocol); | 
					
						
							|  |  |  |   g_free (srv->priv->domain); | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |   g_free (srv->priv->scheme); | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (srv->priv->targets) | 
					
						
							|  |  |  |     g_resolver_free_targets (srv->priv->targets); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   G_OBJECT_CLASS (g_network_service_parent_class)->finalize (object); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | g_network_service_class_init (GNetworkServiceClass *klass) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GObjectClass *gobject_class = G_OBJECT_CLASS (klass); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   gobject_class->set_property = g_network_service_set_property; | 
					
						
							|  |  |  |   gobject_class->get_property = g_network_service_get_property; | 
					
						
							|  |  |  |   gobject_class->finalize = g_network_service_finalize; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   g_object_class_install_property (gobject_class, PROP_SERVICE, | 
					
						
							|  |  |  |                                    g_param_spec_string ("service", | 
					
						
							|  |  |  |                                                         P_("Service"), | 
					
						
							|  |  |  |                                                         P_("Service name, eg \"ldap\""), | 
					
						
							|  |  |  |                                                         NULL, | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  |                                                         G_PARAM_READWRITE | | 
					
						
							|  |  |  |                                                         G_PARAM_CONSTRUCT_ONLY | | 
					
						
							|  |  |  |                                                         G_PARAM_STATIC_STRINGS)); | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |   g_object_class_install_property (gobject_class, PROP_PROTOCOL, | 
					
						
							|  |  |  |                                    g_param_spec_string ("protocol", | 
					
						
							|  |  |  |                                                         P_("Protocol"), | 
					
						
							|  |  |  |                                                         P_("Network protocol, eg \"tcp\""), | 
					
						
							|  |  |  |                                                         NULL, | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  |                                                         G_PARAM_READWRITE | | 
					
						
							|  |  |  |                                                         G_PARAM_CONSTRUCT_ONLY | | 
					
						
							|  |  |  |                                                         G_PARAM_STATIC_STRINGS)); | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |   g_object_class_install_property (gobject_class, PROP_DOMAIN, | 
					
						
							|  |  |  |                                    g_param_spec_string ("domain", | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  |                                                         P_("Domain"), | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |                                                         P_("Network domain, eg, \"example.com\""), | 
					
						
							|  |  |  |                                                         NULL, | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  |                                                         G_PARAM_READWRITE | | 
					
						
							|  |  |  |                                                         G_PARAM_CONSTRUCT_ONLY | | 
					
						
							|  |  |  |                                                         G_PARAM_STATIC_STRINGS)); | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |   g_object_class_install_property (gobject_class, PROP_DOMAIN, | 
					
						
							|  |  |  |                                    g_param_spec_string ("scheme", | 
					
						
							|  |  |  |                                                         P_("Scheme"), | 
					
						
							|  |  |  |                                                         P_("Network scheme (default is to use service)"), | 
					
						
							|  |  |  |                                                         NULL, | 
					
						
							|  |  |  |                                                         G_PARAM_READWRITE | | 
					
						
							|  |  |  |                                                         G_PARAM_STATIC_STRINGS)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | g_network_service_connectable_iface_init (GSocketConnectableIface *connectable_iface) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   connectable_iface->enumerate = g_network_service_connectable_enumerate; | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |   connectable_iface->proxy_enumerate = g_network_service_connectable_proxy_enumerate; | 
					
						
							| 
									
										
										
										
											2015-10-04 15:24:24 +01:00
										 |  |  |   connectable_iface->to_string = g_network_service_connectable_to_string; | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | g_network_service_init (GNetworkService *srv) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-06-24 15:43:04 +01:00
										 |  |  |   srv->priv = g_network_service_get_instance_private (srv); | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | g_network_service_set_property (GObject      *object, | 
					
						
							|  |  |  |                                 guint         prop_id, | 
					
						
							|  |  |  |                                 const GValue *value, | 
					
						
							|  |  |  |                                 GParamSpec   *pspec) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GNetworkService *srv = G_NETWORK_SERVICE (object); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  |   switch (prop_id) | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |     { | 
					
						
							|  |  |  |     case PROP_SERVICE: | 
					
						
							|  |  |  |       srv->priv->service = g_value_dup_string (value); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case PROP_PROTOCOL: | 
					
						
							|  |  |  |       srv->priv->protocol = g_value_dup_string (value); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case PROP_DOMAIN: | 
					
						
							|  |  |  |       srv->priv->domain = g_value_dup_string (value); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |     case PROP_SCHEME: | 
					
						
							|  |  |  |       g_network_service_set_scheme (srv, g_value_get_string (value)); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |     default: | 
					
						
							|  |  |  |       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | g_network_service_get_property (GObject    *object, | 
					
						
							|  |  |  |                                 guint       prop_id, | 
					
						
							|  |  |  |                                 GValue     *value, | 
					
						
							|  |  |  |                                 GParamSpec *pspec) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GNetworkService *srv = G_NETWORK_SERVICE (object); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   switch (prop_id) | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |     case PROP_SERVICE: | 
					
						
							|  |  |  |       g_value_set_string (value, g_network_service_get_service (srv)); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case PROP_PROTOCOL: | 
					
						
							|  |  |  |       g_value_set_string (value, g_network_service_get_protocol (srv)); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case PROP_DOMAIN: | 
					
						
							|  |  |  |       g_value_set_string (value, g_network_service_get_domain (srv)); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |     case PROP_SCHEME: | 
					
						
							|  |  |  |       g_value_set_string (value, g_network_service_get_scheme (srv)); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |     default: | 
					
						
							|  |  |  |       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * g_network_service_new: | 
					
						
							|  |  |  |  * @service: the service type to look up (eg, "ldap") | 
					
						
							|  |  |  |  * @protocol: the networking protocol to use for @service (eg, "tcp") | 
					
						
							|  |  |  |  * @domain: the DNS domain to look up the service in | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Creates a new #GNetworkService representing the given @service, | 
					
						
							|  |  |  |  * @protocol, and @domain. This will initially be unresolved; use the | 
					
						
							|  |  |  |  * #GSocketConnectable interface to resolve it. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2014-02-19 19:35:23 -05:00
										 |  |  |  * Returns: (transfer full) (type GNetworkService): a new #GNetworkService | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Since: 2.22 | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  | GSocketConnectable * | 
					
						
							|  |  |  | g_network_service_new (const gchar *service, | 
					
						
							|  |  |  |                        const gchar *protocol, | 
					
						
							|  |  |  |                        const gchar *domain) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return g_object_new (G_TYPE_NETWORK_SERVICE, | 
					
						
							|  |  |  |                        "service", service, | 
					
						
							|  |  |  |                        "protocol", protocol, | 
					
						
							|  |  |  |                        "domain", domain, | 
					
						
							|  |  |  |                        NULL); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * g_network_service_get_service: | 
					
						
							|  |  |  |  * @srv: a #GNetworkService | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Gets @srv's service name (eg, "ldap"). | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2014-02-19 19:35:23 -05:00
										 |  |  |  * Returns: @srv's service name | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Since: 2.22 | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  | const gchar * | 
					
						
							|  |  |  | g_network_service_get_service (GNetworkService *srv) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   g_return_val_if_fail (G_IS_NETWORK_SERVICE (srv), NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return srv->priv->service; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * g_network_service_get_protocol: | 
					
						
							|  |  |  |  * @srv: a #GNetworkService | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Gets @srv's protocol name (eg, "tcp"). | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2014-02-19 19:35:23 -05:00
										 |  |  |  * Returns: @srv's protocol name | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Since: 2.22 | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  | const gchar * | 
					
						
							|  |  |  | g_network_service_get_protocol (GNetworkService *srv) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   g_return_val_if_fail (G_IS_NETWORK_SERVICE (srv), NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return srv->priv->protocol; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * g_network_service_get_domain: | 
					
						
							|  |  |  |  * @srv: a #GNetworkService | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Gets the domain that @srv serves. This might be either UTF-8 or | 
					
						
							|  |  |  |  * ASCII-encoded, depending on what @srv was created with. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2014-02-19 19:35:23 -05:00
										 |  |  |  * Returns: @srv's domain name | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Since: 2.22 | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  | const gchar * | 
					
						
							|  |  |  | g_network_service_get_domain (GNetworkService *srv) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   g_return_val_if_fail (G_IS_NETWORK_SERVICE (srv), NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return srv->priv->domain; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * g_network_service_get_scheme: | 
					
						
							|  |  |  |  * @srv: a #GNetworkService | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2020-06-12 14:02:30 +01:00
										 |  |  |  * Gets the URI scheme used to resolve proxies. By default, the service name | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |  * is used as scheme. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2014-02-19 19:35:23 -05:00
										 |  |  |  * Returns: @srv's scheme name | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Since: 2.26 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | const gchar * | 
					
						
							|  |  |  | g_network_service_get_scheme (GNetworkService *srv) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   g_return_val_if_fail (G_IS_NETWORK_SERVICE (srv), NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (srv->priv->scheme) | 
					
						
							|  |  |  |     return srv->priv->scheme; | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     return srv->priv->service; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * g_network_service_set_scheme: | 
					
						
							|  |  |  |  * @srv: a #GNetworkService | 
					
						
							| 
									
										
										
										
											2010-08-21 15:34:40 -04:00
										 |  |  |  * @scheme: a URI scheme | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Set's the URI scheme used to resolve proxies. By default, the service name | 
					
						
							|  |  |  |  * is used as scheme. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Since: 2.26 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | void | 
					
						
							| 
									
										
										
										
											2010-08-21 15:34:40 -04:00
										 |  |  | g_network_service_set_scheme (GNetworkService *srv, | 
					
						
							|  |  |  |                               const gchar     *scheme) | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  | { | 
					
						
							|  |  |  |   g_return_if_fail (G_IS_NETWORK_SERVICE (srv)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-14 15:37:06 +02:00
										 |  |  |   g_free (srv->priv->scheme); | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |   srv->priv->scheme = g_strdup (scheme); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   g_object_notify (G_OBJECT (srv), "scheme"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-15 10:05:03 -04:00
										 |  |  | static GList * | 
					
						
							|  |  |  | g_network_service_fallback_targets (GNetworkService *srv) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GSrvTarget *target; | 
					
						
							|  |  |  |   struct servent *entry; | 
					
						
							|  |  |  |   guint16 port; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   entry = getservbyname (srv->priv->service, "tcp"); | 
					
						
							|  |  |  |   port = entry ? g_ntohs (entry->s_port) : 0; | 
					
						
							|  |  |  | #ifdef HAVE_ENDSERVENT
 | 
					
						
							|  |  |  |   endservent (); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (entry == NULL) | 
					
						
							|  |  |  |       return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   target = g_srv_target_new (srv->priv->domain, port, 0, 0); | 
					
						
							|  |  |  |   return g_list_append (NULL, target); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  | #define G_TYPE_NETWORK_SERVICE_ADDRESS_ENUMERATOR (_g_network_service_address_enumerator_get_type ())
 | 
					
						
							|  |  |  | #define G_NETWORK_SERVICE_ADDRESS_ENUMERATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_NETWORK_SERVICE_ADDRESS_ENUMERATOR, GNetworkServiceAddressEnumerator))
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct { | 
					
						
							|  |  |  |   GSocketAddressEnumerator parent_instance; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   GResolver *resolver; | 
					
						
							|  |  |  |   GNetworkService *srv; | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |   GSocketAddressEnumerator *addr_enum; | 
					
						
							|  |  |  |   GList *t; | 
					
						
							|  |  |  |   gboolean use_proxy; | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |   GError *error; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } GNetworkServiceAddressEnumerator; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct { | 
					
						
							|  |  |  |   GSocketAddressEnumeratorClass parent_class; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } GNetworkServiceAddressEnumeratorClass; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-16 21:24:45 -04:00
										 |  |  | static GType _g_network_service_address_enumerator_get_type (void); | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  | G_DEFINE_TYPE (GNetworkServiceAddressEnumerator, _g_network_service_address_enumerator, G_TYPE_SOCKET_ADDRESS_ENUMERATOR) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static GSocketAddress * | 
					
						
							|  |  |  | g_network_service_address_enumerator_next (GSocketAddressEnumerator  *enumerator, | 
					
						
							|  |  |  |                                            GCancellable              *cancellable, | 
					
						
							|  |  |  |                                            GError                   **error) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GNetworkServiceAddressEnumerator *srv_enum = | 
					
						
							|  |  |  |     G_NETWORK_SERVICE_ADDRESS_ENUMERATOR (enumerator); | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |   GSocketAddress *ret = NULL; | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /* If we haven't yet resolved srv, do that */ | 
					
						
							|  |  |  |   if (!srv_enum->srv->priv->targets) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       GList *targets; | 
					
						
							| 
									
										
										
										
											2010-09-15 10:05:03 -04:00
										 |  |  |       GError *my_error = NULL; | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |       targets = g_resolver_lookup_service (srv_enum->resolver, | 
					
						
							|  |  |  |                                            srv_enum->srv->priv->service, | 
					
						
							|  |  |  |                                            srv_enum->srv->priv->protocol, | 
					
						
							|  |  |  |                                            srv_enum->srv->priv->domain, | 
					
						
							| 
									
										
										
										
											2010-09-15 10:05:03 -04:00
										 |  |  |                                            cancellable, &my_error); | 
					
						
							|  |  |  |       if (!targets && g_error_matches (my_error, G_RESOLVER_ERROR, | 
					
						
							|  |  |  |                                        G_RESOLVER_ERROR_NOT_FOUND)) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           targets = g_network_service_fallback_targets (srv_enum->srv); | 
					
						
							|  |  |  |           if (targets) | 
					
						
							|  |  |  |             g_clear_error (&my_error); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-28 15:17:17 -04:00
										 |  |  |       if (my_error) | 
					
						
							| 
									
										
										
										
											2010-09-15 10:05:03 -04:00
										 |  |  |         { | 
					
						
							|  |  |  |           g_propagate_error (error, my_error); | 
					
						
							|  |  |  |           return NULL; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |       srv_enum->srv->priv->targets = targets; | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |       srv_enum->t = srv_enum->srv->priv->targets; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |   /* Delegate to GNetworkAddress */ | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |   do | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |       if (srv_enum->addr_enum == NULL && srv_enum->t) | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |           GError *error = NULL; | 
					
						
							|  |  |  |           gchar *uri; | 
					
						
							|  |  |  |           gchar *hostname; | 
					
						
							|  |  |  |           GSocketConnectable *addr; | 
					
						
							|  |  |  |           GSrvTarget *target = srv_enum->t->data; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           srv_enum->t = g_list_next (srv_enum->t); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           hostname = g_hostname_to_ascii (g_srv_target_get_hostname (target)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           if (hostname == NULL) | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |             { | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |               if (srv_enum->error == NULL) | 
					
						
							|  |  |  |                 srv_enum->error = | 
					
						
							|  |  |  |                   g_error_new (G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, | 
					
						
							|  |  |  |                                "Received invalid hostname '%s' from GSrvTarget", | 
					
						
							|  |  |  |                                g_srv_target_get_hostname (target)); | 
					
						
							|  |  |  |               continue; | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-06 23:34:27 +04:00
										 |  |  |           uri = g_uri_join (G_URI_FLAGS_NONE, | 
					
						
							|  |  |  |                             g_network_service_get_scheme (srv_enum->srv), | 
					
						
							|  |  |  |                             NULL, | 
					
						
							|  |  |  |                             hostname, | 
					
						
							|  |  |  |                             g_srv_target_get_port (target), | 
					
						
							|  |  |  |                             "", | 
					
						
							|  |  |  |                             NULL, | 
					
						
							|  |  |  |                             NULL); | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |           g_free (hostname); | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |           addr = g_network_address_parse_uri (uri, | 
					
						
							|  |  |  |                                               g_srv_target_get_port (target), | 
					
						
							|  |  |  |                                               &error); | 
					
						
							|  |  |  |           g_free (uri); | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |           if (addr == NULL) | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |             { | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |               if (srv_enum->error == NULL) | 
					
						
							|  |  |  |                 srv_enum->error = error; | 
					
						
							| 
									
										
										
										
											2016-03-15 18:08:29 +00:00
										 |  |  |               else | 
					
						
							|  |  |  |                 g_error_free (error); | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |               continue; | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |           if (srv_enum->use_proxy) | 
					
						
							|  |  |  |             srv_enum->addr_enum = g_socket_connectable_proxy_enumerate (addr); | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |           else | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |             srv_enum->addr_enum = g_socket_connectable_enumerate (addr); | 
					
						
							|  |  |  |           g_object_unref (addr); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (srv_enum->addr_enum) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           GError *error = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           ret = g_socket_address_enumerator_next (srv_enum->addr_enum, | 
					
						
							|  |  |  |                                                   cancellable, | 
					
						
							|  |  |  |                                                   &error); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           if (error) | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |             { | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |               if (srv_enum->error == NULL) | 
					
						
							|  |  |  |                 srv_enum->error = error; | 
					
						
							|  |  |  |               else | 
					
						
							|  |  |  |                 g_error_free (error); | 
					
						
							| 
									
										
										
										
											2010-09-15 10:22:13 -04:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-15 10:22:13 -04:00
										 |  |  |           if (!ret) | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |               g_object_unref (srv_enum->addr_enum); | 
					
						
							|  |  |  |               srv_enum->addr_enum = NULL; | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |   while (srv_enum->addr_enum == NULL && srv_enum->t); | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |   if (ret == NULL && srv_enum->error) | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |       g_propagate_error (error, srv_enum->error); | 
					
						
							|  |  |  |       srv_enum->error = NULL; | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |   return ret; | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-02 15:48:22 -04:00
										 |  |  | static void next_async_resolved_targets   (GObject      *source_object, | 
					
						
							|  |  |  |                                            GAsyncResult *result, | 
					
						
							|  |  |  |                                            gpointer      user_data); | 
					
						
							|  |  |  | static void next_async_have_targets       (GTask        *srv_enum); | 
					
						
							|  |  |  | static void next_async_have_address       (GObject      *source_object, | 
					
						
							|  |  |  |                                            GAsyncResult *result, | 
					
						
							|  |  |  |                                            gpointer      user_data); | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | g_network_service_address_enumerator_next_async (GSocketAddressEnumerator  *enumerator, | 
					
						
							|  |  |  |                                                  GCancellable              *cancellable, | 
					
						
							|  |  |  |                                                  GAsyncReadyCallback        callback, | 
					
						
							|  |  |  |                                                  gpointer                   user_data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GNetworkServiceAddressEnumerator *srv_enum = | 
					
						
							|  |  |  |     G_NETWORK_SERVICE_ADDRESS_ENUMERATOR (enumerator); | 
					
						
							| 
									
										
										
										
											2012-08-02 15:48:22 -04:00
										 |  |  |   GTask *task; | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-02 15:48:22 -04:00
										 |  |  |   task = g_task_new (enumerator, cancellable, callback, user_data); | 
					
						
							| 
									
										
										
										
											2016-06-16 19:39:38 -04:00
										 |  |  |   g_task_set_source_tag (task, g_network_service_address_enumerator_next_async); | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /* If we haven't yet resolved srv, do that */ | 
					
						
							|  |  |  |   if (!srv_enum->srv->priv->targets) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       g_resolver_lookup_service_async (srv_enum->resolver, | 
					
						
							|  |  |  |                                        srv_enum->srv->priv->service, | 
					
						
							|  |  |  |                                        srv_enum->srv->priv->protocol, | 
					
						
							|  |  |  |                                        srv_enum->srv->priv->domain, | 
					
						
							|  |  |  |                                        cancellable, | 
					
						
							|  |  |  |                                        next_async_resolved_targets, | 
					
						
							| 
									
										
										
										
											2012-08-02 15:48:22 -04:00
										 |  |  |                                        task); | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |     } | 
					
						
							|  |  |  |   else | 
					
						
							| 
									
										
										
										
											2012-08-02 15:48:22 -04:00
										 |  |  |     next_async_have_targets (task); | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | next_async_resolved_targets (GObject      *source_object, | 
					
						
							|  |  |  |                              GAsyncResult *result, | 
					
						
							|  |  |  |                              gpointer      user_data) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-08-02 15:48:22 -04:00
										 |  |  |   GTask *task = user_data; | 
					
						
							|  |  |  |   GNetworkServiceAddressEnumerator *srv_enum = g_task_get_source_object (task); | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |   GError *error = NULL; | 
					
						
							| 
									
										
										
										
											2010-09-15 10:05:03 -04:00
										 |  |  |   GList *targets; | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-15 10:05:03 -04:00
										 |  |  |   targets = g_resolver_lookup_service_finish (srv_enum->resolver, | 
					
						
							|  |  |  |                                               result, &error); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!targets && g_error_matches (error, G_RESOLVER_ERROR, | 
					
						
							|  |  |  |                                    G_RESOLVER_ERROR_NOT_FOUND)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       targets = g_network_service_fallback_targets (srv_enum->srv); | 
					
						
							|  |  |  |       if (targets) | 
					
						
							|  |  |  |         g_clear_error (&error); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (error) | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2012-08-02 15:48:22 -04:00
										 |  |  |       g_task_return_error (task, error); | 
					
						
							|  |  |  |       g_object_unref (task); | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |     } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-09-15 10:05:03 -04:00
										 |  |  |       srv_enum->t = srv_enum->srv->priv->targets = targets; | 
					
						
							| 
									
										
										
										
											2012-08-02 15:48:22 -04:00
										 |  |  |       next_async_have_targets (task); | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							| 
									
										
										
										
											2012-08-02 15:48:22 -04:00
										 |  |  | next_async_have_targets (GTask *task) | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-08-02 15:48:22 -04:00
										 |  |  |   GNetworkServiceAddressEnumerator *srv_enum = g_task_get_source_object (task); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |   /* Delegate to GNetworkAddress */ | 
					
						
							|  |  |  |   if (srv_enum->addr_enum == NULL && srv_enum->t) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       GSocketConnectable *addr; | 
					
						
							|  |  |  |       GSrvTarget *target = srv_enum->t->data; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       srv_enum->t = g_list_next (srv_enum->t); | 
					
						
							|  |  |  |       addr = g_network_address_new (g_srv_target_get_hostname (target), | 
					
						
							|  |  |  |                                     (guint16) g_srv_target_get_port (target)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (srv_enum->use_proxy) | 
					
						
							|  |  |  |         srv_enum->addr_enum = g_socket_connectable_proxy_enumerate (addr); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         srv_enum->addr_enum = g_socket_connectable_enumerate (addr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       g_object_unref (addr); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |   if (srv_enum->addr_enum) | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |       g_socket_address_enumerator_next_async (srv_enum->addr_enum, | 
					
						
							| 
									
										
										
										
											2012-08-02 15:48:22 -04:00
										 |  |  |                                               g_task_get_cancellable (task), | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |                                               next_async_have_address, | 
					
						
							| 
									
										
										
										
											2012-08-02 15:48:22 -04:00
										 |  |  |                                               task); | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |     } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |       if (srv_enum->error) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2012-08-02 15:48:22 -04:00
										 |  |  |           g_task_return_error (task, srv_enum->error); | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |           srv_enum->error = NULL; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2012-08-02 15:48:22 -04:00
										 |  |  |       else | 
					
						
							|  |  |  |         g_task_return_pointer (task, NULL, NULL); | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-02 15:48:22 -04:00
										 |  |  |       g_object_unref (task); | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  | next_async_have_address (GObject      *source_object, | 
					
						
							|  |  |  |                          GAsyncResult *result, | 
					
						
							|  |  |  |                          gpointer      user_data) | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-08-02 15:48:22 -04:00
										 |  |  |   GTask *task = user_data; | 
					
						
							|  |  |  |   GNetworkServiceAddressEnumerator *srv_enum = g_task_get_source_object (task); | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |   GSocketAddress *address; | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |   GError *error = NULL; | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |    | 
					
						
							|  |  |  |   address = g_socket_address_enumerator_next_finish (srv_enum->addr_enum, | 
					
						
							|  |  |  |                                                      result, | 
					
						
							|  |  |  |                                                      &error); | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |   if (error) | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |       if (srv_enum->error == NULL) | 
					
						
							|  |  |  |         srv_enum->error = error; | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |       else | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |         g_error_free (error); | 
					
						
							| 
									
										
										
										
											2010-09-15 10:22:13 -04:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-15 10:22:13 -04:00
										 |  |  |   if (!address) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |       g_object_unref (srv_enum->addr_enum); | 
					
						
							|  |  |  |       srv_enum->addr_enum = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-02 15:48:22 -04:00
										 |  |  |       next_async_have_targets (task); | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |   else | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2012-08-02 15:48:22 -04:00
										 |  |  |       g_task_return_pointer (task, address, g_object_unref); | 
					
						
							|  |  |  |       g_object_unref (task); | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static GSocketAddress * | 
					
						
							|  |  |  | g_network_service_address_enumerator_next_finish (GSocketAddressEnumerator  *enumerator, | 
					
						
							|  |  |  |                                                   GAsyncResult              *result, | 
					
						
							|  |  |  |                                                   GError                   **error) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-08-02 15:48:22 -04:00
										 |  |  |   return g_task_propagate_pointer (G_TASK (result), error); | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | _g_network_service_address_enumerator_init (GNetworkServiceAddressEnumerator *enumerator) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  | g_network_service_address_enumerator_finalize (GObject *object) | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |   GNetworkServiceAddressEnumerator *srv_enum = | 
					
						
							|  |  |  |     G_NETWORK_SERVICE_ADDRESS_ENUMERATOR (object); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (srv_enum->srv) | 
					
						
							|  |  |  |     g_object_unref (srv_enum->srv); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (srv_enum->addr_enum) | 
					
						
							|  |  |  |     g_object_unref (srv_enum->addr_enum); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (srv_enum->resolver) | 
					
						
							|  |  |  |     g_object_unref (srv_enum->resolver); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (srv_enum->error) | 
					
						
							|  |  |  |     g_error_free (srv_enum->error); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   G_OBJECT_CLASS (_g_network_service_address_enumerator_parent_class)->finalize (object); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | _g_network_service_address_enumerator_class_init (GNetworkServiceAddressEnumeratorClass *srvenum_class) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GObjectClass *object_class = G_OBJECT_CLASS (srvenum_class); | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |   GSocketAddressEnumeratorClass *enumerator_class = | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |     G_SOCKET_ADDRESS_ENUMERATOR_CLASS (srvenum_class); | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |   enumerator_class->next        = g_network_service_address_enumerator_next; | 
					
						
							|  |  |  |   enumerator_class->next_async  = g_network_service_address_enumerator_next_async; | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |   enumerator_class->next_finish = g_network_service_address_enumerator_next_finish; | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |   object_class->finalize = g_network_service_address_enumerator_finalize; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static GSocketAddressEnumerator * | 
					
						
							|  |  |  | g_network_service_connectable_enumerate (GSocketConnectable *connectable) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GNetworkServiceAddressEnumerator *srv_enum; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   srv_enum = g_object_new (G_TYPE_NETWORK_SERVICE_ADDRESS_ENUMERATOR, NULL); | 
					
						
							| 
									
										
										
										
											2017-11-22 00:00:39 -08:00
										 |  |  |   srv_enum->srv = g_object_ref (G_NETWORK_SERVICE (connectable)); | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  |   srv_enum->resolver = g_resolver_get_default (); | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |   srv_enum->use_proxy = FALSE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return G_SOCKET_ADDRESS_ENUMERATOR (srv_enum); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static GSocketAddressEnumerator * | 
					
						
							|  |  |  | g_network_service_connectable_proxy_enumerate (GSocketConnectable *connectable) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GSocketAddressEnumerator *addr_enum; | 
					
						
							|  |  |  |   GNetworkServiceAddressEnumerator *srv_enum; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   addr_enum = g_network_service_connectable_enumerate (connectable); | 
					
						
							|  |  |  |   srv_enum = G_NETWORK_SERVICE_ADDRESS_ENUMERATOR (addr_enum); | 
					
						
							|  |  |  |   srv_enum->use_proxy = TRUE; | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-10 15:45:32 -04:00
										 |  |  |   return addr_enum; | 
					
						
							| 
									
										
										
										
											2008-12-29 13:38:28 -05:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2015-10-04 15:24:24 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | static gchar * | 
					
						
							|  |  |  | g_network_service_connectable_to_string (GSocketConnectable *connectable) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GNetworkService *service; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   service = G_NETWORK_SERVICE (connectable); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return g_strdup_printf ("(%s, %s, %s, %s)", service->priv->service, | 
					
						
							|  |  |  |                           service->priv->protocol, service->priv->domain, | 
					
						
							|  |  |  |                           service->priv->scheme); | 
					
						
							|  |  |  | } |