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 {
99 GSocketConnection *connection = G_SOCKET_CONNECTION (io_stream);
100
101 if (connection->priv->input_stream == NULL)
102 connection->priv->input_stream = (GInputStream *)
103 _g_socket_input_stream_new (connection->priv->socket);
104
105 return connection->priv->input_stream;
106 }
107
108 static GOutputStream *
109 g_socket_connection_get_output_stream (GIOStream *io_stream)
110 {
111 GSocketConnection *connection = G_SOCKET_CONNECTION (io_stream);
112
113 if (connection->priv->output_stream == NULL)
114 connection->priv->output_stream = (GOutputStream *)
115 _g_socket_output_stream_new (connection->priv->socket);
116
117 return connection->priv->output_stream;
118 }
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 {
134 return g_socket_is_connected (connection->priv->socket);
135 }
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 {
156 g_return_val_if_fail (G_IS_SOCKET_CONNECTION (connection), FALSE);
157 g_return_val_if_fail (G_IS_SOCKET_ADDRESS (address), FALSE);
158
159 return g_socket_connect (connection->priv->socket, address,
160 cancellable, error);
161 }
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 {
195 GTask *task;
196 GError *tmp_error = NULL;
197
198 g_return_if_fail (G_IS_SOCKET_CONNECTION (connection));
199 g_return_if_fail (G_IS_SOCKET_ADDRESS (address));
200
201 task = g_task_new (connection, cancellable, callback, user_data);
202 g_task_set_source_tag (task, g_socket_connection_connect_async);
203
204 g_socket_set_blocking (connection->priv->socket, FALSE);
205
206 if (g_socket_connect (connection->priv->socket, address,
207 cancellable, &tmp_error))
208 {
209 g_task_return_boolean (task, TRUE);
210 g_object_unref (task);
211 }
212 else if (g_error_matches (tmp_error, G_IO_ERROR, G_IO_ERROR_PENDING))
213 {
214 GSource *source;
215
216 g_error_free (tmp_error);
217 source = g_socket_create_source (connection->priv->socket,
218 G_IO_OUT, cancellable);
219 g_task_attach_source (task, source,
220 (GSourceFunc) g_socket_connection_connect_callback);
221 g_source_unref (source);
222 }
223 else
224 {
225 g_task_return_error (task, tmp_error);
226 g_object_unref (task);
227 }
228 }
229
230 static gboolean
231 g_socket_connection_connect_callback (GSocket *socket,
232 GIOCondition condition,
233 gpointer user_data)
234 {
235 GTask *task = user_data;
236 GSocketConnection *connection = g_task_get_source_object (task);
237 GError *error = NULL;
238
239 if (g_socket_check_connect_result (connection->priv->socket, &error))
240 g_task_return_boolean (task, TRUE);
241 else
242 g_task_return_error (task, error);
243
244 g_object_unref (task);
245 return FALSE;
246 }
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 {
265 g_return_val_if_fail (G_IS_SOCKET_CONNECTION (connection), FALSE);
266 g_return_val_if_fail (g_task_is_valid (result, connection), FALSE);
267
268 return g_task_propagate_boolean (G_TASK (result), error);
269 }
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 {
286 g_return_val_if_fail (G_IS_SOCKET_CONNECTION (connection), NULL);
287
288 return connection->priv->socket;
289 }
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 {
307 return g_socket_get_local_address (connection->priv->socket, error);
308 }
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 {
333 if (!g_socket_is_connected (connection->priv->socket))
334 {
335 return connection->priv->cached_remote_address ?
336 g_object_ref (connection->priv->cached_remote_address) : NULL;
337 }
338 return g_socket_get_remote_address (connection->priv->socket, error);
339 }
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 {
350 g_clear_object (&connection->priv->cached_remote_address);
351 connection->priv->cached_remote_address = address ? g_object_ref (address) : NULL;
352 }
353
354 static void
355 g_socket_connection_get_property (GObject *object,
356 guint prop_id,
357 GValue *value,
358 GParamSpec *pspec)
359 {
360 GSocketConnection *connection = G_SOCKET_CONNECTION (object);
361
362 switch (prop_id)
363 {
364 case PROP_SOCKET:
365 g_value_set_object (value, connection->priv->socket);
366 break;
367
368 default:
369 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
370 }
371 }
372
373 static void
374 g_socket_connection_set_property (GObject *object,
375 guint prop_id,
376 const GValue *value,
377 GParamSpec *pspec)
378 {
379 GSocketConnection *connection = G_SOCKET_CONNECTION (object);
380
381 switch (prop_id)
382 {
383 case PROP_SOCKET:
384 connection->priv->socket = G_SOCKET (g_value_dup_object (value));
385 break;
386
387 default:
388 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
389 }
390 }
391
392 static void
393 g_socket_connection_constructed (GObject *object)
394 {
395 #ifndef G_DISABLE_ASSERT
396 GSocketConnection *connection = G_SOCKET_CONNECTION (object);
397 #endif
398
399 g_assert (connection->priv->socket != NULL);
400 }
401
402 static void
403 g_socket_connection_dispose (GObject *object)
404 {
405 GSocketConnection *connection = G_SOCKET_CONNECTION (object);
406
407 connection->priv->in_dispose = TRUE;
408
409 g_clear_object (&connection->priv->cached_remote_address);
410
411 G_OBJECT_CLASS (g_socket_connection_parent_class)
412 ->dispose (object);
413
414 connection->priv->in_dispose = FALSE;
415 }
416
417 static void
418 g_socket_connection_finalize (GObject *object)
419 {
420 GSocketConnection *connection = G_SOCKET_CONNECTION (object);
421
422 if (connection->priv->input_stream)
423 g_object_unref (connection->priv->input_stream);
424
425 if (connection->priv->output_stream)
426 g_object_unref (connection->priv->output_stream);
427
428 g_object_unref (connection->priv->socket);
429
430 G_OBJECT_CLASS (g_socket_connection_parent_class)
431 ->finalize (object);
432 }
433
434 static void
435 g_socket_connection_class_init (GSocketConnectionClass *klass)
436 {
437 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
438 GIOStreamClass *stream_class = G_IO_STREAM_CLASS (klass);
439
440 gobject_class->set_property = g_socket_connection_set_property;
441 gobject_class->get_property = g_socket_connection_get_property;
442 gobject_class->constructed = g_socket_connection_constructed;
443 gobject_class->finalize = g_socket_connection_finalize;
444 gobject_class->dispose = g_socket_connection_dispose;
445
446 stream_class->get_input_stream = g_socket_connection_get_input_stream;
447 stream_class->get_output_stream = g_socket_connection_get_output_stream;
448 stream_class->close_fn = g_socket_connection_close;
449 stream_class->close_async = g_socket_connection_close_async;
450 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 g_object_class_install_property (gobject_class,
460 PROP_SOCKET,
461 g_param_spec_object ("socket", NULL, NULL,
462 G_TYPE_SOCKET,
463 G_PARAM_CONSTRUCT_ONLY |
464 G_PARAM_READWRITE |
465 G_PARAM_STATIC_STRINGS));
466 }
467
468 static void
469 g_socket_connection_init (GSocketConnection *connection)
470 {
471 connection->priv = g_socket_connection_get_instance_private (connection);
472 }
473
474 static gboolean
475 g_socket_connection_close (GIOStream *stream,
476 GCancellable *cancellable,
477 GError **error)
478 {
479 GSocketConnection *connection = G_SOCKET_CONNECTION (stream);
480
481 if (connection->priv->output_stream)
482 g_output_stream_close (connection->priv->output_stream,
483 cancellable, NULL);
484 if (connection->priv->input_stream)
485 g_input_stream_close (connection->priv->input_stream,
486 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 if (connection->priv->in_dispose)
495 return TRUE;
496
497 return g_socket_close (connection->priv->socket, error);
498 }
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 {
508 GTask *task;
509 GIOStreamClass *class;
510 GError *error;
511
512 class = G_IO_STREAM_GET_CLASS (stream);
513
514 task = g_task_new (stream, cancellable, callback, user_data);
515 g_task_set_source_tag (task, g_socket_connection_close_async);
516
517 /* socket close is not blocked, just do it! */
518 error = NULL;
519 if (class->close_fn &&
520 !class->close_fn (stream, cancellable, &error))
521 g_task_return_error (task, error);
522 else
523 g_task_return_boolean (task, TRUE);
524
525 g_object_unref (task);
526 }
527
528 static gboolean
529 g_socket_connection_close_finish (GIOStream *stream,
530 GAsyncResult *result,
531 GError **error)
532 {
533 return g_task_propagate_boolean (G_TASK (result), error);
534 }
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 {
546 const ConnectionFactory *factory = key;
547 guint h;
548
549 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 h = h ^ (h << 8) ^ (h << 16) ^ (h << 24);
553
554 return h;
555 }
556
557 static gboolean
558 connection_factory_equal (gconstpointer _a,
559 gconstpointer _b)
560 {
561 const ConnectionFactory *a = _a;
562 const ConnectionFactory *b = _b;
563
564 if (a->socket_family != b->socket_family)
565 return FALSE;
566
567 if (a->socket_type != b->socket_type)
568 return FALSE;
569
570 if (a->protocol != b->protocol)
571 return FALSE;
572
573 return TRUE;
574 }
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 {
599 ConnectionFactory *factory;
600
601 g_return_if_fail (g_type_is_a (g_type, G_TYPE_SOCKET_CONNECTION));
602
603 G_LOCK (connection_factories);
604
605 if (connection_factories == NULL)
606 connection_factories = g_hash_table_new_full (connection_factory_hash,
607 connection_factory_equal,
608 (GDestroyNotify)g_free,
609 NULL);
610
611 factory = g_new0 (ConnectionFactory, 1);
612 factory->socket_family = family;
613 factory->socket_type = type;
614 factory->protocol = protocol;
615 factory->implementation = g_type;
616
617 g_hash_table_insert (connection_factories,
618 factory, factory);
619
620 G_UNLOCK (connection_factories);
621 }
622
623 static void
624 init_builtin_types (void)
625 {
626 g_type_ensure (G_TYPE_UNIX_CONNECTION);
627 g_type_ensure (G_TYPE_TCP_CONNECTION);
628 }
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 {
650 ConnectionFactory *factory, key;
651 GType g_type;
652
653 init_builtin_types ();
654
655 G_LOCK (connection_factories);
656
657 g_type = G_TYPE_SOCKET_CONNECTION;
658
659 if (connection_factories)
660 {
661 key.socket_family = family;
662 key.socket_type = type;
663 key.protocol = protocol_id;
664
665 factory = g_hash_table_lookup (connection_factories, &key);
666 if (factory)
667 g_type = factory->implementation;
668 }
669
670 G_UNLOCK (connection_factories);
671
672 return g_type;
673 }
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 {
689 GType type;
690
691 type = g_socket_connection_factory_lookup_type (g_socket_get_family (socket),
692 g_socket_get_socket_type (socket),
693 g_socket_get_protocol (socket));
694 return g_object_new (type, "socket", socket, NULL);
695 }