Implemented g_socket_client_connect_to_uri() method
[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 #GSocketClient
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 /**
862  * g_socket_client_connect_to_uri:
863  * @client: a #GSocketClient
864  * @uri: A network URI
865  * @default_port: the default port to connect to
866  * @cancellable: a #GCancellable, or %NULL
867  * @error: a pointer to a #GError, or %NULL
868  *
869  * This is a helper function for g_socket_client_connect().
870  *
871  * Attempts to create a TCP connection with a network URI.
872  *
873  * @uri may be any valid URI containing an "authority" (hostname/port)
874  * component. If a port is not specified in the URI, @default_port
875  * will be used.
876  *
877  * Using this rather than g_socket_client_connect() or
878  * g_socket_client_connect_to_host() allows #GSocketClient to
879  * determine when to use application-specific proxy protocols.
880  *
881  * Upon a successful connection, a new #GSocketConnection is constructed
882  * and returned.  The caller owns this new object and must drop their
883  * reference to it when finished with it.
884  *
885  * In the event of any failure (DNS error, service not found, no hosts
886  * connectable) %NULL is returned and @error (if non-%NULL) is set
887  * accordingly.
888  *
889  * Returns: a #GSocketConnection on success, %NULL on error.
890  *
891  * Since: 2.26
892  */
893 GSocketConnection *
894 g_socket_client_connect_to_uri (GSocketClient  *client,
895                                 const gchar    *uri,
896                                 guint16         default_port,
897                                 GCancellable   *cancellable,
898                                 GError        **error)
899 {
900   GSocketConnectable *connectable;
901   GSocketConnection *connection;
902
903   connectable = g_network_address_parse_uri (uri, default_port, error);
904   if (connectable == NULL)
905     return NULL;
906
907   connection = g_socket_client_connect (client, connectable,
908                                         cancellable, error);
909   g_object_unref (connectable);
910
911   return connection;
912 }
913
914 typedef struct
915 {
916   GSimpleAsyncResult *result;
917   GCancellable *cancellable;
918   GSocketClient *client;
919
920   GSocketAddressEnumerator *enumerator;
921   GProxyAddress *proxy_addr;
922   GSocket *current_socket;
923   GSocketConnection *connection;
924
925   GError *last_error;
926 } GSocketClientAsyncConnectData;
927
928 static void
929 g_socket_client_async_connect_complete (GSocketClientAsyncConnectData *data)
930 {
931   if (data->last_error)
932     {
933       g_simple_async_result_set_from_error (data->result, data->last_error);
934       g_error_free (data->last_error);
935     }
936   else
937     {
938       g_assert (data->connection);
939
940       g_simple_async_result_set_op_res_gpointer (data->result,
941                                                  data->connection,
942                                                  g_object_unref);
943     }
944
945   g_simple_async_result_complete (data->result);
946   g_object_unref (data->result);
947   g_object_unref (data->enumerator);
948   if (data->cancellable)
949     g_object_unref (data->cancellable);
950   if (data->current_socket)
951     g_object_unref (data->current_socket);
952   if (data->proxy_addr)
953     g_object_unref (data->proxy_addr);
954   g_slice_free (GSocketClientAsyncConnectData, data);
955 }
956
957
958 static void
959 g_socket_client_enumerator_callback (GObject      *object,
960                                      GAsyncResult *result,
961                                      gpointer      user_data);
962
963 static void
964 set_last_error (GSocketClientAsyncConnectData *data,
965                 GError *error)
966 {
967   g_clear_error (&data->last_error);
968   data->last_error = error;
969 }
970
971 static void
972 enumerator_next_async (GSocketClientAsyncConnectData *data)
973 {
974   g_socket_address_enumerator_next_async (data->enumerator,
975                                           data->cancellable,
976                                           g_socket_client_enumerator_callback,
977                                           data);
978 }
979
980 static void
981 g_socket_client_proxy_connect_callback (GObject      *object,
982                                         GAsyncResult *result,
983                                         gpointer      user_data)
984 {
985   GSocketClientAsyncConnectData *data = user_data;
986   GIOStream *io_stream;
987   GTcpConnection *old_connection = G_TCP_CONNECTION (data->connection);
988
989   io_stream = g_proxy_connect_finish (G_PROXY (object),
990                                       result,
991                                       &data->last_error);
992
993   if (io_stream)
994     {
995       if (G_IS_SOCKET_CONNECTION (io_stream))
996         data->connection = G_SOCKET_CONNECTION (g_object_ref (io_stream));
997       else
998         data->connection = _g_proxy_connection_new (old_connection,
999                                                     io_stream);
1000       g_object_unref (io_stream);
1001     }
1002   else
1003     {
1004       data->connection = NULL;
1005     }
1006
1007   g_object_unref (old_connection);
1008
1009   g_socket_client_async_connect_complete (data);
1010 }
1011
1012 static void
1013 g_socket_client_proxy_connect (GSocketClientAsyncConnectData *data)
1014 {
1015   GProxy *proxy;
1016   const gchar *protocol = g_proxy_address_get_protocol (data->proxy_addr);
1017
1018   proxy = g_proxy_get_default_for_protocol (protocol);
1019
1020   /* The connection should not be anything else then TCP Connection,
1021    * but let's put a safety guard in case
1022    */
1023   if (!G_IS_TCP_CONNECTION (data->connection))
1024     {
1025       g_critical ("Trying to proxy over non-TCP connection, this is "
1026           "most likely a bug in GLib IO library.");
1027
1028       g_set_error_literal (&data->last_error,
1029           G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
1030           _("Trying to proxy over non-TCP connection is not supported."));
1031
1032       g_object_unref (data->connection);
1033       data->connection = NULL;
1034
1035       enumerator_next_async (data);
1036     }
1037   else if (proxy)
1038     {
1039       g_proxy_connect_async (proxy,
1040                              G_IO_STREAM (data->connection),
1041                              data->proxy_addr,
1042                              data->cancellable,
1043                              g_socket_client_proxy_connect_callback,
1044                              data);
1045       g_object_unref (proxy);
1046     }
1047   else
1048     {
1049       g_clear_error (&data->last_error);
1050
1051       g_set_error (&data->last_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
1052           _("Proxy protocol '%s' is not supported."),
1053           protocol);
1054
1055       g_object_unref (data->connection);
1056       data->connection = NULL;
1057
1058       enumerator_next_async (data);
1059     }
1060 }
1061
1062 static gboolean
1063 g_socket_client_socket_callback (GSocket *socket,
1064                                  GIOCondition condition,
1065                                  GSocketClientAsyncConnectData *data)
1066 {
1067   GError *error = NULL;
1068
1069   if (g_cancellable_is_cancelled (data->cancellable))
1070     {
1071       /* Cancelled, return done with last error being cancelled */
1072       g_clear_error (&data->last_error);
1073       g_object_unref (data->current_socket);
1074       data->current_socket = NULL;
1075       g_cancellable_set_error_if_cancelled (data->cancellable,
1076                                             &data->last_error);
1077     }
1078   else
1079     {
1080       /* socket is ready for writing means connect done, did it succeed? */
1081       if (!g_socket_check_connect_result (data->current_socket, &error))
1082         {
1083           set_last_error (data, error);
1084           g_object_unref (data->current_socket);
1085           data->current_socket = NULL;
1086
1087           /* try next one */
1088           enumerator_next_async (data);
1089
1090           return FALSE;
1091         }
1092     }
1093
1094   g_socket_set_blocking (data->current_socket, TRUE);
1095
1096   data->connection =
1097     g_socket_connection_factory_create_connection (data->current_socket);
1098   g_object_unref (data->current_socket);
1099   data->current_socket = NULL;
1100
1101   if (data->proxy_addr)
1102     g_socket_client_proxy_connect (data);
1103   else
1104     g_socket_client_async_connect_complete (data);
1105
1106   return FALSE;
1107 }
1108
1109 static void
1110 g_socket_client_enumerator_callback (GObject      *object,
1111                                      GAsyncResult *result,
1112                                      gpointer      user_data)
1113 {
1114   GSocketClientAsyncConnectData *data = user_data;
1115   GSocketAddress *address = NULL;
1116   GSocket *socket;
1117   GError *tmp_error = NULL;
1118
1119   if (g_cancellable_is_cancelled (data->cancellable))
1120     {
1121       g_clear_error (&data->last_error);
1122       g_cancellable_set_error_if_cancelled (data->cancellable, &data->last_error);
1123       g_socket_client_async_connect_complete (data);
1124       return;
1125     }
1126
1127   address = g_socket_address_enumerator_next_finish (data->enumerator,
1128                                                      result, &tmp_error);
1129
1130   if (address == NULL)
1131     {
1132       if (tmp_error)
1133         set_last_error (data, tmp_error);
1134       else if (data->last_error == NULL)
1135         g_set_error_literal (&data->last_error, G_IO_ERROR, G_IO_ERROR_FAILED,
1136                              _("Unknown error on connect"));
1137
1138       g_socket_client_async_connect_complete (data);
1139       return;
1140     }
1141
1142   if (G_IS_PROXY_ADDRESS (address) &&
1143       data->client->priv->enable_proxy)
1144     data->proxy_addr = g_object_ref (G_PROXY_ADDRESS (address));
1145
1146   g_clear_error (&data->last_error);
1147
1148   socket = create_socket (data->client, address, &data->last_error);
1149   if (socket != NULL)
1150     {
1151       g_socket_set_blocking (socket, FALSE);
1152       if (g_socket_connect (socket, address, data->cancellable, &tmp_error))
1153         {
1154           data->current_socket = socket;
1155           g_socket_client_async_connect_complete (data);
1156
1157           g_object_unref (address);
1158           return;
1159         }
1160       else if (g_error_matches (tmp_error, G_IO_ERROR, G_IO_ERROR_PENDING))
1161         {
1162           GSource *source;
1163
1164           data->current_socket = socket;
1165           g_error_free (tmp_error);
1166
1167           source = g_socket_create_source (socket, G_IO_OUT,
1168                                            data->cancellable);
1169           g_source_set_callback (source,
1170                                  (GSourceFunc) g_socket_client_socket_callback,
1171                                  data, NULL);
1172           g_source_attach (source, g_main_context_get_thread_default ());
1173           g_source_unref (source);
1174
1175           g_object_unref (address);
1176           return;
1177         }
1178       else
1179         {
1180           data->last_error = tmp_error;
1181           g_object_unref (socket);
1182         }
1183     }
1184
1185   g_object_unref (address);
1186   enumerator_next_async (data);
1187 }
1188
1189 /**
1190  * g_socket_client_connect_async:
1191  * @client: a #GTcpClient
1192  * @connectable: a #GSocketConnectable specifying the remote address.
1193  * @cancellable: a #GCancellable, or %NULL
1194  * @callback: a #GAsyncReadyCallback
1195  * @user_data: user data for the callback
1196  *
1197  * This is the asynchronous version of g_socket_client_connect().
1198  *
1199  * When the operation is finished @callback will be
1200  * called. You can then call g_socket_client_connect_finish() to get
1201  * the result of the operation.
1202  *
1203  * Since: 2.22
1204  */
1205 void
1206 g_socket_client_connect_async (GSocketClient       *client,
1207                                GSocketConnectable  *connectable,
1208                                GCancellable        *cancellable,
1209                                GAsyncReadyCallback  callback,
1210                                gpointer             user_data)
1211 {
1212   GSocketClientAsyncConnectData *data;
1213
1214   g_return_if_fail (G_IS_SOCKET_CLIENT (client));
1215
1216   data = g_slice_new0 (GSocketClientAsyncConnectData);
1217
1218   data->result = g_simple_async_result_new (G_OBJECT (client),
1219                                             callback, user_data,
1220                                             g_socket_client_connect_async);
1221   data->client = client;
1222   if (cancellable)
1223     data->cancellable = g_object_ref (cancellable);
1224
1225   if (can_use_proxy (client))
1226       data->enumerator = g_socket_connectable_proxy_enumerate (connectable);
1227   else
1228       data->enumerator = g_socket_connectable_enumerate (connectable);
1229
1230   enumerator_next_async (data);
1231 }
1232
1233 /**
1234  * g_socket_client_connect_to_host_async:
1235  * @client: a #GTcpClient
1236  * @host_and_port: the name and optionally the port of the host to connect to
1237  * @default_port: the default port to connect to
1238  * @cancellable: a #GCancellable, or %NULL
1239  * @callback: a #GAsyncReadyCallback
1240  * @user_data: user data for the callback
1241  *
1242  * This is the asynchronous version of g_socket_client_connect_to_host().
1243  *
1244  * When the operation is finished @callback will be
1245  * called. You can then call g_socket_client_connect_to_host_finish() to get
1246  * the result of the operation.
1247  *
1248  * Since: 2.22
1249  */
1250 void
1251 g_socket_client_connect_to_host_async (GSocketClient        *client,
1252                                        const gchar          *host_and_port,
1253                                        guint16               default_port,
1254                                        GCancellable         *cancellable,
1255                                        GAsyncReadyCallback   callback,
1256                                        gpointer              user_data)
1257 {
1258   GSocketConnectable *connectable;
1259   GError *error;
1260
1261   error = NULL;
1262   connectable = g_network_address_parse (host_and_port, default_port,
1263                                          &error);
1264   if (connectable == NULL)
1265     {
1266       g_simple_async_report_gerror_in_idle (G_OBJECT (client),
1267                                             callback, user_data, error);
1268       g_error_free (error);
1269     }
1270   else
1271     {
1272       g_socket_client_connect_async (client,
1273                                      connectable, cancellable,
1274                                      callback, user_data);
1275       g_object_unref (connectable);
1276     }
1277 }
1278
1279 /**
1280  * g_socket_client_connect_to_service_async:
1281  * @client: a #GSocketClient
1282  * @domain: a domain name
1283  * @service: the name of the service to connect to
1284  * @cancellable: a #GCancellable, or %NULL
1285  * @callback: a #GAsyncReadyCallback
1286  * @user_data: user data for the callback
1287  *
1288  * This is the asynchronous version of
1289  * g_socket_client_connect_to_service().
1290  *
1291  * Since: 2.22
1292  */
1293 void
1294 g_socket_client_connect_to_service_async (GSocketClient       *client,
1295                                           const gchar         *domain,
1296                                           const gchar         *service,
1297                                           GCancellable        *cancellable,
1298                                           GAsyncReadyCallback  callback,
1299                                           gpointer             user_data)
1300 {
1301   GSocketConnectable *connectable;
1302
1303   connectable = g_network_service_new (service, "tcp", domain);
1304   g_socket_client_connect_async (client,
1305                                  connectable, cancellable,
1306                                  callback, user_data);
1307   g_object_unref (connectable);
1308 }
1309
1310 /**
1311  * g_socket_client_connect_to_uri_async:
1312  * @client: a #GSocketClient
1313  * @uri: a network uri
1314  * @default_port: the default port to connect to
1315  * @cancellable: a #GCancellable, or %NULL
1316  * @callback: a #GAsyncReadyCallback
1317  * @user_data: user data for the callback
1318  *
1319  * This is the asynchronous version of g_socket_client_connect_to_uri().
1320  *
1321  * When the operation is finished @callback will be
1322  * called. You can then call g_socket_client_connect_to_uri_finish() to get
1323  * the result of the operation.
1324  *
1325  * Since: 2.26
1326  */
1327 void
1328 g_socket_client_connect_to_uri_async (GSocketClient        *client,
1329                                       const gchar          *uri,
1330                                       guint16               default_port,
1331                                       GCancellable         *cancellable,
1332                                       GAsyncReadyCallback   callback,
1333                                       gpointer              user_data)
1334 {
1335   GSocketConnectable *connectable;
1336   GError *error;
1337
1338   error = NULL;
1339   connectable = g_network_address_parse_uri (uri, default_port, &error);
1340   if (connectable == NULL)
1341     {
1342       g_simple_async_report_gerror_in_idle (G_OBJECT (client),
1343                                             callback, user_data, error);
1344       g_error_free (error);
1345     }
1346   else
1347     {
1348       g_socket_client_connect_async (client,
1349                                      connectable, cancellable,
1350                                      callback, user_data);
1351       g_object_unref (connectable);
1352     }
1353 }
1354
1355
1356 /**
1357  * g_socket_client_connect_finish:
1358  * @client: a #GSocketClient.
1359  * @result: a #GAsyncResult.
1360  * @error: a #GError location to store the error occuring, or %NULL to
1361  * ignore.
1362  *
1363  * Finishes an async connect operation. See g_socket_client_connect_async()
1364  *
1365  * Returns: a #GSocketConnection on success, %NULL on error.
1366  *
1367  * Since: 2.22
1368  */
1369 GSocketConnection *
1370 g_socket_client_connect_finish (GSocketClient  *client,
1371                                 GAsyncResult   *result,
1372                                 GError        **error)
1373 {
1374   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
1375
1376   if (g_simple_async_result_propagate_error (simple, error))
1377     return NULL;
1378
1379   return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
1380 }
1381
1382 /**
1383  * g_socket_client_connect_to_host_finish:
1384  * @client: a #GSocketClient.
1385  * @result: a #GAsyncResult.
1386  * @error: a #GError location to store the error occuring, or %NULL to
1387  * ignore.
1388  *
1389  * Finishes an async connect operation. See g_socket_client_connect_to_host_async()
1390  *
1391  * Returns: a #GSocketConnection on success, %NULL on error.
1392  *
1393  * Since: 2.22
1394  */
1395 GSocketConnection *
1396 g_socket_client_connect_to_host_finish (GSocketClient  *client,
1397                                         GAsyncResult   *result,
1398                                         GError        **error)
1399 {
1400   return g_socket_client_connect_finish (client, result, error);
1401 }
1402
1403 /**
1404  * g_socket_client_connect_to_service_finish:
1405  * @client: a #GSocketClient.
1406  * @result: a #GAsyncResult.
1407  * @error: a #GError location to store the error occuring, or %NULL to
1408  * ignore.
1409  *
1410  * Finishes an async connect operation. See g_socket_client_connect_to_service_async()
1411  *
1412  * Returns: a #GSocketConnection on success, %NULL on error.
1413  *
1414  * Since: 2.22
1415  */
1416 GSocketConnection *
1417 g_socket_client_connect_to_service_finish (GSocketClient  *client,
1418                                            GAsyncResult   *result,
1419                                            GError        **error)
1420 {
1421   return g_socket_client_connect_finish (client, result, error);
1422 }
1423
1424 /**
1425  * g_socket_client_connect_to_uri_finish:
1426  * @client: a #GSocketClient.
1427  * @result: a #GAsyncResult.
1428  * @error: a #GError location to store the error occuring, or %NULL to
1429  * ignore.
1430  *
1431  * Finishes an async connect operation. See g_socket_client_connect_to_uri_async()
1432  *
1433  * Returns: a #GSocketConnection on success, %NULL on error.
1434  *
1435  * Since: 2.26
1436  */
1437 GSocketConnection *
1438 g_socket_client_connect_to_uri_finish (GSocketClient  *client,
1439                                        GAsyncResult   *result,
1440                                        GError        **error)
1441 {
1442   return g_socket_client_connect_finish (client, result, error);
1443 }