Coverage Report

Created: 2025-07-01 07:09

/src/glib/gio/gsocketclient.c
Line
Count
Source (jump to first uncovered line)
1
/*  GIO - GLib Input, Output and Streaming Library
2
 *
3
 * Copyright © 2008, 2009 codethink
4
 * Copyright © 2009 Red Hat, Inc
5
 * Copyright © 2018 Igalia S.L.
6
 *
7
 * This library is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * This library is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General
18
 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
19
 *
20
 * Authors: Ryan Lortie <desrt@desrt.ca>
21
 *          Alexander Larsson <alexl@redhat.com>
22
 */
23
24
#include "config.h"
25
#include "gsocketclient.h"
26
27
#ifndef G_OS_WIN32
28
#include <netinet/in.h>
29
#endif
30
31
#include <stdlib.h>
32
#include <string.h>
33
34
#include <gio/gioenumtypes.h>
35
#include <gio/gsocketaddressenumerator.h>
36
#include <gio/gsocketconnectable.h>
37
#include <gio/gsocketconnection.h>
38
#include <gio/gioprivate.h>
39
#include <gio/gproxyaddressenumerator.h>
40
#include <gio/gproxyaddress.h>
41
#include <gio/gtask.h>
42
#include <gio/gcancellable.h>
43
#include <gio/gioerror.h>
44
#include <gio/gsocket.h>
45
#include <gio/gnetworkaddress.h>
46
#include <gio/gnetworking.h>
47
#include <gio/gnetworkservice.h>
48
#include <gio/gproxy.h>
49
#include <gio/gproxyresolver.h>
50
#include <gio/gsocketaddress.h>
51
#include <gio/gtcpconnection.h>
52
#include <gio/gtcpwrapperconnection.h>
53
#include <gio/gtlscertificate.h>
54
#include <gio/gtlsclientconnection.h>
55
#include <gio/ginetaddress.h>
56
#include "glibintl.h"
57
#include "gmarshal-internal.h"
58
59
/* As recommended by RFC 8305 this is the time it waits
60
 * on a connection before starting another concurrent attempt.
61
 */
62
0
#define HAPPY_EYEBALLS_CONNECTION_ATTEMPT_TIMEOUT_MS 250
63
64
/**
65
 * SECTION:gsocketclient
66
 * @short_description: Helper for connecting to a network service
67
 * @include: gio/gio.h
68
 * @see_also: #GSocketConnection, #GSocketListener
69
 *
70
 * #GSocketClient is a lightweight high-level utility class for connecting to
71
 * a network host using a connection oriented socket type.
72
 *
73
 * You create a #GSocketClient object, set any options you want, and then
74
 * call a sync or async connect operation, which returns a #GSocketConnection
75
 * subclass on success.
76
 *
77
 * The type of the #GSocketConnection object returned depends on the type of
78
 * the underlying socket that is in use. For instance, for a TCP/IP connection
79
 * it will be a #GTcpConnection.
80
 *
81
 * As #GSocketClient is a lightweight object, you don't need to cache it. You
82
 * can just create a new one any time you need one.
83
 *
84
 * Since: 2.22
85
 */
86
87
88
enum
89
{
90
  EVENT,
91
  LAST_SIGNAL
92
};
93
94
static guint signals[LAST_SIGNAL] = { 0 };
95
96
enum
97
{
98
  PROP_NONE,
99
  PROP_FAMILY,
100
  PROP_TYPE,
101
  PROP_PROTOCOL,
102
  PROP_LOCAL_ADDRESS,
103
  PROP_TIMEOUT,
104
  PROP_ENABLE_PROXY,
105
  PROP_TLS,
106
  PROP_TLS_VALIDATION_FLAGS,
107
  PROP_PROXY_RESOLVER
108
};
109
110
struct _GSocketClientPrivate
111
{
112
  GSocketFamily family;
113
  GSocketType type;
114
  GSocketProtocol protocol;
115
  GSocketAddress *local_address;
116
  guint timeout;
117
  gboolean enable_proxy;
118
  GHashTable *app_proxies;
119
  gboolean tls;
120
  GTlsCertificateFlags tls_validation_flags;
121
  GProxyResolver *proxy_resolver;
122
};
123
124
G_DEFINE_TYPE_WITH_PRIVATE (GSocketClient, g_socket_client, G_TYPE_OBJECT)
125
126
static GSocket *
127
create_socket (GSocketClient  *client,
128
         GSocketAddress *dest_address,
129
         GError        **error)
130
0
{
131
0
  GSocketFamily family;
132
0
  GSocket *socket;
133
134
0
  family = client->priv->family;
135
0
  if (family == G_SOCKET_FAMILY_INVALID &&
136
0
      client->priv->local_address != NULL)
137
0
    family = g_socket_address_get_family (client->priv->local_address);
138
0
  if (family == G_SOCKET_FAMILY_INVALID)
139
0
    family = g_socket_address_get_family (dest_address);
140
141
0
  socket = g_socket_new (family,
142
0
       client->priv->type,
143
0
       client->priv->protocol,
144
0
       error);
145
0
  if (socket == NULL)
146
0
    return NULL;
147
148
0
  if (client->priv->local_address)
149
0
    {
150
0
#ifdef IP_BIND_ADDRESS_NO_PORT
151
0
      g_socket_set_option (socket, IPPROTO_IP, IP_BIND_ADDRESS_NO_PORT, 1, NULL);
152
0
#endif
153
154
0
      if (!g_socket_bind (socket,
155
0
        client->priv->local_address,
156
0
        FALSE,
157
0
        error))
158
0
  {
159
0
    g_object_unref (socket);
160
0
    return NULL;
161
0
  }
162
0
    }
163
164
0
  if (client->priv->timeout)
165
0
    g_socket_set_timeout (socket, client->priv->timeout);
166
167
0
  return socket;
168
0
}
169
170
static gboolean
171
can_use_proxy (GSocketClient *client)
172
0
{
173
0
  GSocketClientPrivate *priv = client->priv;
174
175
0
  return priv->enable_proxy
176
0
          && priv->type == G_SOCKET_TYPE_STREAM;
177
0
}
178
179
static void
180
clarify_connect_error (GError             *error,
181
           GSocketConnectable *connectable,
182
           GSocketAddress     *address)
183
0
{
184
0
  const char *name;
185
0
  char *tmp_name = NULL;
186
187
0
  if (G_IS_PROXY_ADDRESS (address))
188
0
    {
189
0
      name = tmp_name = g_inet_address_to_string (g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (address)));
190
191
0
      g_prefix_error (&error, _("Could not connect to proxy server %s: "), name);
192
0
    }
193
0
  else
194
0
    {
195
0
      if (G_IS_NETWORK_ADDRESS (connectable))
196
0
  name = g_network_address_get_hostname (G_NETWORK_ADDRESS (connectable));
197
0
      else if (G_IS_NETWORK_SERVICE (connectable))
198
0
  name = g_network_service_get_domain (G_NETWORK_SERVICE (connectable));
199
0
      else if (G_IS_INET_SOCKET_ADDRESS (connectable))
200
0
  name = tmp_name = g_inet_address_to_string (g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (connectable)));
201
0
      else
202
0
  name = NULL;
203
204
0
      if (name)
205
0
  g_prefix_error (&error, _("Could not connect to %s: "), name);
206
0
      else
207
0
  g_prefix_error (&error, _("Could not connect: "));
208
0
    }
209
210
0
  g_free (tmp_name);
211
0
}
212
213
static void
214
g_socket_client_init (GSocketClient *client)
215
0
{
216
0
  client->priv = g_socket_client_get_instance_private (client);
217
0
  client->priv->type = G_SOCKET_TYPE_STREAM;
218
0
  client->priv->app_proxies = g_hash_table_new_full (g_str_hash,
219
0
                 g_str_equal,
220
0
                 g_free,
221
0
                 NULL);
222
0
}
223
224
/**
225
 * g_socket_client_new:
226
 *
227
 * Creates a new #GSocketClient with the default options.
228
 *
229
 * Returns: a #GSocketClient.
230
 *     Free the returned object with g_object_unref().
231
 *
232
 * Since: 2.22
233
 */
234
GSocketClient *
235
g_socket_client_new (void)
236
0
{
237
0
  return g_object_new (G_TYPE_SOCKET_CLIENT, NULL);
238
0
}
239
240
static void
241
g_socket_client_finalize (GObject *object)
242
0
{
243
0
  GSocketClient *client = G_SOCKET_CLIENT (object);
244
245
0
  g_clear_object (&client->priv->local_address);
246
0
  g_clear_object (&client->priv->proxy_resolver);
247
248
0
  G_OBJECT_CLASS (g_socket_client_parent_class)->finalize (object);
249
250
0
  g_hash_table_unref (client->priv->app_proxies);
251
0
}
252
253
static void
254
g_socket_client_get_property (GObject    *object,
255
            guint       prop_id,
256
            GValue     *value,
257
            GParamSpec *pspec)
258
0
{
259
0
  GSocketClient *client = G_SOCKET_CLIENT (object);
260
261
0
  switch (prop_id)
262
0
    {
263
0
      case PROP_FAMILY:
264
0
  g_value_set_enum (value, client->priv->family);
265
0
  break;
266
267
0
      case PROP_TYPE:
268
0
  g_value_set_enum (value, client->priv->type);
269
0
  break;
270
271
0
      case PROP_PROTOCOL:
272
0
  g_value_set_enum (value, client->priv->protocol);
273
0
  break;
274
275
0
      case PROP_LOCAL_ADDRESS:
276
0
  g_value_set_object (value, client->priv->local_address);
277
0
  break;
278
279
0
      case PROP_TIMEOUT:
280
0
  g_value_set_uint (value, client->priv->timeout);
281
0
  break;
282
283
0
      case PROP_ENABLE_PROXY:
284
0
  g_value_set_boolean (value, client->priv->enable_proxy);
285
0
  break;
286
287
0
      case PROP_TLS:
288
0
  g_value_set_boolean (value, g_socket_client_get_tls (client));
289
0
  break;
290
291
0
      case PROP_TLS_VALIDATION_FLAGS:
292
0
  g_value_set_flags (value, g_socket_client_get_tls_validation_flags (client));
293
0
  break;
294
295
0
      case PROP_PROXY_RESOLVER:
296
0
  g_value_set_object (value, g_socket_client_get_proxy_resolver (client));
297
0
  break;
298
299
0
      default:
300
0
  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
301
0
    }
302
0
}
303
304
static void
305
g_socket_client_set_property (GObject      *object,
306
            guint         prop_id,
307
            const GValue *value,
308
            GParamSpec   *pspec)
309
0
{
310
0
  GSocketClient *client = G_SOCKET_CLIENT (object);
311
312
0
  switch (prop_id)
313
0
    {
314
0
    case PROP_FAMILY:
315
0
      g_socket_client_set_family (client, g_value_get_enum (value));
316
0
      break;
317
318
0
    case PROP_TYPE:
319
0
      g_socket_client_set_socket_type (client, g_value_get_enum (value));
320
0
      break;
321
322
0
    case PROP_PROTOCOL:
323
0
      g_socket_client_set_protocol (client, g_value_get_enum (value));
324
0
      break;
325
326
0
    case PROP_LOCAL_ADDRESS:
327
0
      g_socket_client_set_local_address (client, g_value_get_object (value));
328
0
      break;
329
330
0
    case PROP_TIMEOUT:
331
0
      g_socket_client_set_timeout (client, g_value_get_uint (value));
332
0
      break;
333
334
0
    case PROP_ENABLE_PROXY:
335
0
      g_socket_client_set_enable_proxy (client, g_value_get_boolean (value));
336
0
      break;
337
338
0
    case PROP_TLS:
339
0
      g_socket_client_set_tls (client, g_value_get_boolean (value));
340
0
      break;
341
342
0
    case PROP_TLS_VALIDATION_FLAGS:
343
0
      g_socket_client_set_tls_validation_flags (client, g_value_get_flags (value));
344
0
      break;
345
346
0
    case PROP_PROXY_RESOLVER:
347
0
      g_socket_client_set_proxy_resolver (client, g_value_get_object (value));
348
0
      break;
349
350
0
    default:
351
0
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
352
0
    }
353
0
}
354
355
/**
356
 * g_socket_client_get_family:
357
 * @client: a #GSocketClient.
358
 *
359
 * Gets the socket family of the socket client.
360
 *
361
 * See g_socket_client_set_family() for details.
362
 *
363
 * Returns: a #GSocketFamily
364
 *
365
 * Since: 2.22
366
 */
367
GSocketFamily
368
g_socket_client_get_family (GSocketClient *client)
369
0
{
370
0
  return client->priv->family;
371
0
}
372
373
/**
374
 * g_socket_client_set_family:
375
 * @client: a #GSocketClient.
376
 * @family: a #GSocketFamily
377
 *
378
 * Sets the socket family of the socket client.
379
 * If this is set to something other than %G_SOCKET_FAMILY_INVALID
380
 * then the sockets created by this object will be of the specified
381
 * family.
382
 *
383
 * This might be useful for instance if you want to force the local
384
 * connection to be an ipv4 socket, even though the address might
385
 * be an ipv6 mapped to ipv4 address.
386
 *
387
 * Since: 2.22
388
 */
389
void
390
g_socket_client_set_family (GSocketClient *client,
391
          GSocketFamily  family)
392
0
{
393
0
  if (client->priv->family == family)
394
0
    return;
395
396
0
  client->priv->family = family;
397
0
  g_object_notify (G_OBJECT (client), "family");
398
0
}
399
400
/**
401
 * g_socket_client_get_socket_type:
402
 * @client: a #GSocketClient.
403
 *
404
 * Gets the socket type of the socket client.
405
 *
406
 * See g_socket_client_set_socket_type() for details.
407
 *
408
 * Returns: a #GSocketFamily
409
 *
410
 * Since: 2.22
411
 */
412
GSocketType
413
g_socket_client_get_socket_type (GSocketClient *client)
414
0
{
415
0
  return client->priv->type;
416
0
}
417
418
/**
419
 * g_socket_client_set_socket_type:
420
 * @client: a #GSocketClient.
421
 * @type: a #GSocketType
422
 *
423
 * Sets the socket type of the socket client.
424
 * The sockets created by this object will be of the specified
425
 * type.
426
 *
427
 * It doesn't make sense to specify a type of %G_SOCKET_TYPE_DATAGRAM,
428
 * as GSocketClient is used for connection oriented services.
429
 *
430
 * Since: 2.22
431
 */
432
void
433
g_socket_client_set_socket_type (GSocketClient *client,
434
         GSocketType    type)
435
0
{
436
0
  if (client->priv->type == type)
437
0
    return;
438
439
0
  client->priv->type = type;
440
0
  g_object_notify (G_OBJECT (client), "type");
441
0
}
442
443
/**
444
 * g_socket_client_get_protocol:
445
 * @client: a #GSocketClient
446
 *
447
 * Gets the protocol name type of the socket client.
448
 *
449
 * See g_socket_client_set_protocol() for details.
450
 *
451
 * Returns: a #GSocketProtocol
452
 *
453
 * Since: 2.22
454
 */
455
GSocketProtocol
456
g_socket_client_get_protocol (GSocketClient *client)
457
0
{
458
0
  return client->priv->protocol;
459
0
}
460
461
/**
462
 * g_socket_client_set_protocol:
463
 * @client: a #GSocketClient.
464
 * @protocol: a #GSocketProtocol
465
 *
466
 * Sets the protocol of the socket client.
467
 * The sockets created by this object will use of the specified
468
 * protocol.
469
 *
470
 * If @protocol is %G_SOCKET_PROTOCOL_DEFAULT that means to use the default
471
 * protocol for the socket family and type.
472
 *
473
 * Since: 2.22
474
 */
475
void
476
g_socket_client_set_protocol (GSocketClient   *client,
477
            GSocketProtocol  protocol)
478
0
{
479
0
  if (client->priv->protocol == protocol)
480
0
    return;
481
482
0
  client->priv->protocol = protocol;
483
0
  g_object_notify (G_OBJECT (client), "protocol");
484
0
}
485
486
/**
487
 * g_socket_client_get_local_address:
488
 * @client: a #GSocketClient.
489
 *
490
 * Gets the local address of the socket client.
491
 *
492
 * See g_socket_client_set_local_address() for details.
493
 *
494
 * Returns: (nullable) (transfer none): a #GSocketAddress or %NULL. Do not free.
495
 *
496
 * Since: 2.22
497
 */
498
GSocketAddress *
499
g_socket_client_get_local_address (GSocketClient *client)
500
0
{
501
0
  return client->priv->local_address;
502
0
}
503
504
/**
505
 * g_socket_client_set_local_address:
506
 * @client: a #GSocketClient.
507
 * @address: (nullable): a #GSocketAddress, or %NULL
508
 *
509
 * Sets the local address of the socket client.
510
 * The sockets created by this object will bound to the
511
 * specified address (if not %NULL) before connecting.
512
 *
513
 * This is useful if you want to ensure that the local
514
 * side of the connection is on a specific port, or on
515
 * a specific interface.
516
 *
517
 * Since: 2.22
518
 */
519
void
520
g_socket_client_set_local_address (GSocketClient  *client,
521
           GSocketAddress *address)
522
0
{
523
0
  if (address)
524
0
    g_object_ref (address);
525
526
0
  if (client->priv->local_address)
527
0
    {
528
0
      g_object_unref (client->priv->local_address);
529
0
    }
530
0
  client->priv->local_address = address;
531
0
  g_object_notify (G_OBJECT (client), "local-address");
532
0
}
533
534
/**
535
 * g_socket_client_get_timeout:
536
 * @client: a #GSocketClient
537
 *
538
 * Gets the I/O timeout time for sockets created by @client.
539
 *
540
 * See g_socket_client_set_timeout() for details.
541
 *
542
 * Returns: the timeout in seconds
543
 *
544
 * Since: 2.26
545
 */
546
guint
547
g_socket_client_get_timeout (GSocketClient *client)
548
0
{
549
0
  return client->priv->timeout;
550
0
}
551
552
553
/**
554
 * g_socket_client_set_timeout:
555
 * @client: a #GSocketClient.
556
 * @timeout: the timeout
557
 *
558
 * Sets the I/O timeout for sockets created by @client. @timeout is a
559
 * time in seconds, or 0 for no timeout (the default).
560
 *
561
 * The timeout value affects the initial connection attempt as well,
562
 * so setting this may cause calls to g_socket_client_connect(), etc,
563
 * to fail with %G_IO_ERROR_TIMED_OUT.
564
 *
565
 * Since: 2.26
566
 */
567
void
568
g_socket_client_set_timeout (GSocketClient *client,
569
           guint          timeout)
570
0
{
571
0
  if (client->priv->timeout == timeout)
572
0
    return;
573
574
0
  client->priv->timeout = timeout;
575
0
  g_object_notify (G_OBJECT (client), "timeout");
576
0
}
577
578
/**
579
 * g_socket_client_get_enable_proxy:
580
 * @client: a #GSocketClient.
581
 *
582
 * Gets the proxy enable state; see g_socket_client_set_enable_proxy()
583
 *
584
 * Returns: whether proxying is enabled
585
 *
586
 * Since: 2.26
587
 */
588
gboolean
589
g_socket_client_get_enable_proxy (GSocketClient *client)
590
0
{
591
0
  return client->priv->enable_proxy;
592
0
}
593
594
/**
595
 * g_socket_client_set_enable_proxy:
596
 * @client: a #GSocketClient.
597
 * @enable: whether to enable proxies
598
 *
599
 * Sets whether or not @client attempts to make connections via a
600
 * proxy server. When enabled (the default), #GSocketClient will use a
601
 * #GProxyResolver to determine if a proxy protocol such as SOCKS is
602
 * needed, and automatically do the necessary proxy negotiation.
603
 *
604
 * See also g_socket_client_set_proxy_resolver().
605
 *
606
 * Since: 2.26
607
 */
608
void
609
g_socket_client_set_enable_proxy (GSocketClient *client,
610
          gboolean       enable)
611
0
{
612
0
  enable = !!enable;
613
0
  if (client->priv->enable_proxy == enable)
614
0
    return;
615
616
0
  client->priv->enable_proxy = enable;
617
0
  g_object_notify (G_OBJECT (client), "enable-proxy");
618
0
}
619
620
/**
621
 * g_socket_client_get_tls:
622
 * @client: a #GSocketClient.
623
 *
624
 * Gets whether @client creates TLS connections. See
625
 * g_socket_client_set_tls() for details.
626
 *
627
 * Returns: whether @client uses TLS
628
 *
629
 * Since: 2.28
630
 */
631
gboolean
632
g_socket_client_get_tls (GSocketClient *client)
633
0
{
634
0
  return client->priv->tls;
635
0
}
636
637
/**
638
 * g_socket_client_set_tls:
639
 * @client: a #GSocketClient.
640
 * @tls: whether to use TLS
641
 *
642
 * Sets whether @client creates TLS (aka SSL) connections. If @tls is
643
 * %TRUE, @client will wrap its connections in a #GTlsClientConnection
644
 * and perform a TLS handshake when connecting.
645
 *
646
 * Note that since #GSocketClient must return a #GSocketConnection,
647
 * but #GTlsClientConnection is not a #GSocketConnection, this
648
 * actually wraps the resulting #GTlsClientConnection in a
649
 * #GTcpWrapperConnection when returning it. You can use
650
 * g_tcp_wrapper_connection_get_base_io_stream() on the return value
651
 * to extract the #GTlsClientConnection.
652
 *
653
 * If you need to modify the behavior of the TLS handshake (eg, by
654
 * setting a client-side certificate to use, or connecting to the
655
 * #GTlsConnection::accept-certificate signal), you can connect to
656
 * @client's #GSocketClient::event signal and wait for it to be
657
 * emitted with %G_SOCKET_CLIENT_TLS_HANDSHAKING, which will give you
658
 * a chance to see the #GTlsClientConnection before the handshake
659
 * starts.
660
 *
661
 * Since: 2.28
662
 */
663
void
664
g_socket_client_set_tls (GSocketClient *client,
665
       gboolean       tls)
666
0
{
667
0
  tls = !!tls;
668
0
  if (tls == client->priv->tls)
669
0
    return;
670
671
0
  client->priv->tls = tls;
672
0
  g_object_notify (G_OBJECT (client), "tls");
673
0
}
674
675
/**
676
 * g_socket_client_get_tls_validation_flags:
677
 * @client: a #GSocketClient.
678
 *
679
 * Gets the TLS validation flags used creating TLS connections via
680
 * @client.
681
 *
682
 * Returns: the TLS validation flags
683
 *
684
 * Since: 2.28
685
 */
686
GTlsCertificateFlags
687
g_socket_client_get_tls_validation_flags (GSocketClient *client)
688
0
{
689
0
  return client->priv->tls_validation_flags;
690
0
}
691
692
/**
693
 * g_socket_client_set_tls_validation_flags:
694
 * @client: a #GSocketClient.
695
 * @flags: the validation flags
696
 *
697
 * Sets the TLS validation flags used when creating TLS connections
698
 * via @client. The default value is %G_TLS_CERTIFICATE_VALIDATE_ALL.
699
 *
700
 * Since: 2.28
701
 */
702
void
703
g_socket_client_set_tls_validation_flags (GSocketClient        *client,
704
            GTlsCertificateFlags  flags)
705
0
{
706
0
  if (client->priv->tls_validation_flags != flags)
707
0
    {
708
0
      client->priv->tls_validation_flags = flags;
709
0
      g_object_notify (G_OBJECT (client), "tls-validation-flags");
710
0
    }
711
0
}
712
713
/**
714
 * g_socket_client_get_proxy_resolver:
715
 * @client: a #GSocketClient.
716
 *
717
 * Gets the #GProxyResolver being used by @client. Normally, this will
718
 * be the resolver returned by g_proxy_resolver_get_default(), but you
719
 * can override it with g_socket_client_set_proxy_resolver().
720
 *
721
 * Returns: (transfer none): The #GProxyResolver being used by
722
 *   @client.
723
 *
724
 * Since: 2.36
725
 */
726
GProxyResolver *
727
g_socket_client_get_proxy_resolver (GSocketClient *client)
728
0
{
729
0
  if (client->priv->proxy_resolver)
730
0
    return client->priv->proxy_resolver;
731
0
  else
732
0
    return g_proxy_resolver_get_default ();
733
0
}
734
735
/**
736
 * g_socket_client_set_proxy_resolver:
737
 * @client: a #GSocketClient.
738
 * @proxy_resolver: (nullable): a #GProxyResolver, or %NULL for the
739
 *   default.
740
 *
741
 * Overrides the #GProxyResolver used by @client. You can call this if
742
 * you want to use specific proxies, rather than using the system
743
 * default proxy settings.
744
 *
745
 * Note that whether or not the proxy resolver is actually used
746
 * depends on the setting of #GSocketClient:enable-proxy, which is not
747
 * changed by this function (but which is %TRUE by default)
748
 *
749
 * Since: 2.36
750
 */
751
void
752
g_socket_client_set_proxy_resolver (GSocketClient  *client,
753
                                    GProxyResolver *proxy_resolver)
754
0
{
755
  /* We have to be careful to avoid calling
756
   * g_proxy_resolver_get_default() until we're sure we need it,
757
   * because trying to load the default proxy resolver module will
758
   * break some test programs that aren't expecting it (eg,
759
   * tests/gsettings).
760
   */
761
762
0
  if (client->priv->proxy_resolver)
763
0
    g_object_unref (client->priv->proxy_resolver);
764
765
0
  client->priv->proxy_resolver = proxy_resolver;
766
767
0
  if (client->priv->proxy_resolver)
768
0
    g_object_ref (client->priv->proxy_resolver);
769
0
}
770
771
static void
772
g_socket_client_class_init (GSocketClientClass *class)
773
0
{
774
0
  GObjectClass *gobject_class = G_OBJECT_CLASS (class);
775
776
0
  gobject_class->finalize = g_socket_client_finalize;
777
0
  gobject_class->set_property = g_socket_client_set_property;
778
0
  gobject_class->get_property = g_socket_client_get_property;
779
780
  /**
781
   * GSocketClient::event:
782
   * @client: the #GSocketClient
783
   * @event: the event that is occurring
784
   * @connectable: the #GSocketConnectable that @event is occurring on
785
   * @connection: (nullable): the current representation of the connection
786
   *
787
   * Emitted when @client's activity on @connectable changes state.
788
   * Among other things, this can be used to provide progress
789
   * information about a network connection in the UI. The meanings of
790
   * the different @event values are as follows:
791
   *
792
   * - %G_SOCKET_CLIENT_RESOLVING: @client is about to look up @connectable
793
   *   in DNS. @connection will be %NULL.
794
   *
795
   * - %G_SOCKET_CLIENT_RESOLVED:  @client has successfully resolved
796
   *   @connectable in DNS. @connection will be %NULL.
797
   *
798
   * - %G_SOCKET_CLIENT_CONNECTING: @client is about to make a connection
799
   *   to a remote host; either a proxy server or the destination server
800
   *   itself. @connection is the #GSocketConnection, which is not yet
801
   *   connected.  Since GLib 2.40, you can access the remote
802
   *   address via g_socket_connection_get_remote_address().
803
   *
804
   * - %G_SOCKET_CLIENT_CONNECTED: @client has successfully connected
805
   *   to a remote host. @connection is the connected #GSocketConnection.
806
   *
807
   * - %G_SOCKET_CLIENT_PROXY_NEGOTIATING: @client is about to negotiate
808
   *   with a proxy to get it to connect to @connectable. @connection is
809
   *   the #GSocketConnection to the proxy server.
810
   *
811
   * - %G_SOCKET_CLIENT_PROXY_NEGOTIATED: @client has negotiated a
812
   *   connection to @connectable through a proxy server. @connection is
813
   *   the stream returned from g_proxy_connect(), which may or may not
814
   *   be a #GSocketConnection.
815
   *
816
   * - %G_SOCKET_CLIENT_TLS_HANDSHAKING: @client is about to begin a TLS
817
   *   handshake. @connection is a #GTlsClientConnection.
818
   *
819
   * - %G_SOCKET_CLIENT_TLS_HANDSHAKED: @client has successfully completed
820
   *   the TLS handshake. @connection is a #GTlsClientConnection.
821
   *
822
   * - %G_SOCKET_CLIENT_COMPLETE: @client has either successfully connected
823
   *   to @connectable (in which case @connection is the #GSocketConnection
824
   *   that it will be returning to the caller) or has failed (in which
825
   *   case @connection is %NULL and the client is about to return an error).
826
   *
827
   * Each event except %G_SOCKET_CLIENT_COMPLETE may be emitted
828
   * multiple times (or not at all) for a given connectable (in
829
   * particular, if @client ends up attempting to connect to more than
830
   * one address). However, if @client emits the #GSocketClient::event
831
   * signal at all for a given connectable, then it will always emit
832
   * it with %G_SOCKET_CLIENT_COMPLETE when it is done.
833
   *
834
   * Note that there may be additional #GSocketClientEvent values in
835
   * the future; unrecognized @event values should be ignored.
836
   *
837
   * Since: 2.32
838
   */
839
0
  signals[EVENT] =
840
0
    g_signal_new (I_("event"),
841
0
      G_TYPE_FROM_CLASS (gobject_class),
842
0
      G_SIGNAL_RUN_LAST,
843
0
      G_STRUCT_OFFSET (GSocketClientClass, event),
844
0
      NULL, NULL,
845
0
      _g_cclosure_marshal_VOID__ENUM_OBJECT_OBJECT,
846
0
      G_TYPE_NONE, 3,
847
0
      G_TYPE_SOCKET_CLIENT_EVENT,
848
0
      G_TYPE_SOCKET_CONNECTABLE,
849
0
      G_TYPE_IO_STREAM);
850
0
  g_signal_set_va_marshaller (signals[EVENT],
851
0
                              G_TYPE_FROM_CLASS (class),
852
0
                              _g_cclosure_marshal_VOID__ENUM_OBJECT_OBJECTv);
853
854
0
  g_object_class_install_property (gobject_class, PROP_FAMILY,
855
0
           g_param_spec_enum ("family",
856
0
                  P_("Socket family"),
857
0
                  P_("The sockets address family to use for socket construction"),
858
0
                  G_TYPE_SOCKET_FAMILY,
859
0
                  G_SOCKET_FAMILY_INVALID,
860
0
                  G_PARAM_CONSTRUCT |
861
0
                                                      G_PARAM_READWRITE |
862
0
                                                      G_PARAM_STATIC_STRINGS));
863
864
0
  g_object_class_install_property (gobject_class, PROP_TYPE,
865
0
           g_param_spec_enum ("type",
866
0
                  P_("Socket type"),
867
0
                  P_("The sockets type to use for socket construction"),
868
0
                  G_TYPE_SOCKET_TYPE,
869
0
                  G_SOCKET_TYPE_STREAM,
870
0
                  G_PARAM_CONSTRUCT |
871
0
                                                      G_PARAM_READWRITE |
872
0
                                                      G_PARAM_STATIC_STRINGS));
873
874
0
  g_object_class_install_property (gobject_class, PROP_PROTOCOL,
875
0
           g_param_spec_enum ("protocol",
876
0
                  P_("Socket protocol"),
877
0
                  P_("The protocol to use for socket construction, or 0 for default"),
878
0
                  G_TYPE_SOCKET_PROTOCOL,
879
0
                  G_SOCKET_PROTOCOL_DEFAULT,
880
0
                  G_PARAM_CONSTRUCT |
881
0
                                                      G_PARAM_READWRITE |
882
0
                                                      G_PARAM_STATIC_STRINGS));
883
884
0
  g_object_class_install_property (gobject_class, PROP_LOCAL_ADDRESS,
885
0
           g_param_spec_object ("local-address",
886
0
              P_("Local address"),
887
0
              P_("The local address constructed sockets will be bound to"),
888
0
              G_TYPE_SOCKET_ADDRESS,
889
0
              G_PARAM_CONSTRUCT |
890
0
                                                        G_PARAM_READWRITE |
891
0
                                                        G_PARAM_STATIC_STRINGS));
892
893
0
  g_object_class_install_property (gobject_class, PROP_TIMEOUT,
894
0
           g_param_spec_uint ("timeout",
895
0
                  P_("Socket timeout"),
896
0
                  P_("The I/O timeout for sockets, or 0 for none"),
897
0
                  0, G_MAXUINT, 0,
898
0
                  G_PARAM_CONSTRUCT |
899
0
                                                      G_PARAM_READWRITE |
900
0
                                                      G_PARAM_STATIC_STRINGS));
901
902
0
   g_object_class_install_property (gobject_class, PROP_ENABLE_PROXY,
903
0
            g_param_spec_boolean ("enable-proxy",
904
0
                P_("Enable proxy"),
905
0
                P_("Enable proxy support"),
906
0
                TRUE,
907
0
                G_PARAM_CONSTRUCT |
908
0
                G_PARAM_READWRITE |
909
0
                G_PARAM_STATIC_STRINGS));
910
911
0
  g_object_class_install_property (gobject_class, PROP_TLS,
912
0
           g_param_spec_boolean ("tls",
913
0
               P_("TLS"),
914
0
               P_("Whether to create TLS connections"),
915
0
               FALSE,
916
0
               G_PARAM_CONSTRUCT |
917
0
               G_PARAM_READWRITE |
918
0
               G_PARAM_STATIC_STRINGS));
919
0
  g_object_class_install_property (gobject_class, PROP_TLS_VALIDATION_FLAGS,
920
0
           g_param_spec_flags ("tls-validation-flags",
921
0
                   P_("TLS validation flags"),
922
0
                   P_("TLS validation flags to use"),
923
0
                   G_TYPE_TLS_CERTIFICATE_FLAGS,
924
0
                   G_TLS_CERTIFICATE_VALIDATE_ALL,
925
0
                   G_PARAM_CONSTRUCT |
926
0
                   G_PARAM_READWRITE |
927
0
                   G_PARAM_STATIC_STRINGS));
928
929
  /**
930
   * GSocketClient:proxy-resolver:
931
   *
932
   * The proxy resolver to use
933
   *
934
   * Since: 2.36
935
   */
936
0
  g_object_class_install_property (gobject_class, PROP_PROXY_RESOLVER,
937
0
                                   g_param_spec_object ("proxy-resolver",
938
0
                                                        P_("Proxy resolver"),
939
0
                                                        P_("The proxy resolver to use"),
940
0
                                                        G_TYPE_PROXY_RESOLVER,
941
0
                                                        G_PARAM_CONSTRUCT |
942
0
                                                        G_PARAM_READWRITE |
943
0
                                                        G_PARAM_STATIC_STRINGS));
944
0
}
945
946
static void
947
g_socket_client_emit_event (GSocketClient       *client,
948
          GSocketClientEvent   event,
949
          GSocketConnectable  *connectable,
950
          GIOStream           *connection)
951
0
{
952
0
  g_signal_emit (client, signals[EVENT], 0,
953
0
     event, connectable, connection);
954
0
}
955
956
/* Originally, GSocketClient returned whatever error occured last. Turns
957
 * out this doesn't work well in practice. Consider the following case:
958
 * DNS returns an IPv4 and IPv6 address. First we'll connect() to the
959
 * IPv4 address, and say that succeeds, but TLS is enabled and the TLS
960
 * handshake fails. Then we try the IPv6 address and receive ENETUNREACH
961
 * because IPv6 isn't supported. We wind up returning NETWORK_UNREACHABLE
962
 * even though the address can be pinged and a TLS error would be more
963
 * appropriate. So instead, we now try to return the error corresponding
964
 * to the latest attempted GSocketClientEvent in the connection process.
965
 * TLS errors take precedence over proxy errors, which take precedence
966
 * over connect() errors, which take precedence over DNS errors.
967
 *
968
 * Note that the example above considers a sync codepath, but this is an
969
 * issue for the async codepath too, where events and errors may occur
970
 * in confusing orders.
971
 */
972
typedef struct
973
{
974
  GError *tmp_error;
975
  GError *best_error;
976
  GSocketClientEvent best_error_event;
977
} SocketClientErrorInfo;
978
979
static SocketClientErrorInfo *
980
socket_client_error_info_new (void)
981
0
{
982
0
  return g_new0 (SocketClientErrorInfo, 1);
983
0
}
984
985
static void
986
socket_client_error_info_free (SocketClientErrorInfo *info)
987
0
{
988
0
  g_assert (info->tmp_error == NULL);
989
0
  g_clear_error (&info->best_error);
990
0
  g_free (info);
991
0
}
992
993
static void
994
consider_tmp_error (SocketClientErrorInfo *info,
995
                    GSocketClientEvent     event)
996
0
{
997
0
  if (info->tmp_error == NULL)
998
0
    return;
999
1000
  /* If we ever add more GSocketClientEvents in the future, then we'll
1001
   * no longer be able to use >= for this comparison, because future
1002
   * events will compare greater than G_SOCKET_CLIENT_COMPLETE. Until
1003
   * then, this is convenient. Note G_SOCKET_CLIENT_RESOLVING is 0 so we
1004
   * need to use >= here or those errors would never be set. That means
1005
   * if we get two errors on the same GSocketClientEvent, we wind up
1006
   * preferring the last one, which is fine.
1007
   */
1008
0
  g_assert (event <= G_SOCKET_CLIENT_COMPLETE);
1009
0
  if (event >= info->best_error_event)
1010
0
    {
1011
0
      g_clear_error (&info->best_error);
1012
0
      info->best_error = info->tmp_error;
1013
0
      info->tmp_error = NULL;
1014
0
      info->best_error_event = event;
1015
0
    }
1016
0
  else
1017
0
    {
1018
0
      g_clear_error (&info->tmp_error);
1019
0
    }
1020
0
}
1021
1022
/**
1023
 * g_socket_client_connect:
1024
 * @client: a #GSocketClient.
1025
 * @connectable: a #GSocketConnectable specifying the remote address.
1026
 * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
1027
 * @error: #GError for error reporting, or %NULL to ignore.
1028
 *
1029
 * Tries to resolve the @connectable and make a network connection to it.
1030
 *
1031
 * Upon a successful connection, a new #GSocketConnection is constructed
1032
 * and returned.  The caller owns this new object and must drop their
1033
 * reference to it when finished with it.
1034
 *
1035
 * The type of the #GSocketConnection object returned depends on the type of
1036
 * the underlying socket that is used. For instance, for a TCP/IP connection
1037
 * it will be a #GTcpConnection.
1038
 *
1039
 * The socket created will be the same family as the address that the
1040
 * @connectable resolves to, unless family is set with g_socket_client_set_family()
1041
 * or indirectly via g_socket_client_set_local_address(). The socket type
1042
 * defaults to %G_SOCKET_TYPE_STREAM but can be set with
1043
 * g_socket_client_set_socket_type().
1044
 *
1045
 * If a local address is specified with g_socket_client_set_local_address() the
1046
 * socket will be bound to this address before connecting.
1047
 *
1048
 * Returns: (transfer full): a #GSocketConnection on success, %NULL on error.
1049
 *
1050
 * Since: 2.22
1051
 */
1052
GSocketConnection *
1053
g_socket_client_connect (GSocketClient       *client,
1054
       GSocketConnectable  *connectable,
1055
       GCancellable        *cancellable,
1056
       GError             **error)
1057
0
{
1058
0
  GIOStream *connection = NULL;
1059
0
  GSocketAddressEnumerator *enumerator = NULL;
1060
0
  SocketClientErrorInfo *error_info;
1061
0
  gboolean ever_resolved = FALSE;
1062
1063
0
  error_info = socket_client_error_info_new ();
1064
1065
0
  if (can_use_proxy (client))
1066
0
    {
1067
0
      enumerator = g_socket_connectable_proxy_enumerate (connectable);
1068
0
      if (client->priv->proxy_resolver &&
1069
0
          G_IS_PROXY_ADDRESS_ENUMERATOR (enumerator))
1070
0
        {
1071
0
          g_object_set (G_OBJECT (enumerator),
1072
0
                        "proxy-resolver", client->priv->proxy_resolver,
1073
0
                        NULL);
1074
0
        }
1075
0
    }
1076
0
  else
1077
0
    enumerator = g_socket_connectable_enumerate (connectable);
1078
1079
0
  while (connection == NULL)
1080
0
    {
1081
0
      GSocketAddress *address = NULL;
1082
0
      gboolean application_proxy = FALSE;
1083
0
      GSocket *socket;
1084
0
      gboolean using_proxy;
1085
1086
0
      if (g_cancellable_is_cancelled (cancellable))
1087
0
  {
1088
0
    g_clear_error (&error_info->best_error);
1089
0
    g_cancellable_set_error_if_cancelled (cancellable, &error_info->best_error);
1090
0
    break;
1091
0
  }
1092
1093
0
      if (!ever_resolved)
1094
0
  {
1095
0
    g_socket_client_emit_event (client, G_SOCKET_CLIENT_RESOLVING,
1096
0
              connectable, NULL);
1097
0
  }
1098
0
      address = g_socket_address_enumerator_next (enumerator, cancellable,
1099
0
              &error_info->tmp_error);
1100
0
      consider_tmp_error (error_info, G_SOCKET_CLIENT_RESOLVING);
1101
0
      if (!ever_resolved)
1102
0
  {
1103
0
    g_socket_client_emit_event (client, G_SOCKET_CLIENT_RESOLVED,
1104
0
              connectable, NULL);
1105
0
    ever_resolved = TRUE;
1106
0
  }
1107
1108
0
      if (address == NULL)
1109
0
  {
1110
          /* Enumeration is finished. */
1111
0
          g_assert (&error_info->best_error != NULL);
1112
0
    break;
1113
0
  }
1114
1115
0
      using_proxy = (G_IS_PROXY_ADDRESS (address) &&
1116
0
         client->priv->enable_proxy);
1117
1118
0
      socket = create_socket (client, address, &error_info->tmp_error);
1119
0
      consider_tmp_error (error_info, G_SOCKET_CLIENT_CONNECTING);
1120
0
      if (socket == NULL)
1121
0
  {
1122
0
    g_object_unref (address);
1123
0
    continue;
1124
0
  }
1125
1126
0
      connection = (GIOStream *)g_socket_connection_factory_create_connection (socket);
1127
0
      g_socket_connection_set_cached_remote_address ((GSocketConnection*)connection, address);
1128
0
      g_socket_client_emit_event (client, G_SOCKET_CLIENT_CONNECTING, connectable, connection);
1129
1130
0
      if (g_socket_connection_connect (G_SOCKET_CONNECTION (connection),
1131
0
               address, cancellable, &error_info->tmp_error))
1132
0
  {
1133
0
          g_socket_connection_set_cached_remote_address ((GSocketConnection*)connection, NULL);
1134
0
    g_socket_client_emit_event (client, G_SOCKET_CLIENT_CONNECTED, connectable, connection);
1135
0
  }
1136
0
      else
1137
0
  {
1138
0
    clarify_connect_error (error_info->tmp_error, connectable, address);
1139
0
          consider_tmp_error (error_info, G_SOCKET_CLIENT_CONNECTING);
1140
0
    g_object_unref (connection);
1141
0
    connection = NULL;
1142
0
  }
1143
1144
0
      if (connection && using_proxy)
1145
0
  {
1146
0
    GProxyAddress *proxy_addr = G_PROXY_ADDRESS (address);
1147
0
    const gchar *protocol;
1148
0
    GProxy *proxy;
1149
1150
0
    protocol = g_proxy_address_get_protocol (proxy_addr);
1151
1152
          /* The connection should not be anything else then TCP Connection,
1153
           * but let's put a safety guard in case
1154
     */
1155
0
          if (!G_IS_TCP_CONNECTION (connection))
1156
0
            {
1157
0
              g_critical ("Trying to proxy over non-TCP connection, this is "
1158
0
                          "most likely a bug in GLib IO library.");
1159
1160
0
              g_set_error_literal (&error_info->tmp_error,
1161
0
                  G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
1162
0
                  _("Proxying over a non-TCP connection is not supported."));
1163
0
              consider_tmp_error (error_info, G_SOCKET_CLIENT_PROXY_NEGOTIATING);
1164
1165
0
        g_object_unref (connection);
1166
0
        connection = NULL;
1167
0
            }
1168
0
    else if (g_hash_table_contains (client->priv->app_proxies, protocol))
1169
0
      {
1170
0
        application_proxy = TRUE;
1171
0
      }
1172
0
          else if ((proxy = g_proxy_get_default_for_protocol (protocol)))
1173
0
      {
1174
0
        GIOStream *proxy_connection;
1175
1176
0
        g_socket_client_emit_event (client, G_SOCKET_CLIENT_PROXY_NEGOTIATING, connectable, connection);
1177
0
        proxy_connection = g_proxy_connect (proxy,
1178
0
              connection,
1179
0
              proxy_addr,
1180
0
              cancellable,
1181
0
              &error_info->tmp_error);
1182
0
        consider_tmp_error (error_info, G_SOCKET_CLIENT_PROXY_NEGOTIATING);
1183
1184
0
        g_object_unref (connection);
1185
0
        connection = proxy_connection;
1186
0
        g_object_unref (proxy);
1187
1188
0
        if (connection)
1189
0
    g_socket_client_emit_event (client, G_SOCKET_CLIENT_PROXY_NEGOTIATED, connectable, connection);
1190
0
      }
1191
0
    else
1192
0
      {
1193
0
        g_set_error (&error_info->tmp_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
1194
0
         _("Proxy protocol “%s” is not supported."),
1195
0
         protocol);
1196
0
        consider_tmp_error (error_info, G_SOCKET_CLIENT_PROXY_NEGOTIATING);
1197
0
        g_object_unref (connection);
1198
0
        connection = NULL;
1199
0
      }
1200
0
  }
1201
1202
0
      if (!application_proxy && connection && client->priv->tls)
1203
0
  {
1204
0
    GIOStream *tlsconn;
1205
1206
0
    tlsconn = g_tls_client_connection_new (connection, connectable, &error_info->tmp_error);
1207
0
    g_object_unref (connection);
1208
0
    connection = tlsconn;
1209
1210
0
    if (tlsconn)
1211
0
      {
1212
0
        g_tls_client_connection_set_validation_flags (G_TLS_CLIENT_CONNECTION (tlsconn),
1213
0
                                                            client->priv->tls_validation_flags);
1214
0
        g_socket_client_emit_event (client, G_SOCKET_CLIENT_TLS_HANDSHAKING, connectable, connection);
1215
0
        if (g_tls_connection_handshake (G_TLS_CONNECTION (tlsconn),
1216
0
                cancellable, &error_info->tmp_error))
1217
0
    {
1218
0
      g_socket_client_emit_event (client, G_SOCKET_CLIENT_TLS_HANDSHAKED, connectable, connection);
1219
0
    }
1220
0
        else
1221
0
    {
1222
0
      consider_tmp_error (error_info, G_SOCKET_CLIENT_TLS_HANDSHAKING);
1223
0
      g_object_unref (tlsconn);
1224
0
      connection = NULL;
1225
0
    }
1226
0
      }
1227
0
          else
1228
0
            {
1229
0
              consider_tmp_error (error_info, G_SOCKET_CLIENT_TLS_HANDSHAKING);
1230
0
            }
1231
0
  }
1232
1233
0
      if (connection && !G_IS_SOCKET_CONNECTION (connection))
1234
0
  {
1235
0
    GSocketConnection *wrapper_connection;
1236
1237
0
    wrapper_connection = g_tcp_wrapper_connection_new (connection, socket);
1238
0
    g_object_unref (connection);
1239
0
    connection = (GIOStream *)wrapper_connection;
1240
0
  }
1241
1242
0
      g_object_unref (socket);
1243
0
      g_object_unref (address);
1244
0
    }
1245
0
  g_object_unref (enumerator);
1246
1247
0
  if (!connection)
1248
0
    g_propagate_error (error, g_steal_pointer (&error_info->best_error));
1249
0
  socket_client_error_info_free (error_info);
1250
1251
0
  g_socket_client_emit_event (client, G_SOCKET_CLIENT_COMPLETE, connectable, connection);
1252
0
  return G_SOCKET_CONNECTION (connection);
1253
0
}
1254
1255
/**
1256
 * g_socket_client_connect_to_host:
1257
 * @client: a #GSocketClient
1258
 * @host_and_port: the name and optionally port of the host to connect to
1259
 * @default_port: the default port to connect to
1260
 * @cancellable: (nullable): a #GCancellable, or %NULL
1261
 * @error: a pointer to a #GError, or %NULL
1262
 *
1263
 * This is a helper function for g_socket_client_connect().
1264
 *
1265
 * Attempts to create a TCP connection to the named host.
1266
 *
1267
 * @host_and_port may be in any of a number of recognized formats; an IPv6
1268
 * address, an IPv4 address, or a domain name (in which case a DNS
1269
 * lookup is performed).  Quoting with [] is supported for all address
1270
 * types.  A port override may be specified in the usual way with a
1271
 * colon.  Ports may be given as decimal numbers or symbolic names (in
1272
 * which case an /etc/services lookup is performed).
1273
 *
1274
 * If no port override is given in @host_and_port then @default_port will be
1275
 * used as the port number to connect to.
1276
 *
1277
 * In general, @host_and_port is expected to be provided by the user (allowing
1278
 * them to give the hostname, and a port override if necessary) and
1279
 * @default_port is expected to be provided by the application.
1280
 *
1281
 * In the case that an IP address is given, a single connection
1282
 * attempt is made.  In the case that a name is given, multiple
1283
 * connection attempts may be made, in turn and according to the
1284
 * number of address records in DNS, until a connection succeeds.
1285
 *
1286
 * Upon a successful connection, a new #GSocketConnection is constructed
1287
 * and returned.  The caller owns this new object and must drop their
1288
 * reference to it when finished with it.
1289
 *
1290
 * In the event of any failure (DNS error, service not found, no hosts
1291
 * connectable) %NULL is returned and @error (if non-%NULL) is set
1292
 * accordingly.
1293
 *
1294
 * Returns: (transfer full): a #GSocketConnection on success, %NULL on error.
1295
 *
1296
 * Since: 2.22
1297
 */
1298
GSocketConnection *
1299
g_socket_client_connect_to_host (GSocketClient  *client,
1300
         const gchar    *host_and_port,
1301
         guint16         default_port,
1302
         GCancellable   *cancellable,
1303
         GError        **error)
1304
0
{
1305
0
  GSocketConnectable *connectable;
1306
0
  GSocketConnection *connection;
1307
1308
0
  connectable = g_network_address_parse (host_and_port, default_port, error);
1309
0
  if (connectable == NULL)
1310
0
    return NULL;
1311
1312
0
  connection = g_socket_client_connect (client, connectable,
1313
0
          cancellable, error);
1314
0
  g_object_unref (connectable);
1315
1316
0
  return connection;
1317
0
}
1318
1319
/**
1320
 * g_socket_client_connect_to_service:
1321
 * @client: a #GSocketConnection
1322
 * @domain: a domain name
1323
 * @service: the name of the service to connect to
1324
 * @cancellable: (nullable): a #GCancellable, or %NULL
1325
 * @error: a pointer to a #GError, or %NULL
1326
 *
1327
 * Attempts to create a TCP connection to a service.
1328
 *
1329
 * This call looks up the SRV record for @service at @domain for the
1330
 * "tcp" protocol.  It then attempts to connect, in turn, to each of
1331
 * the hosts providing the service until either a connection succeeds
1332
 * or there are no hosts remaining.
1333
 *
1334
 * Upon a successful connection, a new #GSocketConnection is constructed
1335
 * and returned.  The caller owns this new object and must drop their
1336
 * reference to it when finished with it.
1337
 *
1338
 * In the event of any failure (DNS error, service not found, no hosts
1339
 * connectable) %NULL is returned and @error (if non-%NULL) is set
1340
 * accordingly.
1341
 *
1342
 * Returns: (transfer full): a #GSocketConnection if successful, or %NULL on error
1343
 */
1344
GSocketConnection *
1345
g_socket_client_connect_to_service (GSocketClient  *client,
1346
            const gchar    *domain,
1347
            const gchar    *service,
1348
            GCancellable   *cancellable,
1349
            GError        **error)
1350
0
{
1351
0
  GSocketConnectable *connectable;
1352
0
  GSocketConnection *connection;
1353
1354
0
  connectable = g_network_service_new (service, "tcp", domain);
1355
0
  connection = g_socket_client_connect (client, connectable,
1356
0
          cancellable, error);
1357
0
  g_object_unref (connectable);
1358
1359
0
  return connection;
1360
0
}
1361
1362
/**
1363
 * g_socket_client_connect_to_uri:
1364
 * @client: a #GSocketClient
1365
 * @uri: A network URI
1366
 * @default_port: the default port to connect to
1367
 * @cancellable: (nullable): a #GCancellable, or %NULL
1368
 * @error: a pointer to a #GError, or %NULL
1369
 *
1370
 * This is a helper function for g_socket_client_connect().
1371
 *
1372
 * Attempts to create a TCP connection with a network URI.
1373
 *
1374
 * @uri may be any valid URI containing an "authority" (hostname/port)
1375
 * component. If a port is not specified in the URI, @default_port
1376
 * will be used. TLS will be negotiated if #GSocketClient:tls is %TRUE.
1377
 * (#GSocketClient does not know to automatically assume TLS for
1378
 * certain URI schemes.)
1379
 *
1380
 * Using this rather than g_socket_client_connect() or
1381
 * g_socket_client_connect_to_host() allows #GSocketClient to
1382
 * determine when to use application-specific proxy protocols.
1383
 *
1384
 * Upon a successful connection, a new #GSocketConnection is constructed
1385
 * and returned.  The caller owns this new object and must drop their
1386
 * reference to it when finished with it.
1387
 *
1388
 * In the event of any failure (DNS error, service not found, no hosts
1389
 * connectable) %NULL is returned and @error (if non-%NULL) is set
1390
 * accordingly.
1391
 *
1392
 * Returns: (transfer full): a #GSocketConnection on success, %NULL on error.
1393
 *
1394
 * Since: 2.26
1395
 */
1396
GSocketConnection *
1397
g_socket_client_connect_to_uri (GSocketClient  *client,
1398
        const gchar    *uri,
1399
        guint16         default_port,
1400
        GCancellable   *cancellable,
1401
        GError        **error)
1402
0
{
1403
0
  GSocketConnectable *connectable;
1404
0
  GSocketConnection *connection;
1405
1406
0
  connectable = g_network_address_parse_uri (uri, default_port, error);
1407
0
  if (connectable == NULL)
1408
0
    return NULL;
1409
1410
0
  connection = g_socket_client_connect (client, connectable,
1411
0
          cancellable, error);
1412
0
  g_object_unref (connectable);
1413
1414
0
  return connection;
1415
0
}
1416
1417
typedef struct
1418
{
1419
  GTask *task; /* unowned */
1420
  GSocketClient *client;
1421
1422
  GSocketConnectable *connectable;
1423
  GSocketAddressEnumerator *enumerator;
1424
  GCancellable *enumeration_cancellable;
1425
1426
  GSList *connection_attempts;
1427
  GSList *successful_connections;
1428
  SocketClientErrorInfo *error_info;
1429
1430
  gboolean enumerated_at_least_once;
1431
  gboolean enumeration_completed;
1432
  gboolean connection_in_progress;
1433
  gboolean completed;
1434
} GSocketClientAsyncConnectData;
1435
1436
static void connection_attempt_unref (gpointer attempt);
1437
1438
static void
1439
g_socket_client_async_connect_data_free (GSocketClientAsyncConnectData *data)
1440
0
{
1441
0
  data->task = NULL;
1442
0
  g_clear_object (&data->connectable);
1443
0
  g_clear_object (&data->enumerator);
1444
0
  g_clear_object (&data->enumeration_cancellable);
1445
0
  g_slist_free_full (data->connection_attempts, connection_attempt_unref);
1446
0
  g_slist_free_full (data->successful_connections, connection_attempt_unref);
1447
1448
0
  g_clear_pointer (&data->error_info, socket_client_error_info_free);
1449
1450
0
  g_slice_free (GSocketClientAsyncConnectData, data);
1451
0
}
1452
1453
typedef struct
1454
{
1455
  GSocketAddress *address;
1456
  GSocket *socket;
1457
  GIOStream *connection;
1458
  GProxyAddress *proxy_addr;
1459
  GSocketClientAsyncConnectData *data; /* unowned */
1460
  GSource *timeout_source;
1461
  GCancellable *cancellable;
1462
  grefcount ref;
1463
} ConnectionAttempt;
1464
1465
static ConnectionAttempt *
1466
connection_attempt_new (void)
1467
0
{
1468
0
  ConnectionAttempt *attempt = g_new0 (ConnectionAttempt, 1);
1469
0
  g_ref_count_init (&attempt->ref);
1470
0
  return attempt;
1471
0
}
1472
1473
static ConnectionAttempt *
1474
connection_attempt_ref (ConnectionAttempt *attempt)
1475
0
{
1476
0
  g_ref_count_inc (&attempt->ref);
1477
0
  return attempt;
1478
0
}
1479
1480
static void
1481
connection_attempt_unref (gpointer pointer)
1482
0
{
1483
0
  ConnectionAttempt *attempt = pointer;
1484
0
  if (g_ref_count_dec (&attempt->ref))
1485
0
    {
1486
0
      g_clear_object (&attempt->address);
1487
0
      g_clear_object (&attempt->socket);
1488
0
      g_clear_object (&attempt->connection);
1489
0
      g_clear_object (&attempt->cancellable);
1490
0
      g_clear_object (&attempt->proxy_addr);
1491
0
      if (attempt->timeout_source)
1492
0
        {
1493
0
          g_source_destroy (attempt->timeout_source);
1494
0
          g_source_unref (attempt->timeout_source);
1495
0
        }
1496
0
      g_free (attempt);
1497
0
    }
1498
0
}
1499
1500
static void
1501
connection_attempt_remove (ConnectionAttempt *attempt)
1502
0
{
1503
0
  attempt->data->connection_attempts = g_slist_remove (attempt->data->connection_attempts, attempt);
1504
0
  connection_attempt_unref (attempt);
1505
0
}
1506
1507
static void
1508
cancel_all_attempts (GSocketClientAsyncConnectData *data)
1509
0
{
1510
0
  GSList *l;
1511
1512
0
  for (l = data->connection_attempts; l; l = g_slist_next (l))
1513
0
    {
1514
0
      ConnectionAttempt *attempt_entry = l->data;
1515
0
      g_cancellable_cancel (attempt_entry->cancellable);
1516
0
      connection_attempt_unref (attempt_entry);
1517
0
    }
1518
0
  g_slist_free (data->connection_attempts);
1519
0
  data->connection_attempts = NULL;
1520
1521
0
  g_slist_free_full (data->successful_connections, connection_attempt_unref);
1522
0
  data->successful_connections = NULL;
1523
1524
0
  g_cancellable_cancel (data->enumeration_cancellable);
1525
0
}
1526
1527
static void
1528
g_socket_client_async_connect_complete (ConnectionAttempt *attempt)
1529
0
{
1530
0
  GSocketClientAsyncConnectData *data = attempt->data;
1531
0
  GError *error = NULL;
1532
0
  g_assert (attempt->connection);
1533
0
  g_assert (!data->completed);
1534
1535
0
  if (!G_IS_SOCKET_CONNECTION (attempt->connection))
1536
0
    {
1537
0
      GSocketConnection *wrapper_connection;
1538
1539
0
      wrapper_connection = g_tcp_wrapper_connection_new (attempt->connection, attempt->socket);
1540
0
      g_object_unref (attempt->connection);
1541
0
      attempt->connection = (GIOStream *)wrapper_connection;
1542
0
    }
1543
1544
0
  data->completed = TRUE;
1545
0
  cancel_all_attempts (data);
1546
1547
0
  if (g_cancellable_set_error_if_cancelled (g_task_get_cancellable (data->task), &error))
1548
0
    {
1549
0
      g_debug ("GSocketClient: Connection cancelled!");
1550
0
      g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_COMPLETE, data->connectable, NULL);
1551
0
      g_task_return_error (data->task, g_steal_pointer (&error));
1552
0
    }
1553
0
  else
1554
0
    {
1555
0
      g_debug ("GSocketClient: Connection successful!");
1556
0
      g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_COMPLETE, data->connectable, attempt->connection);
1557
0
      g_task_return_pointer (data->task, g_steal_pointer (&attempt->connection), g_object_unref);
1558
0
    }
1559
1560
0
  connection_attempt_unref (attempt);
1561
0
  g_object_unref (data->task);
1562
0
}
1563
1564
1565
static void
1566
g_socket_client_enumerator_callback (GObject      *object,
1567
             GAsyncResult *result,
1568
             gpointer      user_data);
1569
1570
static void
1571
enumerator_next_async (GSocketClientAsyncConnectData *data,
1572
                       gboolean                       add_task_ref)
1573
0
{
1574
  /* Each enumeration takes a ref. This arg just avoids repeated unrefs when
1575
     an enumeration starts another enumeration */
1576
0
  if (add_task_ref)
1577
0
    g_object_ref (data->task);
1578
1579
0
  if (!data->enumerated_at_least_once)
1580
0
    g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_RESOLVING, data->connectable, NULL);
1581
0
  g_debug ("GSocketClient: Starting new address enumeration");
1582
0
  g_socket_address_enumerator_next_async (data->enumerator,
1583
0
            data->enumeration_cancellable,
1584
0
            g_socket_client_enumerator_callback,
1585
0
            data);
1586
0
}
1587
1588
static void try_next_connection_or_finish (GSocketClientAsyncConnectData *, gboolean);
1589
1590
static void
1591
g_socket_client_tls_handshake_callback (GObject      *object,
1592
          GAsyncResult *result,
1593
          gpointer      user_data)
1594
0
{
1595
0
  ConnectionAttempt *attempt = user_data;
1596
0
  GSocketClientAsyncConnectData *data = attempt->data;
1597
1598
0
  if (g_tls_connection_handshake_finish (G_TLS_CONNECTION (object),
1599
0
           result,
1600
0
           &data->error_info->tmp_error))
1601
0
    {
1602
0
      g_object_unref (attempt->connection);
1603
0
      attempt->connection = G_IO_STREAM (object);
1604
1605
0
      g_debug ("GSocketClient: TLS handshake succeeded");
1606
0
      g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_TLS_HANDSHAKED, data->connectable, attempt->connection);
1607
0
      g_socket_client_async_connect_complete (attempt);
1608
0
    }
1609
0
  else
1610
0
    {
1611
0
      g_object_unref (object);
1612
0
      connection_attempt_unref (attempt);
1613
1614
0
      g_debug ("GSocketClient: TLS handshake failed: %s", data->error_info->tmp_error->message);
1615
0
      consider_tmp_error (data->error_info, G_SOCKET_CLIENT_TLS_HANDSHAKING);
1616
0
      try_next_connection_or_finish (data, TRUE);
1617
0
    }
1618
0
}
1619
1620
static void
1621
g_socket_client_tls_handshake (ConnectionAttempt *attempt)
1622
0
{
1623
0
  GSocketClientAsyncConnectData *data = attempt->data;
1624
0
  GIOStream *tlsconn;
1625
1626
0
  if (!data->client->priv->tls)
1627
0
    {
1628
0
      g_socket_client_async_connect_complete (attempt);
1629
0
      return;
1630
0
    }
1631
1632
0
  g_debug ("GSocketClient: Starting TLS handshake");
1633
0
  tlsconn = g_tls_client_connection_new (attempt->connection,
1634
0
           data->connectable,
1635
0
           &data->error_info->tmp_error);
1636
0
  if (tlsconn)
1637
0
    {
1638
0
      g_tls_client_connection_set_validation_flags (G_TLS_CLIENT_CONNECTION (tlsconn),
1639
0
                                                    data->client->priv->tls_validation_flags);
1640
0
      g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_TLS_HANDSHAKING, data->connectable, G_IO_STREAM (tlsconn));
1641
0
      g_tls_connection_handshake_async (G_TLS_CONNECTION (tlsconn),
1642
0
          G_PRIORITY_DEFAULT,
1643
0
          g_task_get_cancellable (data->task),
1644
0
          g_socket_client_tls_handshake_callback,
1645
0
          attempt);
1646
0
    }
1647
0
  else
1648
0
    {
1649
0
      connection_attempt_unref (attempt);
1650
1651
0
      consider_tmp_error (data->error_info, G_SOCKET_CLIENT_TLS_HANDSHAKING);
1652
0
      try_next_connection_or_finish (data, TRUE);
1653
0
    }
1654
0
}
1655
1656
static void
1657
g_socket_client_proxy_connect_callback (GObject      *object,
1658
          GAsyncResult *result,
1659
          gpointer      user_data)
1660
0
{
1661
0
  ConnectionAttempt *attempt = user_data;
1662
0
  GSocketClientAsyncConnectData *data = attempt->data;
1663
1664
0
  g_object_unref (attempt->connection);
1665
0
  attempt->connection = g_proxy_connect_finish (G_PROXY (object),
1666
0
                                                result,
1667
0
                                                &data->error_info->tmp_error);
1668
0
  if (attempt->connection)
1669
0
    {
1670
0
      g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_PROXY_NEGOTIATED, data->connectable, attempt->connection);
1671
0
      g_socket_client_tls_handshake (attempt);
1672
0
    }
1673
0
  else
1674
0
    {
1675
0
      connection_attempt_unref (attempt);
1676
1677
0
      consider_tmp_error (data->error_info, G_SOCKET_CLIENT_PROXY_NEGOTIATING);
1678
0
      try_next_connection_or_finish (data, TRUE);
1679
0
    }
1680
0
}
1681
1682
static void
1683
complete_connection_with_error (GSocketClientAsyncConnectData *data,
1684
                                GError                        *error)
1685
0
{
1686
0
  g_debug ("GSocketClient: Connection failed: %s", error->message);
1687
0
  g_assert (!data->completed);
1688
1689
0
  g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_COMPLETE, data->connectable, NULL);
1690
0
  data->completed = TRUE;
1691
0
  cancel_all_attempts (data);
1692
0
  g_task_return_error (data->task, error);
1693
0
}
1694
1695
static gboolean
1696
task_completed_or_cancelled (GSocketClientAsyncConnectData *data)
1697
0
{
1698
0
  GTask *task = data->task;
1699
0
  GCancellable *cancellable = g_task_get_cancellable (task);
1700
0
  GError *error = NULL;
1701
1702
0
  if (data->completed)
1703
0
    return TRUE;
1704
0
  else if (g_cancellable_set_error_if_cancelled (cancellable, &error))
1705
0
    {
1706
0
      complete_connection_with_error (data, g_steal_pointer (&error));
1707
0
      return TRUE;
1708
0
    }
1709
0
  else
1710
0
    return FALSE;
1711
0
}
1712
1713
static gboolean
1714
try_next_successful_connection (GSocketClientAsyncConnectData *data)
1715
0
{
1716
0
  ConnectionAttempt *attempt;
1717
0
  const gchar *protocol;
1718
0
  GProxy *proxy;
1719
1720
0
  if (data->connection_in_progress)
1721
0
    return FALSE;
1722
1723
0
  g_assert (data->successful_connections != NULL);
1724
0
  attempt = data->successful_connections->data;
1725
0
  g_assert (attempt != NULL);
1726
0
  data->successful_connections = g_slist_remove (data->successful_connections, attempt);
1727
0
  data->connection_in_progress = TRUE;
1728
1729
0
  g_debug ("GSocketClient: Starting application layer connection");
1730
1731
0
  if (!attempt->proxy_addr)
1732
0
    {
1733
0
      g_socket_client_tls_handshake (g_steal_pointer (&attempt));
1734
0
      return TRUE;
1735
0
    }
1736
1737
0
  protocol = g_proxy_address_get_protocol (attempt->proxy_addr);
1738
1739
  /* The connection should not be anything other than TCP,
1740
   * but let's put a safety guard in case
1741
   */
1742
0
  if (!G_IS_TCP_CONNECTION (attempt->connection))
1743
0
    {
1744
0
      g_critical ("Trying to proxy over non-TCP connection, this is "
1745
0
          "most likely a bug in GLib IO library.");
1746
1747
0
      g_set_error_literal (&data->error_info->tmp_error,
1748
0
          G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
1749
0
          _("Proxying over a non-TCP connection is not supported."));
1750
0
      consider_tmp_error (data->error_info, G_SOCKET_CLIENT_PROXY_NEGOTIATING);
1751
0
    }
1752
0
  else if (g_hash_table_contains (data->client->priv->app_proxies, protocol))
1753
0
    {
1754
      /* Simply complete the connection, we don't want to do TLS handshake
1755
       * as the application proxy handling may need proxy handshake first */
1756
0
      g_socket_client_async_connect_complete (g_steal_pointer (&attempt));
1757
0
      return TRUE;
1758
0
    }
1759
0
  else if ((proxy = g_proxy_get_default_for_protocol (protocol)))
1760
0
    {
1761
0
      GIOStream *connection = attempt->connection;
1762
0
      GProxyAddress *proxy_addr = attempt->proxy_addr;
1763
1764
0
      g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_PROXY_NEGOTIATING, data->connectable, attempt->connection);
1765
0
      g_debug ("GSocketClient: Starting proxy connection");
1766
0
      g_proxy_connect_async (proxy,
1767
0
                             connection,
1768
0
                             proxy_addr,
1769
0
                             g_task_get_cancellable (data->task),
1770
0
                             g_socket_client_proxy_connect_callback,
1771
0
                             g_steal_pointer (&attempt));
1772
0
      g_object_unref (proxy);
1773
0
      return TRUE;
1774
0
    }
1775
0
  else
1776
0
    {
1777
0
      g_set_error (&data->error_info->tmp_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
1778
0
          _("Proxy protocol “%s” is not supported."),
1779
0
          protocol);
1780
0
      consider_tmp_error (data->error_info, G_SOCKET_CLIENT_PROXY_NEGOTIATING);
1781
0
    }
1782
1783
0
  data->connection_in_progress = FALSE;
1784
0
  g_clear_pointer (&attempt, connection_attempt_unref);
1785
0
  return FALSE; /* All non-return paths are failures */
1786
0
}
1787
1788
static void
1789
try_next_connection_or_finish (GSocketClientAsyncConnectData *data,
1790
                               gboolean                       end_current_connection)
1791
0
{
1792
0
  if (end_current_connection)
1793
0
    data->connection_in_progress = FALSE;
1794
1795
0
  if (data->connection_in_progress)
1796
0
    return;
1797
1798
  /* Keep trying successful connections until one works, each iteration pops one */
1799
0
  while (data->successful_connections)
1800
0
    {
1801
0
      if (try_next_successful_connection (data))
1802
0
        return;
1803
0
    }
1804
1805
0
  if (!data->enumeration_completed)
1806
0
    {
1807
0
      enumerator_next_async (data, FALSE);
1808
0
      return;
1809
0
    }
1810
1811
0
  complete_connection_with_error (data, g_steal_pointer (&data->error_info->best_error));
1812
0
}
1813
1814
static void
1815
g_socket_client_connected_callback (GObject      *source,
1816
            GAsyncResult *result,
1817
            gpointer      user_data)
1818
0
{
1819
0
  ConnectionAttempt *attempt = user_data;
1820
0
  GSocketClientAsyncConnectData *data = attempt->data;
1821
1822
0
  if (task_completed_or_cancelled (data) || g_cancellable_is_cancelled (attempt->cancellable))
1823
0
    {
1824
0
      g_object_unref (data->task);
1825
0
      connection_attempt_unref (attempt);
1826
0
      return;
1827
0
    }
1828
1829
0
  if (attempt->timeout_source)
1830
0
    {
1831
0
      g_source_destroy (attempt->timeout_source);
1832
0
      g_clear_pointer (&attempt->timeout_source, g_source_unref);
1833
0
    }
1834
1835
0
  if (!g_socket_connection_connect_finish (G_SOCKET_CONNECTION (source),
1836
0
             result, &data->error_info->tmp_error))
1837
0
    {
1838
0
      if (!g_cancellable_is_cancelled (attempt->cancellable))
1839
0
        {
1840
0
          g_debug ("GSocketClient: Connection attempt failed: %s", data->error_info->tmp_error->message);
1841
0
          clarify_connect_error (data->error_info->tmp_error, data->connectable, attempt->address);
1842
0
          consider_tmp_error (data->error_info, G_SOCKET_CLIENT_CONNECTING);
1843
0
          connection_attempt_remove (attempt);
1844
0
          connection_attempt_unref (attempt);
1845
0
          try_next_connection_or_finish (data, FALSE);
1846
0
        }
1847
0
      else /* Silently ignore cancelled attempts */
1848
0
        {
1849
0
          g_clear_error (&data->error_info->tmp_error);
1850
0
          g_object_unref (data->task);
1851
0
          connection_attempt_unref (attempt);
1852
0
        }
1853
1854
0
      return;
1855
0
    }
1856
1857
0
  g_socket_connection_set_cached_remote_address ((GSocketConnection*)attempt->connection, NULL);
1858
0
  g_debug ("GSocketClient: TCP connection successful");
1859
0
  g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_CONNECTED, data->connectable, attempt->connection);
1860
1861
  /* wrong, but backward compatible */
1862
0
  g_socket_set_blocking (attempt->socket, TRUE);
1863
1864
  /* This ends the parallel "happy eyeballs" portion of connecting.
1865
     Now that we have a successful tcp connection we will attempt to connect
1866
     at the TLS/Proxy layer. If those layers fail we will move on to the next
1867
     connection.
1868
   */
1869
0
  connection_attempt_remove (attempt);
1870
0
  data->successful_connections = g_slist_append (data->successful_connections, g_steal_pointer (&attempt));
1871
0
  try_next_connection_or_finish (data, FALSE);
1872
0
}
1873
1874
static gboolean
1875
on_connection_attempt_timeout (gpointer data)
1876
0
{
1877
0
  ConnectionAttempt *attempt = data;
1878
1879
0
  if (!attempt->data->enumeration_completed)
1880
0
    {
1881
0
      g_debug ("GSocketClient: Timeout reached, trying another enumeration");
1882
0
      enumerator_next_async (attempt->data, TRUE);
1883
0
    }
1884
1885
0
  g_clear_pointer (&attempt->timeout_source, g_source_unref);
1886
0
  return G_SOURCE_REMOVE;
1887
0
}
1888
1889
static void
1890
on_connection_cancelled (GCancellable *cancellable,
1891
                         gpointer      data)
1892
0
{
1893
0
  GCancellable *linked_cancellable = G_CANCELLABLE (data);
1894
1895
0
  g_cancellable_cancel (linked_cancellable);
1896
0
}
1897
1898
static void
1899
g_socket_client_enumerator_callback (GObject      *object,
1900
             GAsyncResult *result,
1901
             gpointer      user_data)
1902
0
{
1903
0
  GSocketClientAsyncConnectData *data = user_data;
1904
0
  GSocketAddress *address = NULL;
1905
0
  GSocket *socket;
1906
0
  ConnectionAttempt *attempt;
1907
1908
0
  if (task_completed_or_cancelled (data))
1909
0
    {
1910
0
      g_object_unref (data->task);
1911
0
      return;
1912
0
    }
1913
1914
0
  address = g_socket_address_enumerator_next_finish (data->enumerator,
1915
0
                 result, &data->error_info->tmp_error);
1916
0
  if (address == NULL)
1917
0
    {
1918
0
      if (G_UNLIKELY (data->enumeration_completed))
1919
0
        return;
1920
1921
0
      data->enumeration_completed = TRUE;
1922
0
      g_debug ("GSocketClient: Address enumeration completed (out of addresses)");
1923
1924
      /* As per API docs: We only care about error if it's the first call,
1925
         after that the enumerator is done.
1926
1927
         Note that we don't care about cancellation errors because
1928
         task_completed_or_cancelled() above should handle that.
1929
1930
         If this fails and nothing is in progress then we will complete task here.
1931
       */
1932
0
      if ((data->enumerated_at_least_once && !data->connection_attempts && !data->connection_in_progress) ||
1933
0
          !data->enumerated_at_least_once)
1934
0
        {
1935
0
          g_debug ("GSocketClient: Address enumeration failed: %s",
1936
0
                   data->error_info->tmp_error ? data->error_info->tmp_error->message : NULL);
1937
0
          consider_tmp_error (data->error_info, G_SOCKET_CLIENT_RESOLVING);
1938
0
          g_assert (data->error_info->best_error);
1939
0
          complete_connection_with_error (data, g_steal_pointer (&data->error_info->best_error));
1940
0
        }
1941
1942
      /* Enumeration should never trigger again, drop our ref */
1943
0
      g_object_unref (data->task);
1944
0
      return;
1945
0
    }
1946
1947
0
  g_debug ("GSocketClient: Address enumeration succeeded");
1948
0
  if (!data->enumerated_at_least_once)
1949
0
    {
1950
0
      g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_RESOLVED,
1951
0
          data->connectable, NULL);
1952
0
      data->enumerated_at_least_once = TRUE;
1953
0
    }
1954
1955
0
  socket = create_socket (data->client, address, &data->error_info->tmp_error);
1956
0
  if (socket == NULL)
1957
0
    {
1958
0
      g_object_unref (address);
1959
0
      consider_tmp_error (data->error_info, G_SOCKET_CLIENT_CONNECTING);
1960
0
      enumerator_next_async (data, FALSE);
1961
0
      return;
1962
0
    }
1963
1964
0
  attempt = connection_attempt_new ();
1965
0
  attempt->data = data;
1966
0
  attempt->socket = socket;
1967
0
  attempt->address = address;
1968
0
  attempt->cancellable = g_cancellable_new ();
1969
0
  attempt->connection = (GIOStream *)g_socket_connection_factory_create_connection (socket);
1970
0
  attempt->timeout_source = g_timeout_source_new (HAPPY_EYEBALLS_CONNECTION_ATTEMPT_TIMEOUT_MS);
1971
1972
0
  if (G_IS_PROXY_ADDRESS (address) && data->client->priv->enable_proxy)
1973
0
    attempt->proxy_addr = g_object_ref (G_PROXY_ADDRESS (address));
1974
1975
0
  g_source_set_callback (attempt->timeout_source, on_connection_attempt_timeout, attempt, NULL);
1976
0
  g_source_attach (attempt->timeout_source, g_task_get_context (data->task));
1977
0
  data->connection_attempts = g_slist_append (data->connection_attempts, attempt);
1978
1979
0
  if (g_task_get_cancellable (data->task))
1980
0
    g_cancellable_connect (g_task_get_cancellable (data->task), G_CALLBACK (on_connection_cancelled),
1981
0
                           g_object_ref (attempt->cancellable), g_object_unref);
1982
1983
0
  g_socket_connection_set_cached_remote_address ((GSocketConnection *)attempt->connection, address);
1984
0
  g_debug ("GSocketClient: Starting TCP connection attempt");
1985
0
  g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_CONNECTING, data->connectable, attempt->connection);
1986
0
  g_socket_connection_connect_async (G_SOCKET_CONNECTION (attempt->connection),
1987
0
             address,
1988
0
             attempt->cancellable,
1989
0
             g_socket_client_connected_callback, connection_attempt_ref (attempt));
1990
0
}
1991
1992
/**
1993
 * g_socket_client_connect_async:
1994
 * @client: a #GSocketClient
1995
 * @connectable: a #GSocketConnectable specifying the remote address.
1996
 * @cancellable: (nullable): a #GCancellable, or %NULL
1997
 * @callback: (scope async): a #GAsyncReadyCallback
1998
 * @user_data: (closure): user data for the callback
1999
 *
2000
 * This is the asynchronous version of g_socket_client_connect().
2001
 *
2002
 * You may wish to prefer the asynchronous version even in synchronous
2003
 * command line programs because, since 2.60, it implements
2004
 * [RFC 8305](https://tools.ietf.org/html/rfc8305) "Happy Eyeballs"
2005
 * recommendations to work around long connection timeouts in networks
2006
 * where IPv6 is broken by performing an IPv4 connection simultaneously
2007
 * without waiting for IPv6 to time out, which is not supported by the
2008
 * synchronous call. (This is not an API guarantee, and may change in
2009
 * the future.)
2010
 *
2011
 * When the operation is finished @callback will be
2012
 * called. You can then call g_socket_client_connect_finish() to get
2013
 * the result of the operation.
2014
 *
2015
 * Since: 2.22
2016
 */
2017
void
2018
g_socket_client_connect_async (GSocketClient       *client,
2019
             GSocketConnectable  *connectable,
2020
             GCancellable        *cancellable,
2021
             GAsyncReadyCallback  callback,
2022
             gpointer             user_data)
2023
0
{
2024
0
  GSocketClientAsyncConnectData *data;
2025
2026
0
  g_return_if_fail (G_IS_SOCKET_CLIENT (client));
2027
2028
0
  data = g_slice_new0 (GSocketClientAsyncConnectData);
2029
0
  data->client = client;
2030
0
  data->connectable = g_object_ref (connectable);
2031
0
  data->error_info = socket_client_error_info_new ();
2032
2033
0
  if (can_use_proxy (client))
2034
0
    {
2035
0
      data->enumerator = g_socket_connectable_proxy_enumerate (connectable);
2036
0
      if (client->priv->proxy_resolver &&
2037
0
          G_IS_PROXY_ADDRESS_ENUMERATOR (data->enumerator))
2038
0
        {
2039
0
          g_object_set (G_OBJECT (data->enumerator),
2040
0
                        "proxy-resolver", client->priv->proxy_resolver,
2041
0
                        NULL);
2042
0
        }
2043
0
    }
2044
0
  else
2045
0
    data->enumerator = g_socket_connectable_enumerate (connectable);
2046
2047
  /* This function tries to match the behavior of g_socket_client_connect ()
2048
     which is simple enough but much of it is done in parallel to be as responsive
2049
     as possible as per Happy Eyeballs (RFC 8305). This complicates flow quite a
2050
     bit but we can describe it in 3 sections:
2051
2052
     Firstly we have address enumeration (DNS):
2053
       - This may be triggered multiple times by enumerator_next_async().
2054
       - It also has its own cancellable (data->enumeration_cancellable).
2055
       - Enumeration is done lazily because GNetworkAddressAddressEnumerator
2056
         also does work in parallel and may lazily add new addresses.
2057
       - If the first enumeration errors then the task errors. Otherwise all enumerations
2058
         will potentially be used (until task or enumeration is cancelled).
2059
2060
      Then we start attempting connections (TCP):
2061
        - Each connection is independent and kept in a ConnectionAttempt object.
2062
          - They each hold a ref on the main task and have their own cancellable.
2063
        - Multiple attempts may happen in parallel as per Happy Eyeballs.
2064
        - Upon failure or timeouts more connection attempts are made.
2065
          - If no connections succeed the task errors.
2066
        - Upon success they are kept in a list of successful connections.
2067
2068
      Lastly we connect at the application layer (TLS, Proxies):
2069
        - These are done in serial.
2070
          - The reasoning here is that Happy Eyeballs is about making bad connections responsive
2071
            at the IP/TCP layers. Issues at the application layer are generally not due to
2072
            connectivity issues but rather misconfiguration.
2073
        - Upon failure it will try the next TCP connection until it runs out and
2074
          the task errors.
2075
        - Upon success it cancels everything remaining (enumeration and connections)
2076
          and returns the connection.
2077
  */
2078
2079
0
  data->task = g_task_new (client, cancellable, callback, user_data);
2080
0
  g_task_set_check_cancellable (data->task, FALSE); /* We handle this manually */
2081
0
  g_task_set_source_tag (data->task, g_socket_client_connect_async);
2082
0
  g_task_set_task_data (data->task, data, (GDestroyNotify)g_socket_client_async_connect_data_free);
2083
2084
0
  data->enumeration_cancellable = g_cancellable_new ();
2085
0
  if (cancellable)
2086
0
    g_cancellable_connect (cancellable, G_CALLBACK (on_connection_cancelled),
2087
0
                           g_object_ref (data->enumeration_cancellable), g_object_unref);
2088
2089
0
  enumerator_next_async (data, FALSE);
2090
0
}
2091
2092
/**
2093
 * g_socket_client_connect_to_host_async:
2094
 * @client: a #GSocketClient
2095
 * @host_and_port: the name and optionally the port of the host to connect to
2096
 * @default_port: the default port to connect to
2097
 * @cancellable: (nullable): a #GCancellable, or %NULL
2098
 * @callback: (scope async): a #GAsyncReadyCallback
2099
 * @user_data: (closure): user data for the callback
2100
 *
2101
 * This is the asynchronous version of g_socket_client_connect_to_host().
2102
 *
2103
 * When the operation is finished @callback will be
2104
 * called. You can then call g_socket_client_connect_to_host_finish() to get
2105
 * the result of the operation.
2106
 *
2107
 * Since: 2.22
2108
 */
2109
void
2110
g_socket_client_connect_to_host_async (GSocketClient        *client,
2111
               const gchar          *host_and_port,
2112
               guint16               default_port,
2113
               GCancellable         *cancellable,
2114
               GAsyncReadyCallback   callback,
2115
               gpointer              user_data)
2116
0
{
2117
0
  GSocketConnectable *connectable;
2118
0
  GError *error;
2119
2120
0
  error = NULL;
2121
0
  connectable = g_network_address_parse (host_and_port, default_port,
2122
0
           &error);
2123
0
  if (connectable == NULL)
2124
0
    {
2125
0
      g_task_report_error (client, callback, user_data,
2126
0
                           g_socket_client_connect_to_host_async,
2127
0
                           error);
2128
0
    }
2129
0
  else
2130
0
    {
2131
0
      g_socket_client_connect_async (client,
2132
0
             connectable, cancellable,
2133
0
             callback, user_data);
2134
0
      g_object_unref (connectable);
2135
0
    }
2136
0
}
2137
2138
/**
2139
 * g_socket_client_connect_to_service_async:
2140
 * @client: a #GSocketClient
2141
 * @domain: a domain name
2142
 * @service: the name of the service to connect to
2143
 * @cancellable: (nullable): a #GCancellable, or %NULL
2144
 * @callback: (scope async): a #GAsyncReadyCallback
2145
 * @user_data: (closure): user data for the callback
2146
 *
2147
 * This is the asynchronous version of
2148
 * g_socket_client_connect_to_service().
2149
 *
2150
 * Since: 2.22
2151
 */
2152
void
2153
g_socket_client_connect_to_service_async (GSocketClient       *client,
2154
            const gchar         *domain,
2155
            const gchar         *service,
2156
            GCancellable        *cancellable,
2157
            GAsyncReadyCallback  callback,
2158
            gpointer             user_data)
2159
0
{
2160
0
  GSocketConnectable *connectable;
2161
2162
0
  connectable = g_network_service_new (service, "tcp", domain);
2163
0
  g_socket_client_connect_async (client,
2164
0
         connectable, cancellable,
2165
0
         callback, user_data);
2166
0
  g_object_unref (connectable);
2167
0
}
2168
2169
/**
2170
 * g_socket_client_connect_to_uri_async:
2171
 * @client: a #GSocketClient
2172
 * @uri: a network uri
2173
 * @default_port: the default port to connect to
2174
 * @cancellable: (nullable): a #GCancellable, or %NULL
2175
 * @callback: (scope async): a #GAsyncReadyCallback
2176
 * @user_data: (closure): user data for the callback
2177
 *
2178
 * This is the asynchronous version of g_socket_client_connect_to_uri().
2179
 *
2180
 * When the operation is finished @callback will be
2181
 * called. You can then call g_socket_client_connect_to_uri_finish() to get
2182
 * the result of the operation.
2183
 *
2184
 * Since: 2.26
2185
 */
2186
void
2187
g_socket_client_connect_to_uri_async (GSocketClient        *client,
2188
              const gchar          *uri,
2189
              guint16               default_port,
2190
              GCancellable         *cancellable,
2191
              GAsyncReadyCallback   callback,
2192
              gpointer              user_data)
2193
0
{
2194
0
  GSocketConnectable *connectable;
2195
0
  GError *error;
2196
2197
0
  error = NULL;
2198
0
  connectable = g_network_address_parse_uri (uri, default_port, &error);
2199
0
  if (connectable == NULL)
2200
0
    {
2201
0
      g_task_report_error (client, callback, user_data,
2202
0
                           g_socket_client_connect_to_uri_async,
2203
0
                           error);
2204
0
    }
2205
0
  else
2206
0
    {
2207
0
      g_debug("g_socket_client_connect_to_uri_async");
2208
0
      g_socket_client_connect_async (client,
2209
0
             connectable, cancellable,
2210
0
             callback, user_data);
2211
0
      g_object_unref (connectable);
2212
0
    }
2213
0
}
2214
2215
2216
/**
2217
 * g_socket_client_connect_finish:
2218
 * @client: a #GSocketClient.
2219
 * @result: a #GAsyncResult.
2220
 * @error: a #GError location to store the error occurring, or %NULL to
2221
 * ignore.
2222
 *
2223
 * Finishes an async connect operation. See g_socket_client_connect_async()
2224
 *
2225
 * Returns: (transfer full): a #GSocketConnection on success, %NULL on error.
2226
 *
2227
 * Since: 2.22
2228
 */
2229
GSocketConnection *
2230
g_socket_client_connect_finish (GSocketClient  *client,
2231
        GAsyncResult   *result,
2232
        GError        **error)
2233
0
{
2234
0
  g_return_val_if_fail (g_task_is_valid (result, client), NULL);
2235
2236
0
  return g_task_propagate_pointer (G_TASK (result), error);
2237
0
}
2238
2239
/**
2240
 * g_socket_client_connect_to_host_finish:
2241
 * @client: a #GSocketClient.
2242
 * @result: a #GAsyncResult.
2243
 * @error: a #GError location to store the error occurring, or %NULL to
2244
 * ignore.
2245
 *
2246
 * Finishes an async connect operation. See g_socket_client_connect_to_host_async()
2247
 *
2248
 * Returns: (transfer full): a #GSocketConnection on success, %NULL on error.
2249
 *
2250
 * Since: 2.22
2251
 */
2252
GSocketConnection *
2253
g_socket_client_connect_to_host_finish (GSocketClient  *client,
2254
          GAsyncResult   *result,
2255
          GError        **error)
2256
0
{
2257
0
  return g_socket_client_connect_finish (client, result, error);
2258
0
}
2259
2260
/**
2261
 * g_socket_client_connect_to_service_finish:
2262
 * @client: a #GSocketClient.
2263
 * @result: a #GAsyncResult.
2264
 * @error: a #GError location to store the error occurring, or %NULL to
2265
 * ignore.
2266
 *
2267
 * Finishes an async connect operation. See g_socket_client_connect_to_service_async()
2268
 *
2269
 * Returns: (transfer full): a #GSocketConnection on success, %NULL on error.
2270
 *
2271
 * Since: 2.22
2272
 */
2273
GSocketConnection *
2274
g_socket_client_connect_to_service_finish (GSocketClient  *client,
2275
             GAsyncResult   *result,
2276
             GError        **error)
2277
0
{
2278
0
  return g_socket_client_connect_finish (client, result, error);
2279
0
}
2280
2281
/**
2282
 * g_socket_client_connect_to_uri_finish:
2283
 * @client: a #GSocketClient.
2284
 * @result: a #GAsyncResult.
2285
 * @error: a #GError location to store the error occurring, or %NULL to
2286
 * ignore.
2287
 *
2288
 * Finishes an async connect operation. See g_socket_client_connect_to_uri_async()
2289
 *
2290
 * Returns: (transfer full): a #GSocketConnection on success, %NULL on error.
2291
 *
2292
 * Since: 2.26
2293
 */
2294
GSocketConnection *
2295
g_socket_client_connect_to_uri_finish (GSocketClient  *client,
2296
               GAsyncResult   *result,
2297
               GError        **error)
2298
0
{
2299
0
  return g_socket_client_connect_finish (client, result, error);
2300
0
}
2301
2302
/**
2303
 * g_socket_client_add_application_proxy:
2304
 * @client: a #GSocketClient
2305
 * @protocol: The proxy protocol
2306
 *
2307
 * Enable proxy protocols to be handled by the application. When the
2308
 * indicated proxy protocol is returned by the #GProxyResolver,
2309
 * #GSocketClient will consider this protocol as supported but will
2310
 * not try to find a #GProxy instance to handle handshaking. The
2311
 * application must check for this case by calling
2312
 * g_socket_connection_get_remote_address() on the returned
2313
 * #GSocketConnection, and seeing if it's a #GProxyAddress of the
2314
 * appropriate type, to determine whether or not it needs to handle
2315
 * the proxy handshaking itself.
2316
 *
2317
 * This should be used for proxy protocols that are dialects of
2318
 * another protocol such as HTTP proxy. It also allows cohabitation of
2319
 * proxy protocols that are reused between protocols. A good example
2320
 * is HTTP. It can be used to proxy HTTP, FTP and Gopher and can also
2321
 * be use as generic socket proxy through the HTTP CONNECT method.
2322
 *
2323
 * When the proxy is detected as being an application proxy, TLS handshake
2324
 * will be skipped. This is required to let the application do the proxy
2325
 * specific handshake.
2326
 */
2327
void
2328
g_socket_client_add_application_proxy (GSocketClient *client,
2329
                     const gchar   *protocol)
2330
0
{
2331
0
  g_hash_table_add (client->priv->app_proxies, g_strdup (protocol));
2332
0
}