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