Add g_socket_connection_connect(), etc
[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/gsimpleasyncresult.h>
38 #include <gio/gcancellable.h>
39 #include <gio/gioerror.h>
40 #include <gio/gsocket.h>
41 #include <gio/gnetworkaddress.h>
42 #include <gio/gnetworkservice.h>
43 #include <gio/gproxy.h>
44 #include <gio/gsocketaddress.h>
45 #include <gio/gtcpconnection.h>
46 #include <gio/gtcpwrapperconnection.h>
47 #include <gio/gtlscertificate.h>
48 #include <gio/gtlsclientconnection.h>
49 #include <gio/ginetaddress.h>
50 #include "glibintl.h"
51
52
53 /**
54  * SECTION:gsocketclient
55  * @short_description: Helper for connecting to a network service
56  * @include: gio/gio.h
57  * @see_also: #GSocketConnection, #GSocketListener
58  *
59  * #GSocketClient is a high-level utility class for connecting to a
60  * network host using a connection oriented socket type.
61  *
62  * You create a #GSocketClient object, set any options you want, and then
63  * call a sync or async connect operation, which returns a #GSocketConnection
64  * subclass on success.
65  *
66  * The type of the #GSocketConnection object returned depends on the type of
67  * the underlying socket that is in use. For instance, for a TCP/IP connection
68  * it will be a #GTcpConnection.
69  *
70  * Since: 2.22
71  */
72
73
74 G_DEFINE_TYPE (GSocketClient, g_socket_client, G_TYPE_OBJECT);
75
76 enum
77 {
78   PROP_NONE,
79   PROP_FAMILY,
80   PROP_TYPE,
81   PROP_PROTOCOL,
82   PROP_LOCAL_ADDRESS,
83   PROP_TIMEOUT,
84   PROP_ENABLE_PROXY,
85   PROP_TLS,
86   PROP_TLS_VALIDATION_FLAGS
87 };
88
89 struct _GSocketClientPrivate
90 {
91   GSocketFamily family;
92   GSocketType type;
93   GSocketProtocol protocol;
94   GSocketAddress *local_address;
95   guint timeout;
96   gboolean enable_proxy;
97   GHashTable *app_proxies;
98   gboolean tls;
99   GTlsCertificateFlags tls_validation_flags;
100 };
101
102 static GSocket *
103 create_socket (GSocketClient  *client,
104                GSocketAddress *dest_address,
105                GError        **error)
106 {
107   GSocketFamily family;
108   GSocket *socket;
109
110   family = client->priv->family;
111   if (family == G_SOCKET_FAMILY_INVALID &&
112       client->priv->local_address != NULL)
113     family = g_socket_address_get_family (client->priv->local_address);
114   if (family == G_SOCKET_FAMILY_INVALID)
115     family = g_socket_address_get_family (dest_address);
116
117   socket = g_socket_new (family,
118                          client->priv->type,
119                          client->priv->protocol,
120                          error);
121   if (socket == NULL)
122     return NULL;
123
124   if (client->priv->local_address)
125     {
126       if (!g_socket_bind (socket,
127                           client->priv->local_address,
128                           FALSE,
129                           error))
130         {
131           g_object_unref (socket);
132           return NULL;
133         }
134     }
135
136   if (client->priv->timeout)
137     g_socket_set_timeout (socket, client->priv->timeout);
138
139   return socket;
140 }
141
142 static gboolean
143 can_use_proxy (GSocketClient *client)
144 {
145   GSocketClientPrivate *priv = client->priv;
146
147   return priv->enable_proxy
148           && priv->type == G_SOCKET_TYPE_STREAM;
149 }
150
151 static void
152 clarify_connect_error (GError             *error,
153                        GSocketConnectable *connectable,
154                        GSocketAddress     *address)
155 {
156   const char *name;
157   char *tmp_name = NULL;
158
159   if (G_IS_PROXY_ADDRESS (address))
160     {
161       name = tmp_name = g_inet_address_to_string (g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (address)));
162
163       g_prefix_error (&error, _("Could not connect to proxy server %s: "), name);
164     }
165   else
166     {
167       if (G_IS_NETWORK_ADDRESS (connectable))
168         name = g_network_address_get_hostname (G_NETWORK_ADDRESS (connectable));
169       else if (G_IS_NETWORK_SERVICE (connectable))
170         name = g_network_service_get_domain (G_NETWORK_SERVICE (connectable));
171       else if (G_IS_INET_SOCKET_ADDRESS (connectable))
172         name = tmp_name = g_inet_address_to_string (g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (connectable)));
173       else
174         name = NULL;
175
176       if (name)
177         g_prefix_error (&error, _("Could not connect to %s: "), name);
178       else
179         g_prefix_error (&error, _("Could not connect: "));
180     }
181
182   g_free (tmp_name);
183 }
184
185 static void
186 g_socket_client_init (GSocketClient *client)
187 {
188   client->priv = G_TYPE_INSTANCE_GET_PRIVATE (client,
189                                               G_TYPE_SOCKET_CLIENT,
190                                               GSocketClientPrivate);
191   client->priv->type = G_SOCKET_TYPE_STREAM;
192   client->priv->app_proxies = g_hash_table_new_full (g_str_hash,
193                                                      g_str_equal,
194                                                      g_free,
195                                                      NULL);
196 }
197
198 /**
199  * g_socket_client_new:
200  *
201  * Creates a new #GSocketClient with the default options.
202  *
203  * Returns: a #GSocketClient.
204  *     Free the returned object with g_object_unref().
205  *
206  * Since: 2.22
207  */
208 GSocketClient *
209 g_socket_client_new (void)
210 {
211   return g_object_new (G_TYPE_SOCKET_CLIENT, NULL);
212 }
213
214 static void
215 g_socket_client_finalize (GObject *object)
216 {
217   GSocketClient *client = G_SOCKET_CLIENT (object);
218
219   if (client->priv->local_address)
220     g_object_unref (client->priv->local_address);
221
222   if (G_OBJECT_CLASS (g_socket_client_parent_class)->finalize)
223     (*G_OBJECT_CLASS (g_socket_client_parent_class)->finalize) (object);
224
225   g_hash_table_unref (client->priv->app_proxies);
226 }
227
228 static void
229 g_socket_client_get_property (GObject    *object,
230                               guint       prop_id,
231                               GValue     *value,
232                               GParamSpec *pspec)
233 {
234   GSocketClient *client = G_SOCKET_CLIENT (object);
235
236   switch (prop_id)
237     {
238       case PROP_FAMILY:
239         g_value_set_enum (value, client->priv->family);
240         break;
241
242       case PROP_TYPE:
243         g_value_set_enum (value, client->priv->type);
244         break;
245
246       case PROP_PROTOCOL:
247         g_value_set_enum (value, client->priv->protocol);
248         break;
249
250       case PROP_LOCAL_ADDRESS:
251         g_value_set_object (value, client->priv->local_address);
252         break;
253
254       case PROP_TIMEOUT:
255         g_value_set_uint (value, client->priv->timeout);
256         break;
257
258       case PROP_ENABLE_PROXY:
259         g_value_set_boolean (value, client->priv->enable_proxy);
260         break;
261
262       case PROP_TLS:
263         g_value_set_boolean (value, g_socket_client_get_tls (client));
264         break;
265
266       case PROP_TLS_VALIDATION_FLAGS:
267         g_value_set_flags (value, g_socket_client_get_tls_validation_flags (client));
268         break;
269
270       default:
271         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
272     }
273 }
274
275 static void
276 g_socket_client_set_property (GObject      *object,
277                               guint         prop_id,
278                               const GValue *value,
279                               GParamSpec   *pspec)
280 {
281   GSocketClient *client = G_SOCKET_CLIENT (object);
282
283   switch (prop_id)
284     {
285     case PROP_FAMILY:
286       g_socket_client_set_family (client, g_value_get_enum (value));
287       break;
288
289     case PROP_TYPE:
290       g_socket_client_set_socket_type (client, g_value_get_enum (value));
291       break;
292
293     case PROP_PROTOCOL:
294       g_socket_client_set_protocol (client, g_value_get_enum (value));
295       break;
296
297     case PROP_LOCAL_ADDRESS:
298       g_socket_client_set_local_address (client, g_value_get_object (value));
299       break;
300
301     case PROP_TIMEOUT:
302       g_socket_client_set_timeout (client, g_value_get_uint (value));
303       break;
304
305     case PROP_ENABLE_PROXY:
306       g_socket_client_set_enable_proxy (client, g_value_get_boolean (value));
307       break;
308
309     case PROP_TLS:
310       g_socket_client_set_tls (client, g_value_get_boolean (value));
311       break;
312
313     case PROP_TLS_VALIDATION_FLAGS:
314       g_socket_client_set_tls_validation_flags (client, g_value_get_flags (value));
315       break;
316
317     default:
318       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
319     }
320 }
321
322 /**
323  * g_socket_client_get_family:
324  * @client: a #GSocketClient.
325  *
326  * Gets the socket family of the socket client.
327  *
328  * See g_socket_client_set_family() for details.
329  *
330  * Returns: a #GSocketFamily
331  *
332  * Since: 2.22
333  */
334 GSocketFamily
335 g_socket_client_get_family (GSocketClient *client)
336 {
337   return client->priv->family;
338 }
339
340 /**
341  * g_socket_client_set_family:
342  * @client: a #GSocketClient.
343  * @family: a #GSocketFamily
344  *
345  * Sets the socket family of the socket client.
346  * If this is set to something other than %G_SOCKET_FAMILY_INVALID
347  * then the sockets created by this object will be of the specified
348  * family.
349  *
350  * This might be useful for instance if you want to force the local
351  * connection to be an ipv4 socket, even though the address might
352  * be an ipv6 mapped to ipv4 address.
353  *
354  * Since: 2.22
355  */
356 void
357 g_socket_client_set_family (GSocketClient *client,
358                             GSocketFamily  family)
359 {
360   if (client->priv->family == family)
361     return;
362
363   client->priv->family = family;
364   g_object_notify (G_OBJECT (client), "family");
365 }
366
367 /**
368  * g_socket_client_get_socket_type:
369  * @client: a #GSocketClient.
370  *
371  * Gets the socket type of the socket client.
372  *
373  * See g_socket_client_set_socket_type() for details.
374  *
375  * Returns: a #GSocketFamily
376  *
377  * Since: 2.22
378  */
379 GSocketType
380 g_socket_client_get_socket_type (GSocketClient *client)
381 {
382   return client->priv->type;
383 }
384
385 /**
386  * g_socket_client_set_socket_type:
387  * @client: a #GSocketClient.
388  * @type: a #GSocketType
389  *
390  * Sets the socket type of the socket client.
391  * The sockets created by this object will be of the specified
392  * type.
393  *
394  * It doesn't make sense to specify a type of %G_SOCKET_TYPE_DATAGRAM,
395  * as GSocketClient is used for connection oriented services.
396  *
397  * Since: 2.22
398  */
399 void
400 g_socket_client_set_socket_type (GSocketClient *client,
401                                  GSocketType    type)
402 {
403   if (client->priv->type == type)
404     return;
405
406   client->priv->type = type;
407   g_object_notify (G_OBJECT (client), "type");
408 }
409
410 /**
411  * g_socket_client_get_protocol:
412  * @client: a #GSocketClient
413  *
414  * Gets the protocol name type of the socket client.
415  *
416  * See g_socket_client_set_protocol() for details.
417  *
418  * Returns: a #GSocketProtocol
419  *
420  * Since: 2.22
421  */
422 GSocketProtocol
423 g_socket_client_get_protocol (GSocketClient *client)
424 {
425   return client->priv->protocol;
426 }
427
428 /**
429  * g_socket_client_set_protocol:
430  * @client: a #GSocketClient.
431  * @protocol: a #GSocketProtocol
432  *
433  * Sets the protocol of the socket client.
434  * The sockets created by this object will use of the specified
435  * protocol.
436  *
437  * If @protocol is %0 that means to use the default
438  * protocol for the socket family and type.
439  *
440  * Since: 2.22
441  */
442 void
443 g_socket_client_set_protocol (GSocketClient   *client,
444                               GSocketProtocol  protocol)
445 {
446   if (client->priv->protocol == protocol)
447     return;
448
449   client->priv->protocol = protocol;
450   g_object_notify (G_OBJECT (client), "protocol");
451 }
452
453 /**
454  * g_socket_client_get_local_address:
455  * @client: a #GSocketClient.
456  *
457  * Gets the local address of the socket client.
458  *
459  * See g_socket_client_set_local_address() for details.
460  *
461  * Returns: (transfer none): a #GSocketAddress or %NULL. Do not free.
462  *
463  * Since: 2.22
464  */
465 GSocketAddress *
466 g_socket_client_get_local_address (GSocketClient *client)
467 {
468   return client->priv->local_address;
469 }
470
471 /**
472  * g_socket_client_set_local_address:
473  * @client: a #GSocketClient.
474  * @address: a #GSocketAddress, or %NULL
475  *
476  * Sets the local address of the socket client.
477  * The sockets created by this object will bound to the
478  * specified address (if not %NULL) before connecting.
479  *
480  * This is useful if you want to ensure that the local
481  * side of the connection is on a specific port, or on
482  * a specific interface.
483  *
484  * Since: 2.22
485  */
486 void
487 g_socket_client_set_local_address (GSocketClient  *client,
488                                    GSocketAddress *address)
489 {
490   if (address)
491     g_object_ref (address);
492
493   if (client->priv->local_address)
494     {
495       g_object_unref (client->priv->local_address);
496     }
497   client->priv->local_address = address;
498   g_object_notify (G_OBJECT (client), "local-address");
499 }
500
501 /**
502  * g_socket_client_get_timeout:
503  * @client: a #GSocketClient
504  *
505  * Gets the I/O timeout time for sockets created by @client.
506  *
507  * See g_socket_client_set_timeout() for details.
508  *
509  * Returns: the timeout in seconds
510  *
511  * Since: 2.26
512  */
513 guint
514 g_socket_client_get_timeout (GSocketClient *client)
515 {
516   return client->priv->timeout;
517 }
518
519
520 /**
521  * g_socket_client_set_timeout:
522  * @client: a #GSocketClient.
523  * @timeout: the timeout
524  *
525  * Sets the I/O timeout for sockets created by @client. @timeout is a
526  * time in seconds, or 0 for no timeout (the default).
527  *
528  * The timeout value affects the initial connection attempt as well,
529  * so setting this may cause calls to g_socket_client_connect(), etc,
530  * to fail with %G_IO_ERROR_TIMED_OUT.
531  *
532  * Since: 2.26
533  */
534 void
535 g_socket_client_set_timeout (GSocketClient *client,
536                              guint          timeout)
537 {
538   if (client->priv->timeout == timeout)
539     return;
540
541   client->priv->timeout = timeout;
542   g_object_notify (G_OBJECT (client), "timeout");
543 }
544
545 /**
546  * g_socket_client_get_enable_proxy:
547  * @client: a #GSocketClient.
548  *
549  * Gets the proxy enable state; see g_socket_client_set_enable_proxy()
550  *
551  * Returns: whether proxying is enabled
552  *
553  * Since: 2.26
554  */
555 gboolean
556 g_socket_client_get_enable_proxy (GSocketClient *client)
557 {
558   return client->priv->enable_proxy;
559 }
560
561 /**
562  * g_socket_client_set_enable_proxy:
563  * @client: a #GSocketClient.
564  * @enable: whether to enable proxies
565  *
566  * Sets whether or not @client attempts to make connections via a
567  * proxy server. When enabled (the default), #GSocketClient will use a
568  * #GProxyResolver to determine if a proxy protocol such as SOCKS is
569  * needed, and automatically do the necessary proxy negotiation.
570  *
571  * Since: 2.26
572  */
573 void
574 g_socket_client_set_enable_proxy (GSocketClient *client,
575                                   gboolean       enable)
576 {
577   enable = !!enable;
578   if (client->priv->enable_proxy == enable)
579     return;
580
581   client->priv->enable_proxy = enable;
582   g_object_notify (G_OBJECT (client), "enable-proxy");
583 }
584
585 /**
586  * g_socket_client_get_tls:
587  * @client: a #GSocketClient.
588  *
589  * Gets whether @client creates TLS connections. See
590  * g_socket_client_set_tls() for details.
591  *
592  * Returns: whether @client uses TLS
593  *
594  * Since: 2.28
595  */
596 gboolean
597 g_socket_client_get_tls (GSocketClient *client)
598 {
599   return client->priv->tls;
600 }
601
602 /**
603  * g_socket_client_set_tls:
604  * @client: a #GSocketClient.
605  * @tls: whether to use TLS
606  *
607  * Sets whether @client creates TLS (aka SSL) connections. If @tls is
608  * %TRUE, @client will wrap its connections in a #GTlsClientConnection
609  * and perform a TLS handshake when connecting.
610  *
611  * Note that since #GSocketClient must return a #GSocketConnection,
612  * but #GTlsClientConnection is not a #GSocketConnection, this
613  * actually wraps the resulting #GTlsClientConnection in a
614  * #GTcpWrapperConnection when returning it. You can use
615  * g_tcp_wrapper_connection_get_base_io_stream() on the return value
616  * to extract the #GTlsClientConnection.
617  *
618  * Since: 2.28
619  */
620 void
621 g_socket_client_set_tls (GSocketClient *client,
622                          gboolean       tls)
623 {
624   tls = !!tls;
625   if (tls == client->priv->tls)
626     return;
627
628   client->priv->tls = tls;
629   g_object_notify (G_OBJECT (client), "tls");
630 }
631
632 /**
633  * g_socket_client_get_tls_validation_flags:
634  * @client: a #GSocketClient.
635  *
636  * Gets the TLS validation flags used creating TLS connections via
637  * @client.
638  *
639  * Returns: the TLS validation flags
640  *
641  * Since: 2.28
642  */
643 GTlsCertificateFlags
644 g_socket_client_get_tls_validation_flags (GSocketClient *client)
645 {
646   return client->priv->tls_validation_flags;
647 }
648
649 /**
650  * g_socket_client_set_tls_validation_flags:
651  * @client: a #GSocketClient.
652  * @flags: the validation flags
653  *
654  * Sets the TLS validation flags used when creating TLS connections
655  * via @client. The default value is %G_TLS_CERTIFICATE_VALIDATE_ALL.
656  *
657  * Since: 2.28
658  */
659 void
660 g_socket_client_set_tls_validation_flags (GSocketClient        *client,
661                                           GTlsCertificateFlags  flags)
662 {
663   if (client->priv->tls_validation_flags != flags)
664     {
665       client->priv->tls_validation_flags = flags;
666       g_object_notify (G_OBJECT (client), "tls-validation-flags");
667     }
668 }
669
670 static void
671 g_socket_client_class_init (GSocketClientClass *class)
672 {
673   GObjectClass *gobject_class = G_OBJECT_CLASS (class);
674
675   g_type_class_add_private (class, sizeof (GSocketClientPrivate));
676
677   gobject_class->finalize = g_socket_client_finalize;
678   gobject_class->set_property = g_socket_client_set_property;
679   gobject_class->get_property = g_socket_client_get_property;
680
681   g_object_class_install_property (gobject_class, PROP_FAMILY,
682                                    g_param_spec_enum ("family",
683                                                       P_("Socket family"),
684                                                       P_("The sockets address family to use for socket construction"),
685                                                       G_TYPE_SOCKET_FAMILY,
686                                                       G_SOCKET_FAMILY_INVALID,
687                                                       G_PARAM_CONSTRUCT |
688                                                       G_PARAM_READWRITE |
689                                                       G_PARAM_STATIC_STRINGS));
690
691   g_object_class_install_property (gobject_class, PROP_TYPE,
692                                    g_param_spec_enum ("type",
693                                                       P_("Socket type"),
694                                                       P_("The sockets type to use for socket construction"),
695                                                       G_TYPE_SOCKET_TYPE,
696                                                       G_SOCKET_TYPE_STREAM,
697                                                       G_PARAM_CONSTRUCT |
698                                                       G_PARAM_READWRITE |
699                                                       G_PARAM_STATIC_STRINGS));
700
701   g_object_class_install_property (gobject_class, PROP_PROTOCOL,
702                                    g_param_spec_enum ("protocol",
703                                                       P_("Socket protocol"),
704                                                       P_("The protocol to use for socket construction, or 0 for default"),
705                                                       G_TYPE_SOCKET_PROTOCOL,
706                                                       G_SOCKET_PROTOCOL_DEFAULT,
707                                                       G_PARAM_CONSTRUCT |
708                                                       G_PARAM_READWRITE |
709                                                       G_PARAM_STATIC_STRINGS));
710
711   g_object_class_install_property (gobject_class, PROP_LOCAL_ADDRESS,
712                                    g_param_spec_object ("local-address",
713                                                         P_("Local address"),
714                                                         P_("The local address constructed sockets will be bound to"),
715                                                         G_TYPE_SOCKET_ADDRESS,
716                                                         G_PARAM_CONSTRUCT |
717                                                         G_PARAM_READWRITE |
718                                                         G_PARAM_STATIC_STRINGS));
719
720   g_object_class_install_property (gobject_class, PROP_TIMEOUT,
721                                    g_param_spec_uint ("timeout",
722                                                       P_("Socket timeout"),
723                                                       P_("The I/O timeout for sockets, or 0 for none"),
724                                                       0, G_MAXUINT, 0,
725                                                       G_PARAM_CONSTRUCT |
726                                                       G_PARAM_READWRITE |
727                                                       G_PARAM_STATIC_STRINGS));
728
729    g_object_class_install_property (gobject_class, PROP_ENABLE_PROXY,
730                                     g_param_spec_boolean ("enable-proxy",
731                                                           P_("Enable proxy"),
732                                                           P_("Enable proxy support"),
733                                                           TRUE,
734                                                           G_PARAM_CONSTRUCT |
735                                                           G_PARAM_READWRITE |
736                                                           G_PARAM_STATIC_STRINGS));
737
738   g_object_class_install_property (gobject_class, PROP_TLS,
739                                    g_param_spec_boolean ("tls",
740                                                          P_("TLS"),
741                                                          P_("Whether to create TLS connections"),
742                                                          FALSE,
743                                                          G_PARAM_CONSTRUCT |
744                                                          G_PARAM_READWRITE |
745                                                          G_PARAM_STATIC_STRINGS));
746   g_object_class_install_property (gobject_class, PROP_TLS_VALIDATION_FLAGS,
747                                    g_param_spec_flags ("tls-validation-flags",
748                                                        P_("TLS validation flags"),
749                                                        P_("TLS validation flags to use"),
750                                                        G_TYPE_TLS_CERTIFICATE_FLAGS,
751                                                        G_TLS_CERTIFICATE_VALIDATE_ALL,
752                                                        G_PARAM_CONSTRUCT |
753                                                        G_PARAM_READWRITE |
754                                                        G_PARAM_STATIC_STRINGS));
755 }
756
757 /**
758  * g_socket_client_connect:
759  * @client: a #GSocketClient.
760  * @connectable: a #GSocketConnectable specifying the remote address.
761  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
762  * @error: #GError for error reporting, or %NULL to ignore.
763  *
764  * Tries to resolve the @connectable and make a network connection to it.
765  *
766  * Upon a successful connection, a new #GSocketConnection is constructed
767  * and returned.  The caller owns this new object and must drop their
768  * reference to it when finished with it.
769  *
770  * The type of the #GSocketConnection object returned depends on the type of
771  * the underlying socket that is used. For instance, for a TCP/IP connection
772  * it will be a #GTcpConnection.
773  *
774  * The socket created will be the same family as the address that the
775  * @connectable resolves to, unless family is set with g_socket_client_set_family()
776  * or indirectly via g_socket_client_set_local_address(). The socket type
777  * defaults to %G_SOCKET_TYPE_STREAM but can be set with
778  * g_socket_client_set_socket_type().
779  *
780  * If a local address is specified with g_socket_client_set_local_address() the
781  * socket will be bound to this address before connecting.
782  *
783  * Returns: (transfer full): a #GSocketConnection on success, %NULL on error.
784  *
785  * Since: 2.22
786  */
787 GSocketConnection *
788 g_socket_client_connect (GSocketClient       *client,
789                          GSocketConnectable  *connectable,
790                          GCancellable        *cancellable,
791                          GError             **error)
792 {
793   GIOStream *connection = NULL;
794   GSocketAddressEnumerator *enumerator = NULL;
795   GError *last_error, *tmp_error;
796
797   last_error = NULL;
798
799   if (can_use_proxy (client))
800     enumerator = g_socket_connectable_proxy_enumerate (connectable);
801   else
802     enumerator = g_socket_connectable_enumerate (connectable);
803
804   while (connection == NULL)
805     {
806       GSocketAddress *address = NULL;
807       gboolean application_proxy = FALSE;
808       GSocket *socket;
809
810       if (g_cancellable_is_cancelled (cancellable))
811         {
812           g_clear_error (error);
813           g_cancellable_set_error_if_cancelled (cancellable, error);
814           break;
815         }
816
817       tmp_error = NULL;
818       address = g_socket_address_enumerator_next (enumerator, cancellable,
819                                                   &tmp_error);
820
821       if (address == NULL)
822         {
823           if (tmp_error)
824             {
825               g_clear_error (&last_error);
826               g_propagate_error (error, tmp_error);
827             }
828           else if (last_error)
829             {
830               g_propagate_error (error, last_error);
831             }
832           else
833             g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
834                                  _("Unknown error on connect"));
835           break;
836         }
837
838       /* clear error from previous attempt */
839       g_clear_error (&last_error);
840
841       socket = create_socket (client, address, &last_error);
842       if (socket == NULL)
843         {
844           g_object_unref (address);
845           continue;
846         }
847
848       connection = (GIOStream *)g_socket_connection_factory_create_connection (socket);
849       if (!g_socket_connection_connect (G_SOCKET_CONNECTION (connection),
850                                         address, cancellable, &last_error))
851         {
852           clarify_connect_error (last_error, connectable, address);
853           g_object_unref (connection);
854           connection = NULL;
855         }
856
857       if (connection &&
858           G_IS_PROXY_ADDRESS (address) &&
859           client->priv->enable_proxy)
860         {
861           GProxyAddress *proxy_addr = G_PROXY_ADDRESS (address);
862           const gchar *protocol;
863           GProxy *proxy;
864
865           protocol = g_proxy_address_get_protocol (proxy_addr);
866           proxy = g_proxy_get_default_for_protocol (protocol);
867
868           /* The connection should not be anything else then TCP Connection,
869            * but let's put a safety guard in case
870            */
871           if (!G_IS_TCP_CONNECTION (connection))
872             {
873               g_critical ("Trying to proxy over non-TCP connection, this is "
874                           "most likely a bug in GLib IO library.");
875
876               g_set_error_literal (&last_error,
877                   G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
878                   _("Trying to proxy over non-TCP connection is not supported."));
879
880               g_object_unref (connection);
881               connection = NULL;
882             }
883           else if (proxy)
884             {
885               GIOStream *proxy_connection;
886
887               proxy_connection = g_proxy_connect (proxy,
888                                                   connection,
889                                                   proxy_addr,
890                                                   cancellable,
891                                                   &last_error);
892               g_object_unref (connection);
893               connection = proxy_connection;
894               g_object_unref (proxy);
895             }
896           else if (!g_hash_table_lookup_extended (client->priv->app_proxies,
897                                                   protocol, NULL, NULL))
898             {
899               g_set_error (&last_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
900                            _("Proxy protocol '%s' is not supported."),
901                            protocol);
902               g_object_unref (connection);
903               connection = NULL;
904             }
905           else
906             {
907               application_proxy = TRUE;
908             }
909         }
910
911       if (!application_proxy && connection && client->priv->tls)
912         {
913           GIOStream *tlsconn;
914
915           tlsconn = g_tls_client_connection_new (connection, connectable, &last_error);
916           g_object_unref (connection);
917           connection = tlsconn;
918
919           if (tlsconn)
920             {
921               g_tls_client_connection_set_validation_flags (G_TLS_CLIENT_CONNECTION (tlsconn),
922                                                             client->priv->tls_validation_flags);
923               if (!g_tls_connection_handshake (G_TLS_CONNECTION (tlsconn),
924                                                cancellable, &last_error))
925                 {
926                   g_object_unref (tlsconn);
927                   connection = NULL;
928                 }
929             }
930         }
931
932       if (connection && !G_IS_SOCKET_CONNECTION (connection))
933         {
934           GSocketConnection *wrapper_connection;
935
936           wrapper_connection = g_tcp_wrapper_connection_new (connection, socket);
937           g_object_unref (connection);
938           connection = (GIOStream *)wrapper_connection;
939         }
940
941       g_object_unref (socket);
942       g_object_unref (address);
943     }
944   g_object_unref (enumerator);
945
946   return G_SOCKET_CONNECTION (connection);
947 }
948
949 /**
950  * g_socket_client_connect_to_host:
951  * @client: a #GSocketClient
952  * @host_and_port: the name and optionally port of the host to connect to
953  * @default_port: the default port to connect to
954  * @cancellable: (allow-none): a #GCancellable, or %NULL
955  * @error: a pointer to a #GError, or %NULL
956  *
957  * This is a helper function for g_socket_client_connect().
958  *
959  * Attempts to create a TCP connection to the named host.
960  *
961  * @host_and_port may be in any of a number of recognized formats; an IPv6
962  * address, an IPv4 address, or a domain name (in which case a DNS
963  * lookup is performed).  Quoting with [] is supported for all address
964  * types.  A port override may be specified in the usual way with a
965  * colon.  Ports may be given as decimal numbers or symbolic names (in
966  * which case an /etc/services lookup is performed).
967  *
968  * If no port override is given in @host_and_port then @default_port will be
969  * used as the port number to connect to.
970  *
971  * In general, @host_and_port is expected to be provided by the user (allowing
972  * them to give the hostname, and a port override if necessary) and
973  * @default_port is expected to be provided by the application.
974  *
975  * In the case that an IP address is given, a single connection
976  * attempt is made.  In the case that a name is given, multiple
977  * connection attempts may be made, in turn and according to the
978  * number of address records in DNS, until a connection succeeds.
979  *
980  * Upon a successful connection, a new #GSocketConnection is constructed
981  * and returned.  The caller owns this new object and must drop their
982  * reference to it when finished with it.
983  *
984  * In the event of any failure (DNS error, service not found, no hosts
985  * connectable) %NULL is returned and @error (if non-%NULL) is set
986  * accordingly.
987  *
988  * Returns: (transfer full): a #GSocketConnection on success, %NULL on error.
989  *
990  * Since: 2.22
991  */
992 GSocketConnection *
993 g_socket_client_connect_to_host (GSocketClient  *client,
994                                  const gchar    *host_and_port,
995                                  guint16         default_port,
996                                  GCancellable   *cancellable,
997                                  GError        **error)
998 {
999   GSocketConnectable *connectable;
1000   GSocketConnection *connection;
1001
1002   connectable = g_network_address_parse (host_and_port, default_port, error);
1003   if (connectable == NULL)
1004     return NULL;
1005
1006   connection = g_socket_client_connect (client, connectable,
1007                                         cancellable, error);
1008   g_object_unref (connectable);
1009
1010   return connection;
1011 }
1012
1013 /**
1014  * g_socket_client_connect_to_service:
1015  * @client: a #GSocketConnection
1016  * @domain: a domain name
1017  * @service: the name of the service to connect to
1018  * @cancellable: (allow-none): a #GCancellable, or %NULL
1019  * @error: a pointer to a #GError, or %NULL
1020  *
1021  * Attempts to create a TCP connection to a service.
1022  *
1023  * This call looks up the SRV record for @service at @domain for the
1024  * "tcp" protocol.  It then attempts to connect, in turn, to each of
1025  * the hosts providing the service until either a connection succeeds
1026  * or there are no hosts remaining.
1027  *
1028  * Upon a successful connection, a new #GSocketConnection is constructed
1029  * and returned.  The caller owns this new object and must drop their
1030  * reference to it when finished with it.
1031  *
1032  * In the event of any failure (DNS error, service not found, no hosts
1033  * connectable) %NULL is returned and @error (if non-%NULL) is set
1034  * accordingly.
1035  *
1036  * Returns: (transfer full): a #GSocketConnection if successful, or %NULL on error
1037  */
1038 GSocketConnection *
1039 g_socket_client_connect_to_service (GSocketClient  *client,
1040                                     const gchar    *domain,
1041                                     const gchar    *service,
1042                                     GCancellable   *cancellable,
1043                                     GError        **error)
1044 {
1045   GSocketConnectable *connectable;
1046   GSocketConnection *connection;
1047
1048   connectable = g_network_service_new (service, "tcp", domain);
1049   connection = g_socket_client_connect (client, connectable,
1050                                         cancellable, error);
1051   g_object_unref (connectable);
1052
1053   return connection;
1054 }
1055
1056 /**
1057  * g_socket_client_connect_to_uri:
1058  * @client: a #GSocketClient
1059  * @uri: A network URI
1060  * @default_port: the default port to connect to
1061  * @cancellable: (allow-none): a #GCancellable, or %NULL
1062  * @error: a pointer to a #GError, or %NULL
1063  *
1064  * This is a helper function for g_socket_client_connect().
1065  *
1066  * Attempts to create a TCP connection with a network URI.
1067  *
1068  * @uri may be any valid URI containing an "authority" (hostname/port)
1069  * component. If a port is not specified in the URI, @default_port
1070  * will be used. TLS will be negotiated if #GSocketClient:tls is %TRUE.
1071  * (#GSocketClient does not know to automatically assume TLS for
1072  * certain URI schemes.)
1073  *
1074  * Using this rather than g_socket_client_connect() or
1075  * g_socket_client_connect_to_host() allows #GSocketClient to
1076  * determine when to use application-specific proxy protocols.
1077  *
1078  * Upon a successful connection, a new #GSocketConnection is constructed
1079  * and returned.  The caller owns this new object and must drop their
1080  * reference to it when finished with it.
1081  *
1082  * In the event of any failure (DNS error, service not found, no hosts
1083  * connectable) %NULL is returned and @error (if non-%NULL) is set
1084  * accordingly.
1085  *
1086  * Returns: (transfer full): a #GSocketConnection on success, %NULL on error.
1087  *
1088  * Since: 2.26
1089  */
1090 GSocketConnection *
1091 g_socket_client_connect_to_uri (GSocketClient  *client,
1092                                 const gchar    *uri,
1093                                 guint16         default_port,
1094                                 GCancellable   *cancellable,
1095                                 GError        **error)
1096 {
1097   GSocketConnectable *connectable;
1098   GSocketConnection *connection;
1099
1100   connectable = g_network_address_parse_uri (uri, default_port, error);
1101   if (connectable == NULL)
1102     return NULL;
1103
1104   connection = g_socket_client_connect (client, connectable,
1105                                         cancellable, error);
1106   g_object_unref (connectable);
1107
1108   return connection;
1109 }
1110
1111 typedef struct
1112 {
1113   GSimpleAsyncResult *result;
1114   GCancellable *cancellable;
1115   GSocketClient *client;
1116
1117   GSocketConnectable *connectable;
1118   GSocketAddressEnumerator *enumerator;
1119   GProxyAddress *proxy_addr;
1120   GSocketAddress *current_addr;
1121   GSocket *current_socket;
1122   GIOStream *connection;
1123
1124   GError *last_error;
1125 } GSocketClientAsyncConnectData;
1126
1127 static void
1128 g_socket_client_async_connect_complete (GSocketClientAsyncConnectData *data)
1129 {
1130   if (data->last_error)
1131     {
1132       g_simple_async_result_take_error (data->result, data->last_error);
1133     }
1134   else
1135     {
1136       g_assert (data->connection);
1137
1138       if (!G_IS_SOCKET_CONNECTION (data->connection))
1139         {
1140           GSocketConnection *wrapper_connection;
1141
1142           wrapper_connection = g_tcp_wrapper_connection_new (data->connection,
1143                                                              data->current_socket);
1144           g_object_unref (data->connection);
1145           data->connection = (GIOStream *)wrapper_connection;
1146         }
1147
1148       g_simple_async_result_set_op_res_gpointer (data->result,
1149                                                  data->connection,
1150                                                  g_object_unref);
1151     }
1152
1153   g_simple_async_result_complete (data->result);
1154   g_object_unref (data->result);
1155   g_object_unref (data->connectable);
1156   g_object_unref (data->enumerator);
1157   if (data->cancellable)
1158     g_object_unref (data->cancellable);
1159   if (data->current_addr)
1160     g_object_unref (data->current_addr);
1161   if (data->current_socket)
1162     g_object_unref (data->current_socket);
1163   if (data->proxy_addr)
1164     g_object_unref (data->proxy_addr);
1165   g_slice_free (GSocketClientAsyncConnectData, data);
1166 }
1167
1168
1169 static void
1170 g_socket_client_enumerator_callback (GObject      *object,
1171                                      GAsyncResult *result,
1172                                      gpointer      user_data);
1173
1174 static void
1175 set_last_error (GSocketClientAsyncConnectData *data,
1176                 GError *error)
1177 {
1178   g_clear_error (&data->last_error);
1179   data->last_error = error;
1180 }
1181
1182 static void
1183 enumerator_next_async (GSocketClientAsyncConnectData *data)
1184 {
1185   /* We need to cleanup the state */
1186   g_clear_object (&data->current_socket);
1187   g_clear_object (&data->current_addr);
1188   g_clear_object (&data->proxy_addr);
1189   g_clear_object (&data->connection);
1190
1191   g_socket_address_enumerator_next_async (data->enumerator,
1192                                           data->cancellable,
1193                                           g_socket_client_enumerator_callback,
1194                                           data);
1195 }
1196
1197 static void
1198 g_socket_client_tls_handshake_callback (GObject      *object,
1199                                         GAsyncResult *result,
1200                                         gpointer      user_data)
1201 {
1202   GSocketClientAsyncConnectData *data = user_data;
1203
1204   if (g_tls_connection_handshake_finish (G_TLS_CONNECTION (object),
1205                                          result,
1206                                          &data->last_error))
1207     {
1208       g_object_unref (data->connection);
1209       data->connection = G_IO_STREAM (object);
1210
1211       g_socket_client_async_connect_complete (data);
1212     }
1213   else
1214     {
1215       g_object_unref (object);
1216       enumerator_next_async (data);
1217     }
1218 }
1219
1220 static void
1221 g_socket_client_tls_handshake (GSocketClientAsyncConnectData *data)
1222 {
1223   GIOStream *tlsconn;
1224
1225   if (!data->client->priv->tls)
1226     {
1227       g_socket_client_async_connect_complete (data);
1228       return;
1229     }
1230
1231   tlsconn = g_tls_client_connection_new (data->connection,
1232                                          data->connectable,
1233                                          &data->last_error);
1234   if (tlsconn)
1235     {
1236       g_tls_client_connection_set_validation_flags (G_TLS_CLIENT_CONNECTION (tlsconn),
1237                                                     data->client->priv->tls_validation_flags);
1238       g_tls_connection_handshake_async (G_TLS_CONNECTION (tlsconn),
1239                                         G_PRIORITY_DEFAULT,
1240                                         data->cancellable,
1241                                         g_socket_client_tls_handshake_callback,
1242                                         data);
1243     }
1244   else
1245     {
1246       enumerator_next_async (data);
1247     }
1248 }
1249
1250 static void
1251 g_socket_client_proxy_connect_callback (GObject      *object,
1252                                         GAsyncResult *result,
1253                                         gpointer      user_data)
1254 {
1255   GSocketClientAsyncConnectData *data = user_data;
1256
1257   g_object_unref (data->connection);
1258   data->connection = g_proxy_connect_finish (G_PROXY (object),
1259                                              result,
1260                                              &data->last_error);
1261   if (!data->connection)
1262     {
1263       enumerator_next_async (data);
1264       return;
1265     }
1266
1267   g_socket_client_tls_handshake (data);
1268 }
1269
1270 static void
1271 g_socket_client_connected_callback (GObject      *source,
1272                                     GAsyncResult *result,
1273                                     gpointer      user_data)
1274 {
1275   GSocketClientAsyncConnectData *data = user_data;
1276   GError *error = NULL;
1277   GProxy *proxy;
1278   const gchar *protocol;
1279
1280   if (!g_socket_connection_connect_finish (G_SOCKET_CONNECTION (source),
1281                                            result, &error))
1282     {
1283       clarify_connect_error (error, data->connectable,
1284                              data->current_addr);
1285       set_last_error (data, error);
1286
1287       /* try next one */
1288       enumerator_next_async (data);
1289       return;
1290     }
1291
1292   /* wrong, but backward compatible */
1293   g_socket_set_blocking (data->current_socket, TRUE);
1294
1295   if (!data->proxy_addr)
1296     {
1297       g_socket_client_tls_handshake (data);
1298       return;
1299     }
1300
1301   protocol  = g_proxy_address_get_protocol (data->proxy_addr);
1302   proxy = g_proxy_get_default_for_protocol (protocol);
1303
1304   /* The connection should not be anything other than TCP,
1305    * but let's put a safety guard in case
1306    */
1307   if (!G_IS_TCP_CONNECTION (data->connection))
1308     {
1309       g_critical ("Trying to proxy over non-TCP connection, this is "
1310           "most likely a bug in GLib IO library.");
1311
1312       g_set_error_literal (&data->last_error,
1313           G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
1314           _("Trying to proxy over non-TCP connection is not supported."));
1315
1316       enumerator_next_async (data);
1317     }
1318   else if (proxy)
1319     {
1320       g_proxy_connect_async (proxy,
1321                              data->connection,
1322                              data->proxy_addr,
1323                              data->cancellable,
1324                              g_socket_client_proxy_connect_callback,
1325                              data);
1326       g_object_unref (proxy);
1327     }
1328   else if (!g_hash_table_lookup_extended (data->client->priv->app_proxies,
1329                                           protocol, NULL, NULL))
1330     {
1331       g_clear_error (&data->last_error);
1332
1333       g_set_error (&data->last_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
1334           _("Proxy protocol '%s' is not supported."),
1335           protocol);
1336
1337       enumerator_next_async (data);
1338     }
1339   else
1340     {
1341       /* Simply complete the connection, we don't want to do TLS handshake
1342        * as the application proxy handling may need proxy handshake first */
1343       g_socket_client_async_connect_complete (data);
1344     }
1345 }
1346
1347 static void
1348 g_socket_client_enumerator_callback (GObject      *object,
1349                                      GAsyncResult *result,
1350                                      gpointer      user_data)
1351 {
1352   GSocketClientAsyncConnectData *data = user_data;
1353   GSocketAddress *address = NULL;
1354   GSocket *socket;
1355   GError *tmp_error = NULL;
1356
1357   if (g_cancellable_is_cancelled (data->cancellable))
1358     {
1359       g_clear_error (&data->last_error);
1360       g_cancellable_set_error_if_cancelled (data->cancellable, &data->last_error);
1361       g_socket_client_async_connect_complete (data);
1362       return;
1363     }
1364
1365   address = g_socket_address_enumerator_next_finish (data->enumerator,
1366                                                      result, &tmp_error);
1367
1368   if (address == NULL)
1369     {
1370       if (tmp_error)
1371         set_last_error (data, tmp_error);
1372       else if (data->last_error == NULL)
1373         g_set_error_literal (&data->last_error, G_IO_ERROR, G_IO_ERROR_FAILED,
1374                              _("Unknown error on connect"));
1375
1376       g_socket_client_async_connect_complete (data);
1377       return;
1378     }
1379
1380   if (G_IS_PROXY_ADDRESS (address) &&
1381       data->client->priv->enable_proxy)
1382     data->proxy_addr = g_object_ref (G_PROXY_ADDRESS (address));
1383
1384   g_clear_error (&data->last_error);
1385
1386   socket = create_socket (data->client, address, &data->last_error);
1387   if (socket == NULL)
1388     {
1389       g_object_unref (address);
1390       enumerator_next_async (data);
1391       return;
1392     }
1393
1394   data->current_socket = socket;
1395   data->current_addr = address;
1396   data->connection = (GIOStream *) g_socket_connection_factory_create_connection (socket);
1397
1398   g_socket_connection_connect_async (G_SOCKET_CONNECTION (data->connection),
1399                                      address, data->cancellable,
1400                                      g_socket_client_connected_callback, data);
1401 }
1402
1403 /**
1404  * g_socket_client_connect_async:
1405  * @client: a #GSocketClient
1406  * @connectable: a #GSocketConnectable specifying the remote address.
1407  * @cancellable: (allow-none): a #GCancellable, or %NULL
1408  * @callback: (scope async): a #GAsyncReadyCallback
1409  * @user_data: (closure): user data for the callback
1410  *
1411  * This is the asynchronous version of g_socket_client_connect().
1412  *
1413  * When the operation is finished @callback will be
1414  * called. You can then call g_socket_client_connect_finish() to get
1415  * the result of the operation.
1416  *
1417  * Since: 2.22
1418  */
1419 void
1420 g_socket_client_connect_async (GSocketClient       *client,
1421                                GSocketConnectable  *connectable,
1422                                GCancellable        *cancellable,
1423                                GAsyncReadyCallback  callback,
1424                                gpointer             user_data)
1425 {
1426   GSocketClientAsyncConnectData *data;
1427
1428   g_return_if_fail (G_IS_SOCKET_CLIENT (client));
1429
1430   data = g_slice_new0 (GSocketClientAsyncConnectData);
1431
1432   data->result = g_simple_async_result_new (G_OBJECT (client),
1433                                             callback, user_data,
1434                                             g_socket_client_connect_async);
1435   data->client = client;
1436   if (cancellable)
1437     data->cancellable = g_object_ref (cancellable);
1438   else
1439     data->cancellable = NULL;
1440   data->last_error = NULL;
1441   data->connectable = g_object_ref (connectable);
1442
1443   if (can_use_proxy (client))
1444       data->enumerator = g_socket_connectable_proxy_enumerate (connectable);
1445   else
1446       data->enumerator = g_socket_connectable_enumerate (connectable);
1447
1448   enumerator_next_async (data);
1449 }
1450
1451 /**
1452  * g_socket_client_connect_to_host_async:
1453  * @client: a #GSocketClient
1454  * @host_and_port: the name and optionally the port of the host to connect to
1455  * @default_port: the default port to connect to
1456  * @cancellable: (allow-none): a #GCancellable, or %NULL
1457  * @callback: (scope async): a #GAsyncReadyCallback
1458  * @user_data: (closure): user data for the callback
1459  *
1460  * This is the asynchronous version of g_socket_client_connect_to_host().
1461  *
1462  * When the operation is finished @callback will be
1463  * called. You can then call g_socket_client_connect_to_host_finish() to get
1464  * the result of the operation.
1465  *
1466  * Since: 2.22
1467  */
1468 void
1469 g_socket_client_connect_to_host_async (GSocketClient        *client,
1470                                        const gchar          *host_and_port,
1471                                        guint16               default_port,
1472                                        GCancellable         *cancellable,
1473                                        GAsyncReadyCallback   callback,
1474                                        gpointer              user_data)
1475 {
1476   GSocketConnectable *connectable;
1477   GError *error;
1478
1479   error = NULL;
1480   connectable = g_network_address_parse (host_and_port, default_port,
1481                                          &error);
1482   if (connectable == NULL)
1483     {
1484       g_simple_async_report_take_gerror_in_idle (G_OBJECT (client),
1485                                             callback, user_data, error);
1486     }
1487   else
1488     {
1489       g_socket_client_connect_async (client,
1490                                      connectable, cancellable,
1491                                      callback, user_data);
1492       g_object_unref (connectable);
1493     }
1494 }
1495
1496 /**
1497  * g_socket_client_connect_to_service_async:
1498  * @client: a #GSocketClient
1499  * @domain: a domain name
1500  * @service: the name of the service to connect to
1501  * @cancellable: (allow-none): a #GCancellable, or %NULL
1502  * @callback: (scope async): a #GAsyncReadyCallback
1503  * @user_data: (closure): user data for the callback
1504  *
1505  * This is the asynchronous version of
1506  * g_socket_client_connect_to_service().
1507  *
1508  * Since: 2.22
1509  */
1510 void
1511 g_socket_client_connect_to_service_async (GSocketClient       *client,
1512                                           const gchar         *domain,
1513                                           const gchar         *service,
1514                                           GCancellable        *cancellable,
1515                                           GAsyncReadyCallback  callback,
1516                                           gpointer             user_data)
1517 {
1518   GSocketConnectable *connectable;
1519
1520   connectable = g_network_service_new (service, "tcp", domain);
1521   g_socket_client_connect_async (client,
1522                                  connectable, cancellable,
1523                                  callback, user_data);
1524   g_object_unref (connectable);
1525 }
1526
1527 /**
1528  * g_socket_client_connect_to_uri_async:
1529  * @client: a #GSocketClient
1530  * @uri: a network uri
1531  * @default_port: the default port to connect to
1532  * @cancellable: (allow-none): a #GCancellable, or %NULL
1533  * @callback: (scope async): a #GAsyncReadyCallback
1534  * @user_data: (closure): user data for the callback
1535  *
1536  * This is the asynchronous version of g_socket_client_connect_to_uri().
1537  *
1538  * When the operation is finished @callback will be
1539  * called. You can then call g_socket_client_connect_to_uri_finish() to get
1540  * the result of the operation.
1541  *
1542  * Since: 2.26
1543  */
1544 void
1545 g_socket_client_connect_to_uri_async (GSocketClient        *client,
1546                                       const gchar          *uri,
1547                                       guint16               default_port,
1548                                       GCancellable         *cancellable,
1549                                       GAsyncReadyCallback   callback,
1550                                       gpointer              user_data)
1551 {
1552   GSocketConnectable *connectable;
1553   GError *error;
1554
1555   error = NULL;
1556   connectable = g_network_address_parse_uri (uri, default_port, &error);
1557   if (connectable == NULL)
1558     {
1559       g_simple_async_report_take_gerror_in_idle (G_OBJECT (client),
1560                                             callback, user_data, error);
1561     }
1562   else
1563     {
1564       g_socket_client_connect_async (client,
1565                                      connectable, cancellable,
1566                                      callback, user_data);
1567       g_object_unref (connectable);
1568     }
1569 }
1570
1571
1572 /**
1573  * g_socket_client_connect_finish:
1574  * @client: a #GSocketClient.
1575  * @result: a #GAsyncResult.
1576  * @error: a #GError location to store the error occurring, or %NULL to
1577  * ignore.
1578  *
1579  * Finishes an async connect operation. See g_socket_client_connect_async()
1580  *
1581  * Returns: (transfer full): a #GSocketConnection on success, %NULL on error.
1582  *
1583  * Since: 2.22
1584  */
1585 GSocketConnection *
1586 g_socket_client_connect_finish (GSocketClient  *client,
1587                                 GAsyncResult   *result,
1588                                 GError        **error)
1589 {
1590   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
1591
1592   if (g_simple_async_result_propagate_error (simple, error))
1593     return NULL;
1594
1595   return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
1596 }
1597
1598 /**
1599  * g_socket_client_connect_to_host_finish:
1600  * @client: a #GSocketClient.
1601  * @result: a #GAsyncResult.
1602  * @error: a #GError location to store the error occurring, or %NULL to
1603  * ignore.
1604  *
1605  * Finishes an async connect operation. See g_socket_client_connect_to_host_async()
1606  *
1607  * Returns: (transfer full): a #GSocketConnection on success, %NULL on error.
1608  *
1609  * Since: 2.22
1610  */
1611 GSocketConnection *
1612 g_socket_client_connect_to_host_finish (GSocketClient  *client,
1613                                         GAsyncResult   *result,
1614                                         GError        **error)
1615 {
1616   return g_socket_client_connect_finish (client, result, error);
1617 }
1618
1619 /**
1620  * g_socket_client_connect_to_service_finish:
1621  * @client: a #GSocketClient.
1622  * @result: a #GAsyncResult.
1623  * @error: a #GError location to store the error occurring, or %NULL to
1624  * ignore.
1625  *
1626  * Finishes an async connect operation. See g_socket_client_connect_to_service_async()
1627  *
1628  * Returns: (transfer full): a #GSocketConnection on success, %NULL on error.
1629  *
1630  * Since: 2.22
1631  */
1632 GSocketConnection *
1633 g_socket_client_connect_to_service_finish (GSocketClient  *client,
1634                                            GAsyncResult   *result,
1635                                            GError        **error)
1636 {
1637   return g_socket_client_connect_finish (client, result, error);
1638 }
1639
1640 /**
1641  * g_socket_client_connect_to_uri_finish:
1642  * @client: a #GSocketClient.
1643  * @result: a #GAsyncResult.
1644  * @error: a #GError location to store the error occurring, or %NULL to
1645  * ignore.
1646  *
1647  * Finishes an async connect operation. See g_socket_client_connect_to_uri_async()
1648  *
1649  * Returns: (transfer full): a #GSocketConnection on success, %NULL on error.
1650  *
1651  * Since: 2.26
1652  */
1653 GSocketConnection *
1654 g_socket_client_connect_to_uri_finish (GSocketClient  *client,
1655                                        GAsyncResult   *result,
1656                                        GError        **error)
1657 {
1658   return g_socket_client_connect_finish (client, result, error);
1659 }
1660
1661 /**
1662  * g_socket_client_add_application_proxy:
1663  * @client: a #GSocketClient
1664  * @protocol: The proxy protocol
1665  *
1666  * Enable proxy protocols to be handled by the application. When the
1667  * indicated proxy protocol is returned by the #GProxyResolver,
1668  * #GSocketClient will consider this protocol as supported but will
1669  * not try to find a #GProxy instance to handle handshaking. The
1670  * application must check for this case by calling
1671  * g_socket_connection_get_remote_address() on the returned
1672  * #GSocketConnection, and seeing if it's a #GProxyAddress of the
1673  * appropriate type, to determine whether or not it needs to handle
1674  * the proxy handshaking itself.
1675  *
1676  * This should be used for proxy protocols that are dialects of
1677  * another protocol such as HTTP proxy. It also allows cohabitation of
1678  * proxy protocols that are reused between protocols. A good example
1679  * is HTTP. It can be used to proxy HTTP, FTP and Gopher and can also
1680  * be use as generic socket proxy through the HTTP CONNECT method.
1681  *
1682  * When the proxy is detected as being an application proxy, TLS handshake
1683  * will be skipped. This is required to let the application do the proxy
1684  * specific handshake.
1685  */
1686 void
1687 g_socket_client_add_application_proxy (GSocketClient *client,
1688                                        const gchar   *protocol)
1689 {
1690   g_hash_table_insert (client->priv->app_proxies, g_strdup (protocol), NULL);
1691 }