Remove protocol names, instead use an enum with common protocols
[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
30 #include <gio/gioenumtypes.h>
31 #include <gio/gsocketaddressenumerator.h>
32 #include <gio/gsocketconnectable.h>
33 #include <gio/gsocketconnection.h>
34 #include <gio/gsimpleasyncresult.h>
35 #include <gio/gcancellable.h>
36 #include <gio/gioerror.h>
37 #include <gio/gsocket.h>
38 #include <gio/gnetworkaddress.h>
39 #include <gio/gsocketaddress.h>
40 #include "glibintl.h"
41
42 #include "gioalias.h"
43
44 /**
45  * SECTION:gsocketclient
46  * @short_description: Helper for connecting to a network service
47  * @include: gio/gio.h
48  * @see_also: #GSocketConnection, #GSocketListener
49  *
50  * #GSocketClient is a high-level utility class for connecting to a
51  * network host using a connection oriented socket type.
52  *
53  * You create a #GSocketClient object, set any options you want, then
54  * call a sync or async connect operation, which returns a #GSocketConnection
55  * subclass on success.
56  *
57  * The type of the #GSocketConnection object returned depends on the type of
58  * the underlying socket that is in use. For instance, for a TCP/IP connection
59  * it will be a #GTcpConnection.
60  *
61  * Since: 2.22
62  **/
63
64
65 G_DEFINE_TYPE (GSocketClient, g_socket_client, G_TYPE_OBJECT);
66
67 enum
68 {
69   PROP_NONE,
70   PROP_FAMILY,
71   PROP_TYPE,
72   PROP_PROTOCOL,
73   PROP_LOCAL_ADDRESS
74 };
75
76 struct _GSocketClientPrivate
77 {
78   GSocketFamily family;
79   GSocketType type;
80   GSocketProtocol protocol;
81   GSocketAddress *local_address;
82 };
83
84 static GSocket *
85 create_socket (GSocketClient  *client,
86                GSocketAddress *dest_address,
87                GError        **error)
88 {
89   GSocketFamily family;
90   GSocket *socket;
91
92   family = client->priv->family;
93   if (family == G_SOCKET_FAMILY_INVALID &&
94       client->priv->local_address != NULL)
95     family = g_socket_address_get_family (client->priv->local_address);
96   if (family == G_SOCKET_FAMILY_INVALID)
97     family = g_socket_address_get_family (dest_address);
98
99   socket = g_socket_new (family,
100                          client->priv->type,
101                          client->priv->protocol,
102                          error);
103   if (socket == NULL)
104     return NULL;
105
106   if (client->priv->local_address)
107     {
108       if (!g_socket_bind (socket,
109                           client->priv->local_address,
110                           FALSE,
111                           error))
112         {
113           g_object_unref (socket);
114           return NULL;
115         }
116     }
117
118   return socket;
119 }
120
121 static void
122 g_socket_client_init (GSocketClient *client)
123 {
124   client->priv = G_TYPE_INSTANCE_GET_PRIVATE (client,
125                                               G_TYPE_SOCKET_CLIENT,
126                                               GSocketClientPrivate);
127   client->priv->type = G_SOCKET_TYPE_STREAM;
128 }
129
130 /**
131  * g_socket_client_new:
132  *
133  * Creates a new #GSocketClient with the default options.
134  *
135  * Returns: a #GSocketClient.
136  *     Free the returned object with g_object_unref().
137  *
138  * Since: 2.22
139  **/
140 GSocketClient *
141 g_socket_client_new (void)
142 {
143   return g_object_new (G_TYPE_SOCKET_CLIENT, NULL);
144 }
145
146 static void
147 g_socket_client_finalize (GObject *object)
148 {
149   GSocketClient *client = G_SOCKET_CLIENT (object);
150
151   if (client->priv->local_address)
152     g_object_unref (client->priv->local_address);
153
154   if (G_OBJECT_CLASS (g_socket_client_parent_class)->finalize)
155     (*G_OBJECT_CLASS (g_socket_client_parent_class)->finalize) (object);
156 }
157
158 static void
159 g_socket_client_get_property (GObject    *object,
160                               guint       prop_id,
161                               GValue     *value,
162                               GParamSpec *pspec)
163 {
164   GSocketClient *client = G_SOCKET_CLIENT (object);
165
166   switch (prop_id)
167     {
168       case PROP_FAMILY:
169         g_value_set_enum (value, client->priv->family);
170         break;
171
172       case PROP_TYPE:
173         g_value_set_enum (value, client->priv->type);
174         break;
175
176       case PROP_PROTOCOL:
177         g_value_set_enum (value, client->priv->protocol);
178         break;
179
180       case PROP_LOCAL_ADDRESS:
181         g_value_set_object (value, client->priv->local_address);
182         break;
183
184       default:
185         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
186     }
187 }
188
189 static void
190 g_socket_client_set_property (GObject      *object,
191                               guint         prop_id,
192                               const GValue *value,
193                               GParamSpec   *pspec)
194 {
195   GSocketClient *client = G_SOCKET_CLIENT (object);
196
197   switch (prop_id)
198     {
199     case PROP_FAMILY:
200       g_socket_client_set_family (client, g_value_get_enum (value));
201       break;
202
203     case PROP_TYPE:
204       g_socket_client_set_socket_type (client, g_value_get_enum (value));
205       break;
206
207     case PROP_PROTOCOL:
208       g_socket_client_set_protocol (client, g_value_get_enum (value));
209       break;
210
211     case PROP_LOCAL_ADDRESS:
212       g_socket_client_set_local_address (client, g_value_get_object (value));
213       break;
214
215     default:
216       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
217     }
218 }
219
220 /**
221  * g_socket_client_get_family:
222  * @client: a #GSocketClient.
223  *
224  * Gets the socket family of the socket client.
225  *
226  * See g_socket_client_set_family() for details.
227  *
228  * Returns: a #GSocketFamily
229  *
230  * Since: 2.22
231  **/
232 GSocketFamily
233 g_socket_client_get_family (GSocketClient *client)
234 {
235   return client->priv->family;
236 }
237
238 /**
239  * g_socket_client_set_family:
240  * @client: a #GSocketClient.
241  * @family: a #GSocketFamily
242  *
243  * Sets the socket family of the socket client.
244  * If this is set to something other than %G_SOCKET_FAMILY_INVALID
245  * then the sockets created by this object will be of the specified
246  * family.
247  *
248  * This might be useful for instance if you want to force the local
249  * connection to be an ipv4 socket, even though the address might
250  * be an ipv6 mapped to ipv4 address.
251  *
252  * Since: 2.22
253  **/
254 void
255 g_socket_client_set_family (GSocketClient *client,
256                             GSocketFamily family)
257 {
258   if (client->priv->family == family)
259     return;
260
261   client->priv->family = family;
262   g_object_notify (G_OBJECT (client), "family");
263 }
264
265 /**
266  * g_socket_client_get_socket_type:
267  * @client: a #GSocketClient.
268  *
269  * Gets the socket type of the socket client.
270  *
271  * See g_socket_client_set_socket_type() for details.
272  *
273  * Returns: a #GSocketFamily
274  *
275  * Since: 2.22
276  **/
277 GSocketType
278 g_socket_client_get_socket_type (GSocketClient *client)
279 {
280   return client->priv->type;
281 }
282
283 /**
284  * g_socket_client_set_socket_type:
285  * @client: a #GSocketClient.
286  * @type: a #GSocketType
287  *
288  * Sets the socket type of the socket client.
289  * The sockets created by this object will be of the specified
290  * type.
291  *
292  * It doesn't make sense to specify a type of %G_SOCKET_TYPE_DATAGRAM,
293  * as GSocketClient is used for connection oriented services.
294  *
295  * Since: 2.22
296  **/
297 void
298 g_socket_client_set_socket_type (GSocketClient *client,
299                                  GSocketType type)
300 {
301   if (client->priv->type == type)
302     return;
303
304   client->priv->type = type;
305   g_object_notify (G_OBJECT (client), "type");
306 }
307
308 /**
309  * g_socket_client_get_protocol:
310  * @client: a #GSocketClient.
311  *
312  * Gets the protocol name type of the socket client.
313  *
314  * See g_socket_client_set_protocol() for details.
315  *
316  * Returns: a #GSocketProtocol
317  *
318  * Since: 2.22
319  **/
320 GSocketProtocol
321 g_socket_client_get_protocol (GSocketClient *client)
322 {
323   return client->priv->protocol;
324 }
325
326 /**
327  * g_socket_client_set_protocol:
328  * @client: a #GSocketClient.
329  * @protocol: a #GSocketProtocol
330  *
331  * Sets the protocol of the socket client.
332  * The sockets created by this object will use of the specified
333  * protocol.
334  *
335  * If @protocol is %0 that means to use the default
336  * protocol for the socket family and type.
337  *
338  * Since: 2.22
339  **/
340 void
341 g_socket_client_set_protocol (GSocketClient *client,
342                               GSocketProtocol protocol)
343 {
344   if (client->priv->protocol == protocol)
345     return;
346
347   client->priv->protocol = protocol;
348   g_object_notify (G_OBJECT (client), "protocol");
349 }
350
351 /**
352  * g_socket_client_get_local_address:
353  * @client: a #GSocketClient.
354  *
355  * Gets the local address of the socket client.
356  *
357  * See g_socket_client_set_local_address() for details.
358  *
359  * Returns: a #GSocketAddres or %NULL. don't free
360  *
361  * Since: 2.22
362  **/
363 GSocketAddress *
364 g_socket_client_get_local_address (GSocketClient *client)
365 {
366   return client->priv->local_address;
367 }
368
369 /**
370  * g_socket_client_set_local_address:
371  * @client: a #GSocketClient.
372  * @address: a #GSocketAddress, or %NULL
373  *
374  * Sets the local address of the socket client.
375  * The sockets created by this object will bound to the
376  * specified address (if not %NULL) before connecting.
377  *
378  * This is useful if you want to ensure the the local
379  * side of the connection is on a specific port, or on
380  * a specific interface.
381  *
382  * Since: 2.22
383  **/
384 void
385 g_socket_client_set_local_address (GSocketClient        *client,
386                                    GSocketAddress       *address)
387 {
388   if (address)
389   g_object_ref (address);
390
391   if (client->priv->local_address)
392     {
393       g_object_unref (client->priv->local_address);
394     }
395   client->priv->local_address = address;
396   g_object_notify (G_OBJECT (client), "local-address");
397 }
398
399 static void
400 g_socket_client_class_init (GSocketClientClass *class)
401 {
402   GObjectClass *gobject_class = G_OBJECT_CLASS (class);
403
404   g_type_class_add_private (class, sizeof (GSocketClientPrivate));
405
406   gobject_class->finalize = g_socket_client_finalize;
407   gobject_class->set_property = g_socket_client_set_property;
408   gobject_class->get_property = g_socket_client_get_property;
409
410   g_object_class_install_property (gobject_class, PROP_FAMILY,
411                                    g_param_spec_enum ("family",
412                                                       P_("Socket family"),
413                                                       P_("The sockets address family to use for socket construction"),
414                                                       G_TYPE_SOCKET_FAMILY,
415                                                       G_SOCKET_FAMILY_INVALID,
416                                                       G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
417
418   g_object_class_install_property (gobject_class, PROP_TYPE,
419                                    g_param_spec_enum ("type",
420                                                       P_("Socket type"),
421                                                       P_("The sockets type to use for socket construction"),
422                                                       G_TYPE_SOCKET_TYPE,
423                                                       G_SOCKET_TYPE_STREAM,
424                                                       G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
425
426   g_object_class_install_property (gobject_class, PROP_PROTOCOL,
427                                    g_param_spec_enum ("protocol",
428                                                       P_("Socket protocol"),
429                                                       P_("The protocol to use for socket construction, or 0 for default"),
430                                                       G_TYPE_SOCKET_PROTOCOL,
431                                                       G_SOCKET_PROTOCOL_DEFAULT,
432                                                       G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
433
434   g_object_class_install_property (gobject_class, PROP_LOCAL_ADDRESS,
435                                    g_param_spec_object ("local-address",
436                                                         P_("Local address"),
437                                                         P_("The local address constructed sockets will be bound to"),
438                                                         G_TYPE_SOCKET_ADDRESS,
439                                                         G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
440 }
441
442 /**
443  * g_socket_client_connect:
444  * @client: a #GSocketClient.
445  * @connectable: a #GSocketConnectable specifying the remote address.
446  * @cancellable: optional #GCancellable object, %NULL to ignore.
447  * @error: #GError for error reporting, or %NULL to ignore.
448  *
449  * Tries to resolve the @connectable and make a network connection to it..
450  *
451  * Upon a successful connection, a new #GSocketConnection is constructed
452  * and returned.  The caller owns this new object and must drop their
453  * reference to it when finished with it.
454  *
455  * The type of the #GSocketConnection object returned depends on the type of
456  * the underlying socket that is used. For instance, for a TCP/IP connection
457  * it will be a #GTcpConnection.
458  *
459  * The socket created will be the same family as the the address that the
460  * @connectable resolves to, unless family is set with g_socket_client_set_family()
461  * or indirectly via g_socket_client_set_local_address(). The socket type
462  * defaults to %G_SOCKET_TYPE_STREAM but can be set with
463  * g_socket_client_set_socket_type().
464  *
465  * If a local address is specified with g_socket_client_set_local_address() the
466  * socket will be bound to this address before connecting.
467  *
468  * Returns: a #GSocketConnection on success, %NULL on error.
469  *
470  * Since: 2.22
471  **/
472 GSocketConnection *
473 g_socket_client_connect (GSocketClient       *client,
474                          GSocketConnectable  *connectable,
475                          GCancellable        *cancellable,
476                          GError             **error)
477 {
478   GSocketConnection *connection = NULL;
479   GSocketAddressEnumerator *enumerator;
480   GError *last_error, *tmp_error;
481
482   last_error = NULL;
483   enumerator = g_socket_connectable_enumerate (connectable);
484   while (connection == NULL)
485     {
486       GSocketAddress *address;
487       GSocket *socket;
488
489       if (g_cancellable_is_cancelled (cancellable))
490         {
491           g_clear_error (error);
492           g_cancellable_set_error_if_cancelled (cancellable, error);
493           break;
494         }
495
496       tmp_error = NULL;
497       address = g_socket_address_enumerator_next (enumerator, cancellable,
498                                                   &tmp_error);
499       if (address == NULL)
500         {
501           if (tmp_error)
502             {
503               g_clear_error (&last_error);
504               g_propagate_error (error, tmp_error);
505             }
506           else if (last_error)
507             {
508               g_propagate_error (error, tmp_error);
509             }
510           else
511             g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
512                          _("Unknown error on connect"));
513           break;
514         }
515
516       /* clear error from previous attempt */
517       g_clear_error (&last_error);
518
519       socket = create_socket (client, address, &last_error);
520       if (socket != NULL)
521         {
522           if (g_socket_connect (socket, address, &last_error))
523             connection = g_socket_connection_factory_create_connection (socket);
524
525           g_object_unref (socket);
526         }
527
528       g_object_unref (address);
529     }
530   g_object_unref (enumerator);
531
532   return connection;
533 }
534
535 /**
536  * g_socket_client_connect_to_host:
537  * @client: a #SocketClient
538  * @host_and_port: the name and optionally port of the host to connect to
539  * @default_port: the default port to connect to
540  * @cancellable: a #GCancellable, or %NULL
541  * @error: a pointer to a #GError, or %NULL
542  *
543  * This is a helper function for g_socket_client_connect().
544  *
545  * Attempts to create a TCP connection to the named host.
546  *
547  * @host_and_port may be in any of a number of recognised formats: an IPv6
548  * address, an IPv4 address, or a domain name (in which case a DNS
549  * lookup is performed).  Quoting with [] is supported for all address
550  * types.  A port override may be specified in the usual way with a
551  * colon.  Ports may be given as decimal numbers or symbolic names (in
552  * which case an /etc/services lookup is performed).
553  *
554  * If no port override is given in @host_and_port then @default_port will be
555  * used as the port number to connect to.
556  *
557  * In general, @host_and_port is expected to be provided by the user (allowing
558  * them to give the hostname, and a port overide if necessary) and
559  * @default_port is expected to be provided by the application.
560
561  * In the case that an IP address is given, a single connection
562  * attempt is made.  In the case that a name is given, multiple
563  * connection attempts may be made, in turn and according to the
564  * number of address records in DNS, until a connection succeeds.
565  *
566  * Upon a successful connection, a new #GSocketConnection is constructed
567  * and returned.  The caller owns this new object and must drop their
568  * reference to it when finished with it.
569  *
570  * In the event of any failure (DNS error, service not found, no hosts
571  * connectable) %NULL is returned and @error (if non-%NULL) is set
572  * accordingly.
573  *
574  Returns: a #GSocketConnection on success, %NULL on error.
575  *
576  * Since: 2.22
577  **/
578 GSocketConnection *
579 g_socket_client_connect_to_host (GSocketClient        *client,
580                                  const char           *host_and_port,
581                                  int                   default_port,
582                                  GCancellable         *cancellable,
583                                  GError              **error)
584 {
585   GSocketConnectable *connectable;
586   GSocketConnection *connection;
587
588   connectable = g_network_address_parse (host_and_port, default_port, error);
589   if (connectable == NULL)
590     return NULL;
591
592   connection = g_socket_client_connect (client, connectable,
593                                         cancellable, error);
594   g_object_unref (connectable);
595
596   return connection;
597 }
598
599 typedef struct
600 {
601   GSimpleAsyncResult *result;
602   GCancellable *cancellable;
603   GSocketClient *client;
604
605   GSocketAddressEnumerator *enumerator;
606   GSocket *current_socket;
607
608   GError *last_error;
609 } GSocketClientAsyncConnectData;
610
611 static void
612 g_socket_client_async_connect_complete (GSocketClientAsyncConnectData *data)
613 {
614   GSocketConnection *connection;
615
616   if (data->last_error)
617     {
618       g_simple_async_result_set_from_error (data->result, data->last_error);
619       g_error_free (data->last_error);
620     }
621   else
622     {
623       g_assert (data->current_socket);
624
625       g_socket_set_blocking (data->current_socket, TRUE);
626
627       connection = g_socket_connection_factory_create_connection (data->current_socket);
628       g_simple_async_result_set_op_res_gpointer (data->result,
629                                                  connection,
630                                                  g_object_unref);
631     }
632
633   g_simple_async_result_complete (data->result);
634   g_object_unref (data->result);
635 }
636
637
638 static void
639 g_socket_client_enumerator_callback (GObject      *object,
640                                      GAsyncResult *result,
641                                      gpointer      user_data);
642
643 static void
644 set_last_error (GSocketClientAsyncConnectData *data,
645                 GError *error)
646 {
647   g_clear_error (&data->last_error);
648   data->last_error = error;
649 }
650
651 static gboolean
652 g_socket_client_socket_callback (GSocket *socket,
653                                  GIOCondition condition,
654                                  GSocketClientAsyncConnectData *data)
655 {
656   GError *error = NULL;
657
658   if (g_cancellable_is_cancelled (data->cancellable))
659     {
660       /* Cancelled, return done with last error being cancelled */
661       g_clear_error (&data->last_error);
662       g_object_unref (data->current_socket);
663       data->current_socket = NULL;
664       g_cancellable_set_error_if_cancelled (data->cancellable,
665                                             &data->last_error);
666     }
667   else
668     {
669       /* socket is ready for writing means connect done, did it succeed? */
670       if (!g_socket_check_connect_result (data->current_socket, &error))
671         {
672           set_last_error (data, error);
673
674           /* try next one */
675           g_socket_address_enumerator_next_async (data->enumerator,
676                                                   data->cancellable,
677                                                   g_socket_client_enumerator_callback,
678                                                   data);
679
680           return FALSE;
681         }
682     }
683
684   g_socket_client_async_connect_complete (data);
685
686   return FALSE;
687 }
688
689 static void
690 g_socket_client_enumerator_callback (GObject      *object,
691                                      GAsyncResult *result,
692                                      gpointer      user_data)
693 {
694   GSocketClientAsyncConnectData *data = user_data;
695   GSocketAddress *address;
696   GSocket *socket;
697   GError *tmp_error = NULL;
698
699   if (g_cancellable_is_cancelled (data->cancellable))
700     {
701       g_clear_error (&data->last_error);
702       g_cancellable_set_error_if_cancelled (data->cancellable, &data->last_error);
703       g_socket_client_async_connect_complete (data);
704       return;
705     }
706
707   address = g_socket_address_enumerator_next_finish (data->enumerator,
708                                                      result, &tmp_error);
709
710   if (address == NULL)
711     {
712       if (tmp_error)
713         set_last_error (data, tmp_error);
714       else if (data->last_error == NULL)
715         g_set_error (&data->last_error, G_IO_ERROR, G_IO_ERROR_FAILED,
716                      _("Unknown error on connect"));
717
718       g_socket_client_async_connect_complete (data);
719       return;
720     }
721
722   g_clear_error (&data->last_error);
723
724   socket = create_socket (data->client, address, &data->last_error);
725   if (socket != NULL)
726     {
727       g_socket_set_blocking (socket, FALSE);
728       if (g_socket_connect (socket, address, &tmp_error))
729         {
730           data->current_socket = socket;
731           g_socket_client_async_connect_complete (data);
732
733           g_object_unref (address);
734           return;
735         }
736       else if (g_error_matches (tmp_error, G_IO_ERROR, G_IO_ERROR_PENDING))
737         {
738           GSource *source;
739
740           data->current_socket = socket;
741           g_error_free (tmp_error);
742
743           source = g_socket_create_source (socket, G_IO_OUT,
744                                            data->cancellable);
745           g_source_set_callback (source,
746                                  (GSourceFunc) g_socket_client_socket_callback,
747                                  data, NULL);
748           g_source_attach (source, NULL);
749           g_source_unref (source);
750
751           g_object_unref (address);
752           return;
753         }
754       else
755         {
756           data->last_error = tmp_error;
757           g_object_unref (socket);
758         }
759       g_object_unref (address);
760     }
761
762   g_socket_address_enumerator_next_async (data->enumerator,
763                                           data->cancellable,
764                                           g_socket_client_enumerator_callback,
765                                           data);
766 }
767
768 /**
769  * g_socket_client_connect_async:
770  * @client: a #GTcpClient
771  * @connectable: a #GSocketConnectable specifying the remote address.
772  * @cancellable: a #GCancellable, or %NULL
773  * @callback: a #GAsyncReadyCallback
774  * @user_data: user data for the callback
775  *
776  * This is the asynchronous version of g_socket_client_connect().
777  *
778  * When the operation is finished @callback will be
779  * called. You can then call g_socket_client_connect_finish() to get
780  * the result of the operation.
781  *
782  * Since: 2.22
783  **/
784 void
785 g_socket_client_connect_async (GSocketClient       *client,
786                                GSocketConnectable  *connectable,
787                                GCancellable        *cancellable,
788                                GAsyncReadyCallback  callback,
789                                gpointer             user_data)
790 {
791   GSocketClientAsyncConnectData *data;
792
793   g_return_if_fail (G_IS_SOCKET_CLIENT (client));
794
795   data = g_slice_new (GSocketClientAsyncConnectData);
796
797   data->result = g_simple_async_result_new (G_OBJECT (client),
798                                             callback, user_data,
799                                             g_socket_client_connect_async);
800   data->client = client;
801   if (cancellable)
802     data->cancellable = g_object_ref (cancellable);
803   else
804     data->cancellable = NULL;
805   data->last_error = NULL;
806   data->enumerator = g_socket_connectable_enumerate (connectable);
807
808   g_socket_address_enumerator_next_async (data->enumerator, cancellable,
809                                           g_socket_client_enumerator_callback,
810                                           data);
811 }
812
813 /**
814  * g_socket_client_connect_to_host_async:
815  * @client: a #GTcpClient
816  * @host_and_port: the name and optionally the port of the host to connect to
817  * @default_port: the default port to connect to
818  * @cancellable: a #GCancellable, or %NULL
819  * @callback: a #GAsyncReadyCallback
820  * @user_data: user data for the callback
821  *
822  * This is the asynchronous version of g_socket_client_connect_to_host().
823  *
824  * When the operation is finished @callback will be
825  * called. You can then call g_socket_client_connect_to_host_finish() to get
826  * the result of the operation.
827  *
828  * Since: 2.22
829  **/
830 void
831 g_socket_client_connect_to_host_async (GSocketClient        *client,
832                                        const char           *host_and_port,
833                                        int                   default_port,
834                                        GCancellable         *cancellable,
835                                        GAsyncReadyCallback   callback,
836                                        gpointer              user_data)
837 {
838   GSocketConnectable *connectable;
839   GError *error;
840
841   error = NULL;
842   connectable = g_network_address_parse (host_and_port, default_port,
843                                          &error);
844   if (connectable == NULL)
845     {
846       g_simple_async_report_gerror_in_idle (G_OBJECT (client),
847                                             callback, user_data, error);
848       g_error_free (error);
849     }
850   else
851     {
852       g_socket_client_connect_async (client,
853                                      connectable, cancellable,
854                                      callback, user_data);
855       g_object_unref (connectable);
856     }
857 }
858
859 /**
860  * g_socket_client_connect_finish:
861  * @client: a #GSocketClient.
862  * @result: a #GAsyncResult.
863  * @error: a #GError location to store the error occuring, or %NULL to
864  * ignore.
865  *
866  * Finishes an async connect operation. See g_socket_client_connect_async()
867  *
868  * Returns: a #GSocketConnection on success, %NULL on error.
869  *
870  * Since: 2.22
871  **/
872 GSocketConnection *
873 g_socket_client_connect_finish (GSocketClient  *client,
874                                 GAsyncResult   *result,
875                                 GError        **error)
876 {
877   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
878
879   if (g_simple_async_result_propagate_error (simple, error))
880     return NULL;
881
882   return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
883 }
884
885 /**
886  * g_socket_client_connect_to_host_finish:
887  * @client: a #GSocketClient.
888  * @result: a #GAsyncResult.
889  * @error: a #GError location to store the error occuring, or %NULL to
890  * ignore.
891  *
892  * Finishes an async connect operation. See g_socket_client_connect_to_host_async()
893  *
894  * Returns: a #GSocketConnection on success, %NULL on error.
895  *
896  * Since: 2.22
897  **/
898 GSocketConnection *
899 g_socket_client_connect_to_host_finish (GSocketClient        *client,
900                                         GAsyncResult         *result,
901                                         GError              **error)
902 {
903   return g_socket_client_connect_finish (client, result, error);
904 }
905
906 #define __G_SOCKET_CLIENT_C__
907 #include "gioaliasdef.c"