Coverage Report

Created: 2025-07-23 08:13

/src/pango/subprojects/glib/gio/gsocketconnection.c
Line
Count
Source (jump to first uncovered line)
1
/* GIO - GLib Input, Output and Streaming Library
2
 *
3
 * Copyright © 2008 Christian Kellner, Samuel Cormier-Iijima
4
 *           © 2008 codethink
5
 * Copyright © 2009 Red Hat, Inc
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: Christian Kellner <gicmo@gnome.org>
23
 *          Samuel Cormier-Iijima <sciyoshi@gmail.com>
24
 *          Ryan Lortie <desrt@desrt.ca>
25
 *          Alexander Larsson <alexl@redhat.com>
26
 */
27
28
#include "config.h"
29
30
#include "gsocketconnection.h"
31
32
#include "gsocketoutputstream.h"
33
#include "gsocketinputstream.h"
34
#include "gioprivate.h"
35
#include <gio/giostream.h>
36
#include <gio/gtask.h>
37
#include "gunixconnection.h"
38
#include "gtcpconnection.h"
39
#include "glibintl.h"
40
41
42
/**
43
 * GSocketConnection:
44
 *
45
 * `GSocketConnection` is a [class@Gio.IOStream] for a connected socket. They
46
 * can be created either by [class@Gio.SocketClient] when connecting to a host,
47
 * or by [class@Gio.SocketListener] when accepting a new client.
48
 *
49
 * The type of the `GSocketConnection` object returned from these calls
50
 * depends on the type of the underlying socket that is in use. For
51
 * instance, for a TCP/IP connection it will be a [class@Gio.TcpConnection].
52
 *
53
 * Choosing what type of object to construct is done with the socket
54
 * connection factory, and it is possible for third parties to register
55
 * custom socket connection types for specific combination of socket
56
 * family/type/protocol using [func@Gio.SocketConnection.factory_register_type].
57
 *
58
 * To close a `GSocketConnection`, use [method@Gio.IOStream.close]. Closing both
59
 * substreams of the [class@Gio.IOStream] separately will not close the
60
 * underlying [class@Gio.Socket].
61
 *
62
 * Since: 2.22
63
 */
64
65
enum
66
{
67
  PROP_NONE,
68
  PROP_SOCKET,
69
};
70
71
struct _GSocketConnectionPrivate
72
{
73
  GSocket       *socket;
74
  GInputStream  *input_stream;
75
  GOutputStream *output_stream;
76
77
  GSocketAddress *cached_remote_address;
78
79
  gboolean       in_dispose;
80
};
81
82
static gboolean g_socket_connection_close         (GIOStream            *stream,
83
               GCancellable         *cancellable,
84
               GError              **error);
85
static void     g_socket_connection_close_async   (GIOStream            *stream,
86
               int                   io_priority,
87
               GCancellable         *cancellable,
88
               GAsyncReadyCallback   callback,
89
               gpointer              user_data);
90
static gboolean g_socket_connection_close_finish  (GIOStream            *stream,
91
               GAsyncResult         *result,
92
               GError              **error);
93
94
G_DEFINE_TYPE_WITH_PRIVATE (GSocketConnection, g_socket_connection, G_TYPE_IO_STREAM)
95
96
static GInputStream *
97
g_socket_connection_get_input_stream (GIOStream *io_stream)
98
0
{
99
0
  GSocketConnection *connection = G_SOCKET_CONNECTION (io_stream);
100
101
0
  if (connection->priv->input_stream == NULL)
102
0
    connection->priv->input_stream = (GInputStream *)
103
0
      _g_socket_input_stream_new (connection->priv->socket);
104
105
0
  return connection->priv->input_stream;
106
0
}
107
108
static GOutputStream *
109
g_socket_connection_get_output_stream (GIOStream *io_stream)
110
0
{
111
0
  GSocketConnection *connection = G_SOCKET_CONNECTION (io_stream);
112
113
0
  if (connection->priv->output_stream == NULL)
114
0
    connection->priv->output_stream = (GOutputStream *)
115
0
      _g_socket_output_stream_new (connection->priv->socket);
116
117
0
  return connection->priv->output_stream;
118
0
}
119
120
/**
121
 * g_socket_connection_is_connected:
122
 * @connection: a #GSocketConnection
123
 *
124
 * Checks if @connection is connected. This is equivalent to calling
125
 * g_socket_is_connected() on @connection's underlying #GSocket.
126
 *
127
 * Returns: whether @connection is connected
128
 *
129
 * Since: 2.32
130
 */
131
gboolean
132
g_socket_connection_is_connected (GSocketConnection  *connection)
133
0
{
134
0
  return g_socket_is_connected (connection->priv->socket);
135
0
}
136
137
/**
138
 * g_socket_connection_connect:
139
 * @connection: a #GSocketConnection
140
 * @address: a #GSocketAddress specifying the remote address.
141
 * @cancellable: (nullable): a %GCancellable or %NULL
142
 * @error: #GError for error reporting, or %NULL to ignore.
143
 *
144
 * Connect @connection to the specified remote address.
145
 *
146
 * Returns: %TRUE if the connection succeeded, %FALSE on error
147
 *
148
 * Since: 2.32
149
 */
150
gboolean
151
g_socket_connection_connect (GSocketConnection  *connection,
152
           GSocketAddress     *address,
153
           GCancellable       *cancellable,
154
           GError            **error)
155
0
{
156
0
  g_return_val_if_fail (G_IS_SOCKET_CONNECTION (connection), FALSE);
157
0
  g_return_val_if_fail (G_IS_SOCKET_ADDRESS (address), FALSE);
158
159
0
  return g_socket_connect (connection->priv->socket, address,
160
0
         cancellable, error);
161
0
}
162
163
static gboolean g_socket_connection_connect_callback (GSocket      *socket,
164
                  GIOCondition  condition,
165
                  gpointer      user_data);
166
167
/**
168
 * g_socket_connection_connect_async:
169
 * @connection: a #GSocketConnection
170
 * @address: a #GSocketAddress specifying the remote address.
171
 * @cancellable: (nullable): a %GCancellable or %NULL
172
 * @callback: (scope async): a #GAsyncReadyCallback
173
 * @user_data: user data for the callback
174
 *
175
 * Asynchronously connect @connection to the specified remote address.
176
 *
177
 * This clears the #GSocket:blocking flag on @connection's underlying
178
 * socket if it is currently set.
179
 *
180
 * If #GSocket:timeout is set, the operation will time out and return
181
 * %G_IO_ERROR_TIMED_OUT after that period. Otherwise, it will continue
182
 * indefinitely until operating system timeouts (if any) are hit.
183
 *
184
 * Use g_socket_connection_connect_finish() to retrieve the result.
185
 *
186
 * Since: 2.32
187
 */
188
void
189
g_socket_connection_connect_async (GSocketConnection   *connection,
190
           GSocketAddress      *address,
191
           GCancellable        *cancellable,
192
           GAsyncReadyCallback  callback,
193
           gpointer             user_data)
194
0
{
195
0
  GTask *task;
196
0
  GError *tmp_error = NULL;
197
198
0
  g_return_if_fail (G_IS_SOCKET_CONNECTION (connection));
199
0
  g_return_if_fail (G_IS_SOCKET_ADDRESS (address));
200
201
0
  task = g_task_new (connection, cancellable, callback, user_data);
202
0
  g_task_set_source_tag (task, g_socket_connection_connect_async);
203
204
0
  g_socket_set_blocking (connection->priv->socket, FALSE);
205
206
0
  if (g_socket_connect (connection->priv->socket, address,
207
0
      cancellable, &tmp_error))
208
0
    {
209
0
      g_task_return_boolean (task, TRUE);
210
0
      g_object_unref (task);
211
0
    }
212
0
  else if (g_error_matches (tmp_error, G_IO_ERROR, G_IO_ERROR_PENDING))
213
0
    {
214
0
      GSource *source;
215
216
0
      g_error_free (tmp_error);
217
0
      source = g_socket_create_source (connection->priv->socket,
218
0
               G_IO_OUT, cancellable);
219
0
      g_task_attach_source (task, source,
220
0
          (GSourceFunc) g_socket_connection_connect_callback);
221
0
      g_source_unref (source);
222
0
    }
223
0
  else
224
0
    {
225
0
      g_task_return_error (task, tmp_error);
226
0
      g_object_unref (task);
227
0
    }
228
0
}
229
230
static gboolean
231
g_socket_connection_connect_callback (GSocket      *socket,
232
              GIOCondition  condition,
233
              gpointer      user_data)
234
0
{
235
0
  GTask *task = user_data;
236
0
  GSocketConnection *connection = g_task_get_source_object (task);
237
0
  GError *error = NULL;
238
239
0
  if (g_socket_check_connect_result (connection->priv->socket, &error))
240
0
    g_task_return_boolean (task, TRUE);
241
0
  else
242
0
    g_task_return_error (task, error);
243
244
0
  g_object_unref (task);
245
0
  return FALSE;
246
0
}
247
248
/**
249
 * g_socket_connection_connect_finish:
250
 * @connection: a #GSocketConnection
251
 * @result: the #GAsyncResult
252
 * @error: #GError for error reporting, or %NULL to ignore.
253
 *
254
 * Gets the result of a g_socket_connection_connect_async() call.
255
 *
256
 * Returns: %TRUE if the connection succeeded, %FALSE on error
257
 *
258
 * Since: 2.32
259
 */
260
gboolean
261
g_socket_connection_connect_finish (GSocketConnection  *connection,
262
            GAsyncResult       *result,
263
            GError            **error)
264
0
{
265
0
  g_return_val_if_fail (G_IS_SOCKET_CONNECTION (connection), FALSE);
266
0
  g_return_val_if_fail (g_task_is_valid (result, connection), FALSE);
267
268
0
  return g_task_propagate_boolean (G_TASK (result), error);
269
0
}
270
271
/**
272
 * g_socket_connection_get_socket:
273
 * @connection: a #GSocketConnection
274
 *
275
 * Gets the underlying #GSocket object of the connection.
276
 * This can be useful if you want to do something unusual on it
277
 * not supported by the #GSocketConnection APIs.
278
 *
279
 * Returns: (transfer none): a #GSocket or %NULL on error.
280
 *
281
 * Since: 2.22
282
 */
283
GSocket *
284
g_socket_connection_get_socket (GSocketConnection *connection)
285
0
{
286
0
  g_return_val_if_fail (G_IS_SOCKET_CONNECTION (connection), NULL);
287
288
0
  return connection->priv->socket;
289
0
}
290
291
/**
292
 * g_socket_connection_get_local_address:
293
 * @connection: a #GSocketConnection
294
 * @error: #GError for error reporting, or %NULL to ignore.
295
 *
296
 * Try to get the local address of a socket connection.
297
 *
298
 * Returns: (transfer full): a #GSocketAddress or %NULL on error.
299
 *     Free the returned object with g_object_unref().
300
 *
301
 * Since: 2.22
302
 */
303
GSocketAddress *
304
g_socket_connection_get_local_address (GSocketConnection  *connection,
305
               GError            **error)
306
0
{
307
0
  return g_socket_get_local_address (connection->priv->socket, error);
308
0
}
309
310
/**
311
 * g_socket_connection_get_remote_address:
312
 * @connection: a #GSocketConnection
313
 * @error: #GError for error reporting, or %NULL to ignore.
314
 *
315
 * Try to get the remote address of a socket connection.
316
 *
317
 * Since GLib 2.40, when used with g_socket_client_connect() or
318
 * g_socket_client_connect_async(), during emission of
319
 * %G_SOCKET_CLIENT_CONNECTING, this function will return the remote
320
 * address that will be used for the connection.  This allows
321
 * applications to print e.g. "Connecting to example.com
322
 * (10.42.77.3)...".
323
 *
324
 * Returns: (transfer full): a #GSocketAddress or %NULL on error.
325
 *     Free the returned object with g_object_unref().
326
 *
327
 * Since: 2.22
328
 */
329
GSocketAddress *
330
g_socket_connection_get_remote_address (GSocketConnection  *connection,
331
          GError            **error)
332
0
{
333
0
  if (!g_socket_is_connected (connection->priv->socket))
334
0
    {
335
0
      return connection->priv->cached_remote_address ?
336
0
        g_object_ref (connection->priv->cached_remote_address) : NULL;
337
0
    }
338
0
  return g_socket_get_remote_address (connection->priv->socket, error);
339
0
}
340
341
/* Private API allowing applications to retrieve the resolved address
342
 * now, before we start connecting.
343
 *
344
 * https://bugzilla.gnome.org/show_bug.cgi?id=712547
345
 */
346
void
347
g_socket_connection_set_cached_remote_address (GSocketConnection *connection,
348
                                               GSocketAddress    *address)
349
0
{
350
0
  g_clear_object (&connection->priv->cached_remote_address);
351
0
  connection->priv->cached_remote_address = address ? g_object_ref (address) : NULL;
352
0
}
353
354
static void
355
g_socket_connection_get_property (GObject    *object,
356
                                  guint       prop_id,
357
                                  GValue     *value,
358
                                  GParamSpec *pspec)
359
0
{
360
0
  GSocketConnection *connection = G_SOCKET_CONNECTION (object);
361
362
0
  switch (prop_id)
363
0
    {
364
0
     case PROP_SOCKET:
365
0
      g_value_set_object (value, connection->priv->socket);
366
0
      break;
367
368
0
     default:
369
0
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
370
0
    }
371
0
}
372
373
static void
374
g_socket_connection_set_property (GObject      *object,
375
                                  guint         prop_id,
376
                                  const GValue *value,
377
                                  GParamSpec   *pspec)
378
0
{
379
0
  GSocketConnection *connection = G_SOCKET_CONNECTION (object);
380
381
0
  switch (prop_id)
382
0
    {
383
0
     case PROP_SOCKET:
384
0
      connection->priv->socket = G_SOCKET (g_value_dup_object (value));
385
0
      break;
386
387
0
     default:
388
0
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
389
0
    }
390
0
}
391
392
static void
393
g_socket_connection_constructed (GObject *object)
394
0
{
395
0
#ifndef G_DISABLE_ASSERT
396
0
  GSocketConnection *connection = G_SOCKET_CONNECTION (object);
397
0
#endif
398
399
0
  g_assert (connection->priv->socket != NULL);
400
0
}
401
402
static void
403
g_socket_connection_dispose (GObject *object)
404
0
{
405
0
  GSocketConnection *connection = G_SOCKET_CONNECTION (object);
406
407
0
  connection->priv->in_dispose = TRUE;
408
409
0
  g_clear_object (&connection->priv->cached_remote_address);
410
411
0
  G_OBJECT_CLASS (g_socket_connection_parent_class)
412
0
    ->dispose (object);
413
414
0
  connection->priv->in_dispose = FALSE;
415
0
}
416
417
static void
418
g_socket_connection_finalize (GObject *object)
419
0
{
420
0
  GSocketConnection *connection = G_SOCKET_CONNECTION (object);
421
422
0
  if (connection->priv->input_stream)
423
0
    g_object_unref (connection->priv->input_stream);
424
425
0
  if (connection->priv->output_stream)
426
0
    g_object_unref (connection->priv->output_stream);
427
428
0
  g_object_unref (connection->priv->socket);
429
430
0
  G_OBJECT_CLASS (g_socket_connection_parent_class)
431
0
    ->finalize (object);
432
0
}
433
434
static void
435
g_socket_connection_class_init (GSocketConnectionClass *klass)
436
0
{
437
0
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
438
0
  GIOStreamClass *stream_class = G_IO_STREAM_CLASS (klass);
439
440
0
  gobject_class->set_property = g_socket_connection_set_property;
441
0
  gobject_class->get_property = g_socket_connection_get_property;
442
0
  gobject_class->constructed = g_socket_connection_constructed;
443
0
  gobject_class->finalize = g_socket_connection_finalize;
444
0
  gobject_class->dispose = g_socket_connection_dispose;
445
446
0
  stream_class->get_input_stream = g_socket_connection_get_input_stream;
447
0
  stream_class->get_output_stream = g_socket_connection_get_output_stream;
448
0
  stream_class->close_fn = g_socket_connection_close;
449
0
  stream_class->close_async = g_socket_connection_close_async;
450
0
  stream_class->close_finish = g_socket_connection_close_finish;
451
452
  /**
453
   * GSocketConnection:socket:
454
   *
455
   * The underlying [class@Gio.Socket].
456
   *
457
   * Since: 2.22
458
   */
459
0
  g_object_class_install_property (gobject_class,
460
0
                                   PROP_SOCKET,
461
0
                                   g_param_spec_object ("socket", NULL, NULL,
462
0
                                                        G_TYPE_SOCKET,
463
0
                                                        G_PARAM_CONSTRUCT_ONLY |
464
0
                                                        G_PARAM_READWRITE |
465
0
                                                        G_PARAM_STATIC_STRINGS));
466
0
}
467
468
static void
469
g_socket_connection_init (GSocketConnection *connection)
470
0
{
471
0
  connection->priv = g_socket_connection_get_instance_private (connection);
472
0
}
473
474
static gboolean
475
g_socket_connection_close (GIOStream     *stream,
476
         GCancellable  *cancellable,
477
         GError       **error)
478
0
{
479
0
  GSocketConnection *connection = G_SOCKET_CONNECTION (stream);
480
481
0
  if (connection->priv->output_stream)
482
0
    g_output_stream_close (connection->priv->output_stream,
483
0
         cancellable, NULL);
484
0
  if (connection->priv->input_stream)
485
0
    g_input_stream_close (connection->priv->input_stream,
486
0
        cancellable, NULL);
487
488
  /* Don't close the underlying socket if this is being called
489
   * as part of dispose(); when destroying the GSocketConnection,
490
   * we only want to close the socket if we're holding the last
491
   * reference on it, and in that case it will close itself when
492
   * we unref it in finalize().
493
   */
494
0
  if (connection->priv->in_dispose)
495
0
    return TRUE;
496
497
0
  return g_socket_close (connection->priv->socket, error);
498
0
}
499
500
501
static void
502
g_socket_connection_close_async (GIOStream           *stream,
503
         int                  io_priority,
504
         GCancellable        *cancellable,
505
         GAsyncReadyCallback  callback,
506
         gpointer             user_data)
507
0
{
508
0
  GTask *task;
509
0
  GIOStreamClass *class;
510
0
  GError *error;
511
512
0
  class = G_IO_STREAM_GET_CLASS (stream);
513
514
0
  task = g_task_new (stream, cancellable, callback, user_data);
515
0
  g_task_set_source_tag (task, g_socket_connection_close_async);
516
517
  /* socket close is not blocked, just do it! */
518
0
  error = NULL;
519
0
  if (class->close_fn &&
520
0
      !class->close_fn (stream, cancellable, &error))
521
0
    g_task_return_error (task, error);
522
0
  else
523
0
    g_task_return_boolean (task, TRUE);
524
525
0
  g_object_unref (task);
526
0
}
527
528
static gboolean
529
g_socket_connection_close_finish (GIOStream     *stream,
530
          GAsyncResult  *result,
531
          GError       **error)
532
0
{
533
0
  return g_task_propagate_boolean (G_TASK (result), error);
534
0
}
535
536
typedef struct {
537
  GSocketFamily socket_family;
538
  GSocketType socket_type;
539
  int protocol;
540
  GType implementation;
541
} ConnectionFactory;
542
543
static guint
544
connection_factory_hash (gconstpointer key)
545
0
{
546
0
  const ConnectionFactory *factory = key;
547
0
  guint h;
548
549
0
  h = factory->socket_family ^ (factory->socket_type << 4) ^ (factory->protocol << 8);
550
  /* This is likely to be small, so spread over whole
551
     hash space to get some distribution */
552
0
  h = h ^ (h << 8) ^ (h << 16) ^ (h << 24);
553
554
0
  return h;
555
0
}
556
557
static gboolean
558
connection_factory_equal (gconstpointer _a,
559
        gconstpointer _b)
560
0
{
561
0
  const ConnectionFactory *a = _a;
562
0
  const ConnectionFactory *b = _b;
563
564
0
  if (a->socket_family != b->socket_family)
565
0
    return FALSE;
566
567
0
  if (a->socket_type != b->socket_type)
568
0
    return FALSE;
569
570
0
  if (a->protocol != b->protocol)
571
0
    return FALSE;
572
573
0
  return TRUE;
574
0
}
575
576
static GHashTable *connection_factories = NULL;
577
G_LOCK_DEFINE_STATIC(connection_factories);
578
579
/**
580
 * g_socket_connection_factory_register_type:
581
 * @g_type: a #GType, inheriting from %G_TYPE_SOCKET_CONNECTION
582
 * @family: a #GSocketFamily
583
 * @type: a #GSocketType
584
 * @protocol: a protocol id
585
 *
586
 * Looks up the #GType to be used when creating socket connections on
587
 * sockets with the specified @family, @type and @protocol.
588
 *
589
 * If no type is registered, the #GSocketConnection base type is returned.
590
 *
591
 * Since: 2.22
592
 */
593
void
594
g_socket_connection_factory_register_type (GType         g_type,
595
             GSocketFamily family,
596
             GSocketType   type,
597
             gint          protocol)
598
0
{
599
0
  ConnectionFactory *factory;
600
601
0
  g_return_if_fail (g_type_is_a (g_type, G_TYPE_SOCKET_CONNECTION));
602
603
0
  G_LOCK (connection_factories);
604
605
0
  if (connection_factories == NULL)
606
0
    connection_factories = g_hash_table_new_full (connection_factory_hash,
607
0
              connection_factory_equal,
608
0
              (GDestroyNotify)g_free,
609
0
              NULL);
610
611
0
  factory = g_new0 (ConnectionFactory, 1);
612
0
  factory->socket_family = family;
613
0
  factory->socket_type = type;
614
0
  factory->protocol = protocol;
615
0
  factory->implementation = g_type;
616
617
0
  g_hash_table_insert (connection_factories,
618
0
           factory, factory);
619
620
0
  G_UNLOCK (connection_factories);
621
0
}
622
623
static void
624
init_builtin_types (void)
625
0
{
626
0
  g_type_ensure (G_TYPE_UNIX_CONNECTION);
627
0
  g_type_ensure (G_TYPE_TCP_CONNECTION);
628
0
}
629
630
/**
631
 * g_socket_connection_factory_lookup_type:
632
 * @family: a #GSocketFamily
633
 * @type: a #GSocketType
634
 * @protocol_id: a protocol id
635
 *
636
 * Looks up the #GType to be used when creating socket connections on
637
 * sockets with the specified @family, @type and @protocol_id.
638
 *
639
 * If no type is registered, the #GSocketConnection base type is returned.
640
 *
641
 * Returns: a #GType
642
 *
643
 * Since: 2.22
644
 */
645
GType
646
g_socket_connection_factory_lookup_type (GSocketFamily family,
647
           GSocketType   type,
648
           gint          protocol_id)
649
0
{
650
0
  ConnectionFactory *factory, key;
651
0
  GType g_type;
652
653
0
  init_builtin_types ();
654
655
0
  G_LOCK (connection_factories);
656
657
0
  g_type = G_TYPE_SOCKET_CONNECTION;
658
659
0
  if (connection_factories)
660
0
    {
661
0
      key.socket_family = family;
662
0
      key.socket_type = type;
663
0
      key.protocol = protocol_id;
664
665
0
      factory = g_hash_table_lookup (connection_factories, &key);
666
0
      if (factory)
667
0
  g_type = factory->implementation;
668
0
    }
669
670
0
  G_UNLOCK (connection_factories);
671
672
0
  return g_type;
673
0
}
674
675
/**
676
 * g_socket_connection_factory_create_connection:
677
 * @socket: a #GSocket
678
 *
679
 * Creates a #GSocketConnection subclass of the right type for
680
 * @socket.
681
 *
682
 * Returns: (transfer full): a #GSocketConnection
683
 *
684
 * Since: 2.22
685
 */
686
GSocketConnection *
687
g_socket_connection_factory_create_connection (GSocket *socket)
688
0
{
689
0
  GType type;
690
691
0
  type = g_socket_connection_factory_lookup_type (g_socket_get_family (socket),
692
0
              g_socket_get_socket_type (socket),
693
0
              g_socket_get_protocol (socket));
694
0
  return g_object_new (type, "socket", socket, NULL);
695
0
}