Hooked proxy enumeration into GSocketClient
[platform/upstream/glib.git] / gio / gsocketclient.c
1 /*  GIO - GLib Input, Output and Streaming Library
2  *
3  * Copyright © 2008, 2009 codethink
4  * Copyright © 2009 Red Hat, Inc
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General
17  * Public License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
19  * Boston, MA 02111-1307, USA.
20  *
21  * Authors: Ryan Lortie <desrt@desrt.ca>
22  *          Alexander Larsson <alexl@redhat.com>
23  */
24
25 #include "config.h"
26 #include "gsocketclient.h"
27
28 #include <stdlib.h>
29 #include <string.h>
30
31 #include <gio/gioenumtypes.h>
32 #include <gio/gsocketaddressenumerator.h>
33 #include <gio/gsocketconnectable.h>
34 #include <gio/gsocketconnection.h>
35 #include <gio/gproxyaddressenumerator.h>
36 #include <gio/gproxyaddress.h>
37 #include <gio/gproxyconnection.h>
38 #include <gio/gsimpleasyncresult.h>
39 #include <gio/gcancellable.h>
40 #include <gio/gioerror.h>
41 #include <gio/gsocket.h>
42 #include <gio/gnetworkaddress.h>
43 #include <gio/gnetworkservice.h>
44 #include <gio/gproxy.h>
45 #include <gio/gsocketaddress.h>
46 #include <gio/gtcpconnection.h>
47 #include "glibintl.h"
48
49
50 /**
51  * SECTION:gsocketclient
52  * @short_description: Helper for connecting to a network service
53  * @include: gio/gio.h
54  * @see_also: #GSocketConnection, #GSocketListener
55  *
56  * #GSocketClient is a high-level utility class for connecting to a
57  * network host using a connection oriented socket type.
58  *
59  * You create a #GSocketClient object, set any options you want, then
60  * call a sync or async connect operation, which returns a #GSocketConnection
61  * subclass on success.
62  *
63  * The type of the #GSocketConnection object returned depends on the type of
64  * the underlying socket that is in use. For instance, for a TCP/IP connection
65  * it will be a #GTcpConnection.
66  *
67  * Since: 2.22
68  */
69
70
71 G_DEFINE_TYPE (GSocketClient, g_socket_client, G_TYPE_OBJECT);
72
73 enum
74 {
75   PROP_NONE,
76   PROP_FAMILY,
77   PROP_TYPE,
78   PROP_PROTOCOL,
79   PROP_LOCAL_ADDRESS,
80   PROP_TIMEOUT,
81   PROP_ENABLE_PROXY,
82 };
83
84 struct _GSocketClientPrivate
85 {
86   GSocketFamily family;
87   GSocketType type;
88   GSocketProtocol protocol;
89   GSocketAddress *local_address;
90   guint timeout;
91   gboolean enable_proxy;
92 };
93
94 static GSocket *
95 create_socket (GSocketClient  *client,
96                GSocketAddress *dest_address,
97                GError        **error)
98 {
99   GSocketFamily family;
100   GSocket *socket;
101
102   family = client->priv->family;
103   if (family == G_SOCKET_FAMILY_INVALID &&
104       client->priv->local_address != NULL)
105     family = g_socket_address_get_family (client->priv->local_address);
106   if (family == G_SOCKET_FAMILY_INVALID)
107     family = g_socket_address_get_family (dest_address);
108
109   socket = g_socket_new (family,
110                          client->priv->type,
111                          client->priv->protocol,
112                          error);
113   if (socket == NULL)
114     return NULL;
115
116   if (client->priv->local_address)
117     {
118       if (!g_socket_bind (socket,
119                           client->priv->local_address,
120                           FALSE,
121                           error))
122         {
123           g_object_unref (socket);
124           return NULL;
125         }
126     }
127
128   if (client->priv->timeout)
129     g_socket_set_timeout (socket, client->priv->timeout);
130
131   return socket;
132 }
133
134 gboolean
135 can_use_proxy (GSocketClient *client)
136 {
137   GSocketClientPrivate *priv = client->priv;
138
139   return priv->enable_proxy
140           && priv->type == G_SOCKET_TYPE_STREAM;
141 }
142
143 static void
144 g_socket_client_init (GSocketClient *client)
145 {
146   client->priv = G_TYPE_INSTANCE_GET_PRIVATE (client,
147                                               G_TYPE_SOCKET_CLIENT,
148                                               GSocketClientPrivate);
149   client->priv->type = G_SOCKET_TYPE_STREAM;
150 }
151
152 /**
153  * g_socket_client_new:
154  *
155  * Creates a new #GSocketClient with the default options.
156  *
157  * Returns: a #GSocketClient.
158  *     Free the returned object with g_object_unref().
159  *
160  * Since: 2.22
161  */
162 GSocketClient *
163 g_socket_client_new (void)
164 {
165   return g_object_new (G_TYPE_SOCKET_CLIENT, NULL);
166 }
167
168 static void
169 g_socket_client_finalize (GObject *object)
170 {
171   GSocketClient *client = G_SOCKET_CLIENT (object);
172
173   if (client->priv->local_address)
174     g_object_unref (client->priv->local_address);
175
176   if (G_OBJECT_CLASS (g_socket_client_parent_class)->finalize)
177     (*G_OBJECT_CLASS (g_socket_client_parent_class)->finalize) (object);
178 }
179
180 static void
181 g_socket_client_get_property (GObject    *object,
182                               guint       prop_id,
183                               GValue     *value,
184                               GParamSpec *pspec)
185 {
186   GSocketClient *client = G_SOCKET_CLIENT (object);
187
188   switch (prop_id)
189     {
190       case PROP_FAMILY:
191         g_value_set_enum (value, client->priv->family);
192         break;
193
194       case PROP_TYPE:
195         g_value_set_enum (value, client->priv->type);
196         break;
197
198       case PROP_PROTOCOL:
199         g_value_set_enum (value, client->priv->protocol);
200         break;
201
202       case PROP_LOCAL_ADDRESS:
203         g_value_set_object (value, client->priv->local_address);
204         break;
205
206       case PROP_TIMEOUT:
207         g_value_set_uint (value, client->priv->timeout);
208         break;
209
210       case PROP_ENABLE_PROXY:
211         g_value_set_boolean (value, client->priv->enable_proxy);
212         break;
213
214       default:
215         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
216     }
217 }
218
219 static void
220 g_socket_client_set_property (GObject      *object,
221                               guint         prop_id,
222                               const GValue *value,
223                               GParamSpec   *pspec)
224 {
225   GSocketClient *client = G_SOCKET_CLIENT (object);
226
227   switch (prop_id)
228     {
229     case PROP_FAMILY:
230       g_socket_client_set_family (client, g_value_get_enum (value));
231       break;
232
233     case PROP_TYPE:
234       g_socket_client_set_socket_type (client, g_value_get_enum (value));
235       break;
236
237     case PROP_PROTOCOL:
238       g_socket_client_set_protocol (client, g_value_get_enum (value));
239       break;
240
241     case PROP_LOCAL_ADDRESS:
242       g_socket_client_set_local_address (client, g_value_get_object (value));
243       break;
244
245     case PROP_TIMEOUT:
246       g_socket_client_set_timeout (client, g_value_get_uint (value));
247       break;
248
249     case PROP_ENABLE_PROXY:
250       g_socket_client_set_enable_proxy (client, g_value_get_boolean (value));
251       break;
252
253     default:
254       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
255     }
256 }
257
258 /**
259  * g_socket_client_get_family:
260  * @client: a #GSocketClient.
261  *
262  * Gets the socket family of the socket client.
263  *
264  * See g_socket_client_set_family() for details.
265  *
266  * Returns: a #GSocketFamily
267  *
268  * Since: 2.22
269  */
270 GSocketFamily
271 g_socket_client_get_family (GSocketClient *client)
272 {
273   return client->priv->family;
274 }
275
276 /**
277  * g_socket_client_set_family:
278  * @client: a #GSocketClient.
279  * @family: a #GSocketFamily
280  *
281  * Sets the socket family of the socket client.
282  * If this is set to something other than %G_SOCKET_FAMILY_INVALID
283  * then the sockets created by this object will be of the specified
284  * family.
285  *
286  * This might be useful for instance if you want to force the local
287  * connection to be an ipv4 socket, even though the address might
288  * be an ipv6 mapped to ipv4 address.
289  *
290  * Since: 2.22
291  */
292 void
293 g_socket_client_set_family (GSocketClient *client,
294                             GSocketFamily  family)
295 {
296   if (client->priv->family == family)
297     return;
298
299   client->priv->family = family;
300   g_object_notify (G_OBJECT (client), "family");
301 }
302
303 /**
304  * g_socket_client_get_socket_type:
305  * @client: a #GSocketClient.
306  *
307  * Gets the socket type of the socket client.
308  *
309  * See g_socket_client_set_socket_type() for details.
310  *
311  * Returns: a #GSocketFamily
312  *
313  * Since: 2.22
314  */
315 GSocketType
316 g_socket_client_get_socket_type (GSocketClient *client)
317 {
318   return client->priv->type;
319 }
320
321 /**
322  * g_socket_client_set_socket_type:
323  * @client: a #GSocketClient.
324  * @type: a #GSocketType
325  *
326  * Sets the socket type of the socket client.
327  * The sockets created by this object will be of the specified
328  * type.
329  *
330  * It doesn't make sense to specify a type of %G_SOCKET_TYPE_DATAGRAM,
331  * as GSocketClient is used for connection oriented services.
332  *
333  * Since: 2.22
334  */
335 void
336 g_socket_client_set_socket_type (GSocketClient *client,
337                                  GSocketType    type)
338 {
339   if (client->priv->type == type)
340     return;
341
342   client->priv->type = type;
343   g_object_notify (G_OBJECT (client), "type");
344 }
345
346 /**
347  * g_socket_client_get_protocol:
348  * @client: a #GSocketClient
349  *
350  * Gets the protocol name type of the socket client.
351  *
352  * See g_socket_client_set_protocol() for details.
353  *
354  * Returns: a #GSocketProtocol
355  *
356  * Since: 2.22
357  */
358 GSocketProtocol
359 g_socket_client_get_protocol (GSocketClient *client)
360 {
361   return client->priv->protocol;
362 }
363
364 /**
365  * g_socket_client_set_protocol:
366  * @client: a #GSocketClient.
367  * @protocol: a #GSocketProtocol
368  *
369  * Sets the protocol of the socket client.
370  * The sockets created by this object will use of the specified
371  * protocol.
372  *
373  * If @protocol is %0 that means to use the default
374  * protocol for the socket family and type.
375  *
376  * Since: 2.22
377  */
378 void
379 g_socket_client_set_protocol (GSocketClient   *client,
380                               GSocketProtocol  protocol)
381 {
382   if (client->priv->protocol == protocol)
383     return;
384
385   client->priv->protocol = protocol;
386   g_object_notify (G_OBJECT (client), "protocol");
387 }
388
389 /**
390  * g_socket_client_get_local_address:
391  * @client: a #GSocketClient.
392  *
393  * Gets the local address of the socket client.
394  *
395  * See g_socket_client_set_local_address() for details.
396  *
397  * Returns: (transfer none): a #GSocketAddres or %NULL. don't free
398  *
399  * Since: 2.22
400  */
401 GSocketAddress *
402 g_socket_client_get_local_address (GSocketClient *client)
403 {
404   return client->priv->local_address;
405 }
406
407 /**
408  * g_socket_client_set_local_address:
409  * @client: a #GSocketClient.
410  * @address: a #GSocketAddress, or %NULL
411  *
412  * Sets the local address of the socket client.
413  * The sockets created by this object will bound to the
414  * specified address (if not %NULL) before connecting.
415  *
416  * This is useful if you want to ensure the the local
417  * side of the connection is on a specific port, or on
418  * a specific interface.
419  *
420  * Since: 2.22
421  */
422 void
423 g_socket_client_set_local_address (GSocketClient  *client,
424                                    GSocketAddress *address)
425 {
426   if (address)
427     g_object_ref (address);
428
429   if (client->priv->local_address)
430     {
431       g_object_unref (client->priv->local_address);
432     }
433   client->priv->local_address = address;
434   g_object_notify (G_OBJECT (client), "local-address");
435 }
436
437 /**
438  * g_socket_client_get_timeout:
439  * @client: a #GSocketClient
440  *
441  * Gets the I/O timeout time for sockets created by @client.
442  *
443  * See g_socket_client_set_timeout() for details.
444  *
445  * Returns: the timeout in seconds
446  *
447  * Since: 2.26
448  */
449 guint
450 g_socket_client_get_timeout (GSocketClient *client)
451 {
452   return client->priv->timeout;
453 }
454
455
456 /**
457  * g_socket_client_set_timeout:
458  * @client: a #GSocketClient.
459  * @timeout: the timeout
460  *
461  * Sets the I/O timeout for sockets created by @client. @timeout is a
462  * time in seconds, or 0 for no timeout (the default).
463  *
464  * The timeout value affects the initial connection attempt as well,
465  * so setting this may cause calls to g_socket_client_connect(), etc,
466  * to fail with %G_IO_ERROR_TIMED_OUT.
467  *
468  * Since: 2.26
469  */
470 void
471 g_socket_client_set_timeout (GSocketClient *client,
472                              guint          timeout)
473 {
474   if (client->priv->timeout == timeout)
475     return;
476
477   client->priv->timeout = timeout;
478   g_object_notify (G_OBJECT (client), "timeout");
479 }
480
481 /**
482  * g_socket_client_get_enable_proxy:
483  * @client: a #GSocketClient.
484  *
485  * Gets the proxy enable state; see g_socket_client_set_enable_proxy()
486  *
487  * Returns: whether proxying is enabled
488  *
489  * Since: 2.26
490  */
491 gboolean
492 g_socket_client_get_enable_proxy (GSocketClient *client)
493 {
494   return client->priv->enable_proxy;
495 }
496
497 /**
498  * g_socket_client_set_enable_proxy:
499  * @client: a #GSocketClient.
500  * @enable: whether to enable proxies
501  *
502  * Sets whether or not @client attempts to make connections via a
503  * proxy server. When enabled (the default), #GSocketClient will use a
504  * #GProxyResolver to determine if a proxy protocol such as SOCKS is
505  * needed, and automatically do the necessary proxy negotiation.
506  *
507  * Since: 2.26
508  */
509 void
510 g_socket_client_set_enable_proxy (GSocketClient *client,
511                                   gboolean       enable)
512 {
513   enable = !!enable;
514   if (client->priv->enable_proxy == enable)
515     return;
516
517   client->priv->enable_proxy = enable;
518   g_object_notify (G_OBJECT (client), "enable-proxy");
519 }
520
521 static void
522 g_socket_client_class_init (GSocketClientClass *class)
523 {
524   GObjectClass *gobject_class = G_OBJECT_CLASS (class);
525
526   g_type_class_add_private (class, sizeof (GSocketClientPrivate));
527
528   gobject_class->finalize = g_socket_client_finalize;
529   gobject_class->set_property = g_socket_client_set_property;
530   gobject_class->get_property = g_socket_client_get_property;
531
532   g_object_class_install_property (gobject_class, PROP_FAMILY,
533                                    g_param_spec_enum ("family",
534                                                       P_("Socket family"),
535                                                       P_("The sockets address family to use for socket construction"),
536                                                       G_TYPE_SOCKET_FAMILY,
537                                                       G_SOCKET_FAMILY_INVALID,
538                                                       G_PARAM_CONSTRUCT |
539                                                       G_PARAM_READWRITE |
540                                                       G_PARAM_STATIC_STRINGS));
541
542   g_object_class_install_property (gobject_class, PROP_TYPE,
543                                    g_param_spec_enum ("type",
544                                                       P_("Socket type"),
545                                                       P_("The sockets type to use for socket construction"),
546                                                       G_TYPE_SOCKET_TYPE,
547                                                       G_SOCKET_TYPE_STREAM,
548                                                       G_PARAM_CONSTRUCT |
549                                                       G_PARAM_READWRITE |
550                                                       G_PARAM_STATIC_STRINGS));
551
552   g_object_class_install_property (gobject_class, PROP_PROTOCOL,
553                                    g_param_spec_enum ("protocol",
554                                                       P_("Socket protocol"),
555                                                       P_("The protocol to use for socket construction, or 0 for default"),
556                                                       G_TYPE_SOCKET_PROTOCOL,
557                                                       G_SOCKET_PROTOCOL_DEFAULT,
558                                                       G_PARAM_CONSTRUCT |
559                                                       G_PARAM_READWRITE |
560                                                       G_PARAM_STATIC_STRINGS));
561
562   g_object_class_install_property (gobject_class, PROP_LOCAL_ADDRESS,
563                                    g_param_spec_object ("local-address",
564                                                         P_("Local address"),
565                                                         P_("The local address constructed sockets will be bound to"),
566                                                         G_TYPE_SOCKET_ADDRESS,
567                                                         G_PARAM_CONSTRUCT |
568                                                         G_PARAM_READWRITE |
569                                                         G_PARAM_STATIC_STRINGS));
570
571   g_object_class_install_property (gobject_class, PROP_TIMEOUT,
572                                    g_param_spec_uint ("timeout",
573                                                       P_("Socket timeout"),
574                                                       P_("The I/O timeout for sockets, or 0 for none"),
575                                                       0, G_MAXUINT, 0,
576                                                       G_PARAM_CONSTRUCT |
577                                                       G_PARAM_READWRITE |
578                                                       G_PARAM_STATIC_STRINGS));
579
580    g_object_class_install_property (gobject_class, PROP_ENABLE_PROXY,
581                                     g_param_spec_boolean ("enable-proxy",
582                                                           P_("Enable proxy"),
583                                                           P_("Enable proxy support"),
584                                                           TRUE,
585                                                           G_PARAM_CONSTRUCT |
586                                                           G_PARAM_READWRITE |
587                                                           G_PARAM_STATIC_STRINGS));
588
589 }
590
591 /**
592  * g_socket_client_connect:
593  * @client: a #GSocketClient.
594  * @connectable: a #GSocketConnectable specifying the remote address.
595  * @cancellable: optional #GCancellable object, %NULL to ignore.
596  * @error: #GError for error reporting, or %NULL to ignore.
597  *
598  * Tries to resolve the @connectable and make a network connection to it..
599  *
600  * Upon a successful connection, a new #GSocketConnection is constructed
601  * and returned.  The caller owns this new object and must drop their
602  * reference to it when finished with it.
603  *
604  * The type of the #GSocketConnection object returned depends on the type of
605  * the underlying socket that is used. For instance, for a TCP/IP connection
606  * it will be a #GTcpConnection.
607  *
608  * The socket created will be the same family as the the address that the
609  * @connectable resolves to, unless family is set with g_socket_client_set_family()
610  * or indirectly via g_socket_client_set_local_address(). The socket type
611  * defaults to %G_SOCKET_TYPE_STREAM but can be set with
612  * g_socket_client_set_socket_type().
613  *
614  * If a local address is specified with g_socket_client_set_local_address() the
615  * socket will be bound to this address before connecting.
616  *
617  * Returns: a #GSocketConnection on success, %NULL on error.
618  *
619  * Since: 2.22
620  */
621 GSocketConnection *
622 g_socket_client_connect (GSocketClient       *client,
623                          GSocketConnectable  *connectable,
624                          GCancellable        *cancellable,
625                          GError             **error)
626 {
627   GSocketConnection *connection = NULL;
628   GSocketAddressEnumerator *enumerator = NULL;
629   GError *last_error, *tmp_error;
630
631   last_error = NULL;
632
633   if (can_use_proxy (client))
634     enumerator = g_socket_connectable_proxy_enumerate (connectable);
635   else
636     enumerator = g_socket_connectable_enumerate (connectable);
637
638   while (connection == NULL)
639     {
640       GSocketAddress *address = NULL;
641       GSocket *socket;
642
643       if (g_cancellable_is_cancelled (cancellable))
644         {
645           g_clear_error (error);
646           g_cancellable_set_error_if_cancelled (cancellable, error);
647           break;
648         }
649
650       tmp_error = NULL;
651       address = g_socket_address_enumerator_next (enumerator, cancellable,
652                                                   &tmp_error);
653
654       if (address == NULL)
655         {
656           if (tmp_error)
657             {
658               g_clear_error (&last_error);
659               g_propagate_error (error, tmp_error);
660             }
661           else if (last_error)
662             {
663               g_propagate_error (error, last_error);
664             }
665           else
666             g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
667                                  _("Unknown error on connect"));
668           break;
669         }
670
671       /* clear error from previous attempt */
672       g_clear_error (&last_error);
673
674       socket = create_socket (client, address, &last_error);
675       if (socket != NULL)
676         {
677           if (g_socket_connect (socket, address, cancellable, &last_error))
678             connection = g_socket_connection_factory_create_connection (socket);
679
680           g_object_unref (socket);
681         }
682
683       if (connection &&
684           G_IS_PROXY_ADDRESS (address) &&
685           client->priv->enable_proxy)
686         {
687           GProxyAddress *proxy_addr = G_PROXY_ADDRESS (address);
688           const gchar *protocol;
689           GProxy *proxy;
690
691           protocol = g_proxy_address_get_protocol (proxy_addr);
692           proxy = g_proxy_get_default_for_protocol (protocol);
693
694           /* The connection should not be anything else then TCP Connection,
695            * but let's put a safety guard in case
696            */
697           if (!G_IS_TCP_CONNECTION (connection))
698             {
699               g_critical ("Trying to proxy over non-TCP connection, this is "
700                           "most likely a bug in GLib IO library.");
701
702               g_set_error_literal (&last_error,
703                   G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
704                   _("Trying to proxy over non-TCP connection is not supported."));
705
706               g_object_unref (connection);
707               connection = NULL;
708             }
709           else if (proxy)
710             {
711               GIOStream *io_stream;
712               GTcpConnection *old_connection = G_TCP_CONNECTION (connection);
713
714               io_stream = g_proxy_connect (proxy,
715                                            G_IO_STREAM (old_connection),
716                                            proxy_addr,
717                                            cancellable,
718                                            &last_error);
719
720               if (io_stream)
721                 {
722                   if (G_IS_SOCKET_CONNECTION (io_stream))
723                     connection = G_SOCKET_CONNECTION (g_object_ref (io_stream));
724                   else
725                     connection = _g_proxy_connection_new (old_connection,
726                                                           io_stream);
727
728                   g_object_unref (io_stream);
729                 }
730               else
731                 {
732                   connection = NULL;
733                 }
734
735               g_object_unref (old_connection);
736               g_object_unref (proxy);
737             }
738           else
739             {
740               g_set_error (&last_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
741                            _("Proxy protocol '%s' is not supported."),
742                            protocol);
743               g_object_unref (connection);
744               connection = NULL;
745             }
746         }
747
748       g_object_unref (address);
749     }
750   g_object_unref (enumerator);
751
752   return connection;
753 }
754
755 /**
756  * g_socket_client_connect_to_host:
757  * @client: a #SocketClient
758  * @host_and_port: the name and optionally port of the host to connect to
759  * @default_port: the default port to connect to
760  * @cancellable: a #GCancellable, or %NULL
761  * @error: a pointer to a #GError, or %NULL
762  *
763  * This is a helper function for g_socket_client_connect().
764  *
765  * Attempts to create a TCP connection to the named host.
766  *
767  * @host_and_port may be in any of a number of recognised formats: an IPv6
768  * address, an IPv4 address, or a domain name (in which case a DNS
769  * lookup is performed).  Quoting with [] is supported for all address
770  * types.  A port override may be specified in the usual way with a
771  * colon.  Ports may be given as decimal numbers or symbolic names (in
772  * which case an /etc/services lookup is performed).
773  *
774  * If no port override is given in @host_and_port then @default_port will be
775  * used as the port number to connect to.
776  *
777  * In general, @host_and_port is expected to be provided by the user (allowing
778  * them to give the hostname, and a port overide if necessary) and
779  * @default_port is expected to be provided by the application.
780  *
781  * In the case that an IP address is given, a single connection
782  * attempt is made.  In the case that a name is given, multiple
783  * connection attempts may be made, in turn and according to the
784  * number of address records in DNS, until a connection succeeds.
785  *
786  * Upon a successful connection, a new #GSocketConnection is constructed
787  * and returned.  The caller owns this new object and must drop their
788  * reference to it when finished with it.
789  *
790  * In the event of any failure (DNS error, service not found, no hosts
791  * connectable) %NULL is returned and @error (if non-%NULL) is set
792  * accordingly.
793  *
794  Returns: a #GSocketConnection on success, %NULL on error.
795  *
796  * Since: 2.22
797  */
798 GSocketConnection *
799 g_socket_client_connect_to_host (GSocketClient  *client,
800                                  const gchar    *host_and_port,
801                                  guint16         default_port,
802                                  GCancellable   *cancellable,
803                                  GError        **error)
804 {
805   GSocketConnectable *connectable;
806   GSocketConnection *connection;
807
808   connectable = g_network_address_parse (host_and_port, default_port, error);
809   if (connectable == NULL)
810     return NULL;
811
812   connection = g_socket_client_connect (client, connectable,
813                                         cancellable, error);
814   g_object_unref (connectable);
815
816   return connection;
817 }
818
819 /**
820  * g_socket_client_connect_to_service:
821  * @client: a #GSocketConnection
822  * @domain: a domain name
823  * @service: the name of the service to connect to
824  * @cancellable: a #GCancellable, or %NULL
825  * @error: a pointer to a #GError, or %NULL
826  * @returns: a #GSocketConnection if successful, or %NULL on error
827  *
828  * Attempts to create a TCP connection to a service.
829  *
830  * This call looks up the SRV record for @service at @domain for the
831  * "tcp" protocol.  It then attempts to connect, in turn, to each of
832  * the hosts providing the service until either a connection succeeds
833  * or there are no hosts remaining.
834  *
835  * Upon a successful connection, a new #GSocketConnection is constructed
836  * and returned.  The caller owns this new object and must drop their
837  * reference to it when finished with it.
838  *
839  * In the event of any failure (DNS error, service not found, no hosts
840  * connectable) %NULL is returned and @error (if non-%NULL) is set
841  * accordingly.
842  */
843 GSocketConnection *
844 g_socket_client_connect_to_service (GSocketClient  *client,
845                                     const gchar    *domain,
846                                     const gchar    *service,
847                                     GCancellable   *cancellable,
848                                     GError        **error)
849 {
850   GSocketConnectable *connectable;
851   GSocketConnection *connection;
852
853   connectable = g_network_service_new (service, "tcp", domain);
854   connection = g_socket_client_connect (client, connectable,
855                                         cancellable, error);
856   g_object_unref (connectable);
857
858   return connection;
859 }
860
861 typedef struct
862 {
863   GSimpleAsyncResult *result;
864   GCancellable *cancellable;
865   GSocketClient *client;
866
867   GSocketAddressEnumerator *enumerator;
868   GProxyAddress *proxy_addr;
869   GSocket *current_socket;
870   GSocketConnection *connection;
871
872   GError *last_error;
873 } GSocketClientAsyncConnectData;
874
875 static void
876 g_socket_client_async_connect_complete (GSocketClientAsyncConnectData *data)
877 {
878   if (data->last_error)
879     {
880       g_simple_async_result_set_from_error (data->result, data->last_error);
881       g_error_free (data->last_error);
882     }
883   else
884     {
885       g_assert (data->connection);
886
887       g_simple_async_result_set_op_res_gpointer (data->result,
888                                                  data->connection,
889                                                  g_object_unref);
890     }
891
892   g_simple_async_result_complete (data->result);
893   g_object_unref (data->result);
894   g_object_unref (data->enumerator);
895   if (data->cancellable)
896     g_object_unref (data->cancellable);
897   if (data->current_socket)
898     g_object_unref (data->current_socket);
899   if (data->proxy_addr)
900     g_object_unref (data->proxy_addr);
901   g_slice_free (GSocketClientAsyncConnectData, data);
902 }
903
904
905 static void
906 g_socket_client_enumerator_callback (GObject      *object,
907                                      GAsyncResult *result,
908                                      gpointer      user_data);
909
910 static void
911 set_last_error (GSocketClientAsyncConnectData *data,
912                 GError *error)
913 {
914   g_clear_error (&data->last_error);
915   data->last_error = error;
916 }
917
918 static void
919 enumerator_next_async (GSocketClientAsyncConnectData *data)
920 {
921   g_socket_address_enumerator_next_async (data->enumerator,
922                                           data->cancellable,
923                                           g_socket_client_enumerator_callback,
924                                           data);
925 }
926
927 static void
928 g_socket_client_proxy_connect_callback (GObject      *object,
929                                         GAsyncResult *result,
930                                         gpointer      user_data)
931 {
932   GSocketClientAsyncConnectData *data = user_data;
933   GIOStream *io_stream;
934   GTcpConnection *old_connection = G_TCP_CONNECTION (data->connection);
935
936   io_stream = g_proxy_connect_finish (G_PROXY (object),
937                                       result,
938                                       &data->last_error);
939
940   if (io_stream)
941     {
942       if (G_IS_SOCKET_CONNECTION (io_stream))
943         data->connection = G_SOCKET_CONNECTION (g_object_ref (io_stream));
944       else
945         data->connection = _g_proxy_connection_new (old_connection,
946                                                     io_stream);
947       g_object_unref (io_stream);
948     }
949   else
950     {
951       data->connection = NULL;
952     }
953
954   g_object_unref (old_connection);
955
956   g_socket_client_async_connect_complete (data);
957 }
958
959 static void
960 g_socket_client_proxy_connect (GSocketClientAsyncConnectData *data)
961 {
962   GProxy *proxy;
963   const gchar *protocol = g_proxy_address_get_protocol (data->proxy_addr);
964
965   proxy = g_proxy_get_default_for_protocol (protocol);
966
967   /* The connection should not be anything else then TCP Connection,
968    * but let's put a safety guard in case
969    */
970   if (!G_IS_TCP_CONNECTION (data->connection))
971     {
972       g_critical ("Trying to proxy over non-TCP connection, this is "
973           "most likely a bug in GLib IO library.");
974
975       g_set_error_literal (&data->last_error,
976           G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
977           _("Trying to proxy over non-TCP connection is not supported."));
978
979       g_object_unref (data->connection);
980       data->connection = NULL;
981
982       enumerator_next_async (data);
983     }
984   else if (proxy)
985     {
986       g_proxy_connect_async (proxy,
987                              G_IO_STREAM (data->connection),
988                              data->proxy_addr,
989                              data->cancellable,
990                              g_socket_client_proxy_connect_callback,
991                              data);
992       g_object_unref (proxy);
993     }
994   else
995     {
996       g_clear_error (&data->last_error);
997
998       g_set_error (&data->last_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
999           _("Proxy protocol '%s' is not supported."),
1000           protocol);
1001
1002       g_object_unref (data->connection);
1003       data->connection = NULL;
1004
1005       enumerator_next_async (data);
1006     }
1007 }
1008
1009 static gboolean
1010 g_socket_client_socket_callback (GSocket *socket,
1011                                  GIOCondition condition,
1012                                  GSocketClientAsyncConnectData *data)
1013 {
1014   GError *error = NULL;
1015
1016   if (g_cancellable_is_cancelled (data->cancellable))
1017     {
1018       /* Cancelled, return done with last error being cancelled */
1019       g_clear_error (&data->last_error);
1020       g_object_unref (data->current_socket);
1021       data->current_socket = NULL;
1022       g_cancellable_set_error_if_cancelled (data->cancellable,
1023                                             &data->last_error);
1024     }
1025   else
1026     {
1027       /* socket is ready for writing means connect done, did it succeed? */
1028       if (!g_socket_check_connect_result (data->current_socket, &error))
1029         {
1030           set_last_error (data, error);
1031           g_object_unref (data->current_socket);
1032           data->current_socket = NULL;
1033
1034           /* try next one */
1035           enumerator_next_async (data);
1036
1037           return FALSE;
1038         }
1039     }
1040
1041   g_socket_set_blocking (data->current_socket, TRUE);
1042
1043   data->connection =
1044     g_socket_connection_factory_create_connection (data->current_socket);
1045   g_object_unref (data->current_socket);
1046   data->current_socket = NULL;
1047
1048   if (data->proxy_addr)
1049     g_socket_client_proxy_connect (data);
1050   else
1051     g_socket_client_async_connect_complete (data);
1052
1053   return FALSE;
1054 }
1055
1056 static void
1057 g_socket_client_enumerator_callback (GObject      *object,
1058                                      GAsyncResult *result,
1059                                      gpointer      user_data)
1060 {
1061   GSocketClientAsyncConnectData *data = user_data;
1062   GSocketAddress *address = NULL;
1063   GSocket *socket;
1064   GError *tmp_error = NULL;
1065
1066   if (g_cancellable_is_cancelled (data->cancellable))
1067     {
1068       g_clear_error (&data->last_error);
1069       g_cancellable_set_error_if_cancelled (data->cancellable, &data->last_error);
1070       g_socket_client_async_connect_complete (data);
1071       return;
1072     }
1073
1074   address = g_socket_address_enumerator_next_finish (data->enumerator,
1075                                                      result, &tmp_error);
1076
1077   if (address == NULL)
1078     {
1079       if (tmp_error)
1080         set_last_error (data, tmp_error);
1081       else if (data->last_error == NULL)
1082         g_set_error_literal (&data->last_error, G_IO_ERROR, G_IO_ERROR_FAILED,
1083                              _("Unknown error on connect"));
1084
1085       g_socket_client_async_connect_complete (data);
1086       return;
1087     }
1088
1089   if (G_IS_PROXY_ADDRESS (address) &&
1090       data->client->priv->enable_proxy)
1091     data->proxy_addr = g_object_ref (G_PROXY_ADDRESS (address));
1092
1093   g_clear_error (&data->last_error);
1094
1095   socket = create_socket (data->client, address, &data->last_error);
1096   if (socket != NULL)
1097     {
1098       g_socket_set_blocking (socket, FALSE);
1099       if (g_socket_connect (socket, address, data->cancellable, &tmp_error))
1100         {
1101           data->current_socket = socket;
1102           g_socket_client_async_connect_complete (data);
1103
1104           g_object_unref (address);
1105           return;
1106         }
1107       else if (g_error_matches (tmp_error, G_IO_ERROR, G_IO_ERROR_PENDING))
1108         {
1109           GSource *source;
1110
1111           data->current_socket = socket;
1112           g_error_free (tmp_error);
1113
1114           source = g_socket_create_source (socket, G_IO_OUT,
1115                                            data->cancellable);
1116           g_source_set_callback (source,
1117                                  (GSourceFunc) g_socket_client_socket_callback,
1118                                  data, NULL);
1119           g_source_attach (source, g_main_context_get_thread_default ());
1120           g_source_unref (source);
1121
1122           g_object_unref (address);
1123           return;
1124         }
1125       else
1126         {
1127           data->last_error = tmp_error;
1128           g_object_unref (socket);
1129         }
1130     }
1131
1132   g_object_unref (address);
1133   enumerator_next_async (data);
1134 }
1135
1136 /**
1137  * g_socket_client_connect_async:
1138  * @client: a #GTcpClient
1139  * @connectable: a #GSocketConnectable specifying the remote address.
1140  * @cancellable: a #GCancellable, or %NULL
1141  * @callback: a #GAsyncReadyCallback
1142  * @user_data: user data for the callback
1143  *
1144  * This is the asynchronous version of g_socket_client_connect().
1145  *
1146  * When the operation is finished @callback will be
1147  * called. You can then call g_socket_client_connect_finish() to get
1148  * the result of the operation.
1149  *
1150  * Since: 2.22
1151  */
1152 void
1153 g_socket_client_connect_async (GSocketClient       *client,
1154                                GSocketConnectable  *connectable,
1155                                GCancellable        *cancellable,
1156                                GAsyncReadyCallback  callback,
1157                                gpointer             user_data)
1158 {
1159   GSocketClientAsyncConnectData *data;
1160
1161   g_return_if_fail (G_IS_SOCKET_CLIENT (client));
1162
1163   data = g_slice_new0 (GSocketClientAsyncConnectData);
1164
1165   data->result = g_simple_async_result_new (G_OBJECT (client),
1166                                             callback, user_data,
1167                                             g_socket_client_connect_async);
1168   data->client = client;
1169   if (cancellable)
1170     data->cancellable = g_object_ref (cancellable);
1171
1172   if (can_use_proxy (client))
1173       data->enumerator = g_socket_connectable_proxy_enumerate (connectable);
1174   else
1175       data->enumerator = g_socket_connectable_enumerate (connectable);
1176
1177   enumerator_next_async (data);
1178 }
1179
1180 /**
1181  * g_socket_client_connect_to_host_async:
1182  * @client: a #GTcpClient
1183  * @host_and_port: the name and optionally the port of the host to connect to
1184  * @default_port: the default port to connect to
1185  * @cancellable: a #GCancellable, or %NULL
1186  * @callback: a #GAsyncReadyCallback
1187  * @user_data: user data for the callback
1188  *
1189  * This is the asynchronous version of g_socket_client_connect_to_host().
1190  *
1191  * When the operation is finished @callback will be
1192  * called. You can then call g_socket_client_connect_to_host_finish() to get
1193  * the result of the operation.
1194  *
1195  * Since: 2.22
1196  */
1197 void
1198 g_socket_client_connect_to_host_async (GSocketClient        *client,
1199                                        const gchar          *host_and_port,
1200                                        guint16               default_port,
1201                                        GCancellable         *cancellable,
1202                                        GAsyncReadyCallback   callback,
1203                                        gpointer              user_data)
1204 {
1205   GSocketConnectable *connectable;
1206   GError *error;
1207
1208   error = NULL;
1209   connectable = g_network_address_parse (host_and_port, default_port,
1210                                          &error);
1211   if (connectable == NULL)
1212     {
1213       g_simple_async_report_gerror_in_idle (G_OBJECT (client),
1214                                             callback, user_data, error);
1215       g_error_free (error);
1216     }
1217   else
1218     {
1219       g_socket_client_connect_async (client,
1220                                      connectable, cancellable,
1221                                      callback, user_data);
1222       g_object_unref (connectable);
1223     }
1224 }
1225
1226 /**
1227  * g_socket_client_connect_to_service_async:
1228  * @client: a #GSocketClient
1229  * @domain: a domain name
1230  * @service: the name of the service to connect to
1231  * @cancellable: a #GCancellable, or %NULL
1232  * @callback: a #GAsyncReadyCallback
1233  * @user_data: user data for the callback
1234  *
1235  * This is the asynchronous version of
1236  * g_socket_client_connect_to_service().
1237  *
1238  * Since: 2.22
1239  */
1240 void
1241 g_socket_client_connect_to_service_async (GSocketClient       *client,
1242                                           const gchar         *domain,
1243                                           const gchar         *service,
1244                                           GCancellable        *cancellable,
1245                                           GAsyncReadyCallback  callback,
1246                                           gpointer             user_data)
1247 {
1248   GSocketConnectable *connectable;
1249
1250   connectable = g_network_service_new (service, "tcp", domain);
1251   g_socket_client_connect_async (client,
1252                                  connectable, cancellable,
1253                                  callback, user_data);
1254   g_object_unref (connectable);
1255 }
1256
1257 /**
1258  * g_socket_client_connect_finish:
1259  * @client: a #GSocketClient.
1260  * @result: a #GAsyncResult.
1261  * @error: a #GError location to store the error occuring, or %NULL to
1262  * ignore.
1263  *
1264  * Finishes an async connect operation. See g_socket_client_connect_async()
1265  *
1266  * Returns: a #GSocketConnection on success, %NULL on error.
1267  *
1268  * Since: 2.22
1269  */
1270 GSocketConnection *
1271 g_socket_client_connect_finish (GSocketClient  *client,
1272                                 GAsyncResult   *result,
1273                                 GError        **error)
1274 {
1275   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
1276
1277   if (g_simple_async_result_propagate_error (simple, error))
1278     return NULL;
1279
1280   return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
1281 }
1282
1283 /**
1284  * g_socket_client_connect_to_host_finish:
1285  * @client: a #GSocketClient.
1286  * @result: a #GAsyncResult.
1287  * @error: a #GError location to store the error occuring, or %NULL to
1288  * ignore.
1289  *
1290  * Finishes an async connect operation. See g_socket_client_connect_to_host_async()
1291  *
1292  * Returns: a #GSocketConnection on success, %NULL on error.
1293  *
1294  * Since: 2.22
1295  */
1296 GSocketConnection *
1297 g_socket_client_connect_to_host_finish (GSocketClient  *client,
1298                                         GAsyncResult   *result,
1299                                         GError        **error)
1300 {
1301   return g_socket_client_connect_finish (client, result, error);
1302 }
1303
1304 /**
1305  * g_socket_client_connect_to_service_finish:
1306  * @client: a #GSocketClient.
1307  * @result: a #GAsyncResult.
1308  * @error: a #GError location to store the error occuring, or %NULL to
1309  * ignore.
1310  *
1311  * Finishes an async connect operation. See g_socket_client_connect_to_service_async()
1312  *
1313  * Returns: a #GSocketConnection on success, %NULL on error.
1314  *
1315  * Since: 2.22
1316  */
1317 GSocketConnection *
1318 g_socket_client_connect_to_service_finish (GSocketClient  *client,
1319                                            GAsyncResult   *result,
1320                                            GError        **error)
1321 {
1322   return g_socket_client_connect_finish (client, result, error);
1323 }