Coverage Report

Created: 2025-06-13 06:55

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