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