1 /* GIO - GLib Input, Output and Streaming Library
3 * Copyright © 2008 Christian Kellner, Samuel Cormier-Iijima
5 * Copyright © 2009 Red Hat, Inc
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General
18 * Public License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
20 * Boston, MA 02111-1307, USA.
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>
30 #include "gsocketconnection.h"
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"
43 * SECTION:gsocketconnection
44 * @short_description: A socket connection
46 * @see_also: #GIOStream, #GSocketClient, #GSocketListener
48 * #GSocketConnection is a #GIOStream for a connected socket. They
49 * can be created either by #GSocketClient when connecting to a host,
50 * or by #GSocketListener when accepting a new client.
52 * The type of the #GSocketConnection object returned from these calls
53 * depends on the type of the underlying socket that is in use. For
54 * instance, for a TCP/IP connection it will be a #GTcpConnection.
56 * Choosing what type of object to construct is done with the socket
57 * connection factory, and it is possible for 3rd parties to register
58 * custom socket connection types for specific combination of socket
59 * family/type/protocol using g_socket_connection_factory_register_type().
70 struct _GSocketConnectionPrivate
73 GInputStream *input_stream;
74 GOutputStream *output_stream;
76 GSocketAddress *cached_remote_address;
81 static gboolean g_socket_connection_close (GIOStream *stream,
82 GCancellable *cancellable,
84 static void g_socket_connection_close_async (GIOStream *stream,
86 GCancellable *cancellable,
87 GAsyncReadyCallback callback,
89 static gboolean g_socket_connection_close_finish (GIOStream *stream,
93 G_DEFINE_TYPE_WITH_PRIVATE (GSocketConnection, g_socket_connection, G_TYPE_IO_STREAM)
96 g_socket_connection_get_input_stream (GIOStream *io_stream)
98 GSocketConnection *connection = G_SOCKET_CONNECTION (io_stream);
100 if (connection->priv->input_stream == NULL)
101 connection->priv->input_stream = (GInputStream *)
102 _g_socket_input_stream_new (connection->priv->socket);
104 return connection->priv->input_stream;
107 static GOutputStream *
108 g_socket_connection_get_output_stream (GIOStream *io_stream)
110 GSocketConnection *connection = G_SOCKET_CONNECTION (io_stream);
112 if (connection->priv->output_stream == NULL)
113 connection->priv->output_stream = (GOutputStream *)
114 _g_socket_output_stream_new (connection->priv->socket);
116 return connection->priv->output_stream;
120 * g_socket_connection_is_connected:
121 * @connection: a #GSocketConnection
123 * Checks if @connection is connected. This is equivalent to calling
124 * g_socket_is_connected() on @connection's underlying #GSocket.
126 * Returns: whether @connection is connected
131 g_socket_connection_is_connected (GSocketConnection *connection)
133 return g_socket_is_connected (connection->priv->socket);
137 * g_socket_connection_connect:
138 * @connection: a #GSocketConnection
139 * @address: a #GSocketAddress specifying the remote address.
140 * @cancellable: (allow-none): a %GCancellable or %NULL
141 * @error: #GError for error reporting, or %NULL to ignore.
143 * Connect @connection to the specified remote address.
145 * Returns: %TRUE if the connection succeeded, %FALSE on error
150 g_socket_connection_connect (GSocketConnection *connection,
151 GSocketAddress *address,
152 GCancellable *cancellable,
155 g_return_val_if_fail (G_IS_SOCKET_CONNECTION (connection), FALSE);
156 g_return_val_if_fail (G_IS_SOCKET_ADDRESS (address), FALSE);
158 return g_socket_connect (connection->priv->socket, address,
162 static gboolean g_socket_connection_connect_callback (GSocket *socket,
163 GIOCondition condition,
167 * g_socket_connection_connect_async:
168 * @connection: a #GSocketConnection
169 * @address: a #GSocketAddress specifying the remote address.
170 * @cancellable: (allow-none): a %GCancellable or %NULL
171 * @callback: (scope async): a #GAsyncReadyCallback
172 * @user_data: (closure): user data for the callback
174 * Asynchronously connect @connection to the specified remote address.
176 * This clears the #GSocket:blocking flag on @connection's underlying
177 * socket if it is currently set.
179 * Use g_socket_connection_connect_finish() to retrieve the result.
184 g_socket_connection_connect_async (GSocketConnection *connection,
185 GSocketAddress *address,
186 GCancellable *cancellable,
187 GAsyncReadyCallback callback,
191 GError *tmp_error = NULL;
193 g_return_if_fail (G_IS_SOCKET_CONNECTION (connection));
194 g_return_if_fail (G_IS_SOCKET_ADDRESS (address));
196 task = g_task_new (connection, cancellable, callback, user_data);
198 g_socket_set_blocking (connection->priv->socket, FALSE);
200 if (g_socket_connect (connection->priv->socket, address,
201 cancellable, &tmp_error))
203 g_task_return_boolean (task, TRUE);
204 g_object_unref (task);
206 else if (g_error_matches (tmp_error, G_IO_ERROR, G_IO_ERROR_PENDING))
210 g_error_free (tmp_error);
211 source = g_socket_create_source (connection->priv->socket,
212 G_IO_OUT, cancellable);
213 g_task_attach_source (task, source,
214 (GSourceFunc) g_socket_connection_connect_callback);
215 g_source_unref (source);
219 g_task_return_error (task, tmp_error);
220 g_object_unref (task);
225 g_socket_connection_connect_callback (GSocket *socket,
226 GIOCondition condition,
229 GTask *task = user_data;
230 GSocketConnection *connection = g_task_get_source_object (task);
231 GError *error = NULL;
233 if (g_socket_check_connect_result (connection->priv->socket, &error))
234 g_task_return_boolean (task, TRUE);
236 g_task_return_error (task, error);
238 g_object_unref (task);
243 * g_socket_connection_connect_finish:
244 * @connection: a #GSocketConnection
245 * @result: the #GAsyncResult
246 * @error: #GError for error reporting, or %NULL to ignore.
248 * Gets the result of a g_socket_connection_connect_async() call.
250 * Returns: %TRUE if the connection succeeded, %FALSE on error
255 g_socket_connection_connect_finish (GSocketConnection *connection,
256 GAsyncResult *result,
259 g_return_val_if_fail (G_IS_SOCKET_CONNECTION (connection), FALSE);
260 g_return_val_if_fail (g_task_is_valid (result, connection), FALSE);
262 return g_task_propagate_boolean (G_TASK (result), error);
266 * g_socket_connection_get_socket:
267 * @connection: a #GSocketConnection
269 * Gets the underlying #GSocket object of the connection.
270 * This can be useful if you want to do something unusual on it
271 * not supported by the #GSocketConnection APIs.
273 * Returns: (transfer none): a #GSocketAddress or %NULL on error.
278 g_socket_connection_get_socket (GSocketConnection *connection)
280 g_return_val_if_fail (G_IS_SOCKET_CONNECTION (connection), NULL);
282 return connection->priv->socket;
286 * g_socket_connection_get_local_address:
287 * @connection: a #GSocketConnection
288 * @error: #GError for error reporting, or %NULL to ignore.
290 * Try to get the local address of a socket connection.
292 * Returns: (transfer full): a #GSocketAddress or %NULL on error.
293 * Free the returned object with g_object_unref().
298 g_socket_connection_get_local_address (GSocketConnection *connection,
301 return g_socket_get_local_address (connection->priv->socket, error);
305 * g_socket_connection_get_remote_address:
306 * @connection: a #GSocketConnection
307 * @error: #GError for error reporting, or %NULL to ignore.
309 * Try to get the remote address of a socket connection.
311 * Since GLib 2.40, when used with g_socket_client_connect() or
312 * g_socket_client_connect_async(), during emission of
313 * %G_SOCKET_CLIENT_CONNECTING, this function will return the remote
314 * address that will be used for the connection. This allows
315 * applications to print e.g. "Connecting to example.com
318 * Returns: (transfer full): a #GSocketAddress or %NULL on error.
319 * Free the returned object with g_object_unref().
324 g_socket_connection_get_remote_address (GSocketConnection *connection,
327 if (!g_socket_is_connected (connection->priv->socket))
329 return connection->priv->cached_remote_address ?
330 g_object_ref (connection->priv->cached_remote_address) : NULL;
332 return g_socket_get_remote_address (connection->priv->socket, error);
335 /* Private API allowing applications to retrieve the resolved address
336 * now, before we start connecting.
338 * https://bugzilla.gnome.org/show_bug.cgi?id=712547
341 g_socket_connection_set_cached_remote_address (GSocketConnection *connection,
342 GSocketAddress *address)
344 g_clear_object (&connection->priv->cached_remote_address);
345 connection->priv->cached_remote_address = address ? g_object_ref (address) : NULL;
349 g_socket_connection_get_property (GObject *object,
354 GSocketConnection *connection = G_SOCKET_CONNECTION (object);
359 g_value_set_object (value, connection->priv->socket);
363 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
368 g_socket_connection_set_property (GObject *object,
373 GSocketConnection *connection = G_SOCKET_CONNECTION (object);
378 connection->priv->socket = G_SOCKET (g_value_dup_object (value));
382 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
387 g_socket_connection_constructed (GObject *object)
389 GSocketConnection *connection = G_SOCKET_CONNECTION (object);
391 g_assert (connection->priv->socket != NULL);
395 g_socket_connection_dispose (GObject *object)
397 GSocketConnection *connection = G_SOCKET_CONNECTION (object);
399 connection->priv->in_dispose = TRUE;
401 g_clear_object (&connection->priv->cached_remote_address);
403 G_OBJECT_CLASS (g_socket_connection_parent_class)
406 connection->priv->in_dispose = FALSE;
410 g_socket_connection_finalize (GObject *object)
412 GSocketConnection *connection = G_SOCKET_CONNECTION (object);
414 if (connection->priv->input_stream)
415 g_object_unref (connection->priv->input_stream);
417 if (connection->priv->output_stream)
418 g_object_unref (connection->priv->output_stream);
420 g_object_unref (connection->priv->socket);
422 G_OBJECT_CLASS (g_socket_connection_parent_class)
427 g_socket_connection_class_init (GSocketConnectionClass *klass)
429 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
430 GIOStreamClass *stream_class = G_IO_STREAM_CLASS (klass);
432 gobject_class->set_property = g_socket_connection_set_property;
433 gobject_class->get_property = g_socket_connection_get_property;
434 gobject_class->constructed = g_socket_connection_constructed;
435 gobject_class->finalize = g_socket_connection_finalize;
436 gobject_class->dispose = g_socket_connection_dispose;
438 stream_class->get_input_stream = g_socket_connection_get_input_stream;
439 stream_class->get_output_stream = g_socket_connection_get_output_stream;
440 stream_class->close_fn = g_socket_connection_close;
441 stream_class->close_async = g_socket_connection_close_async;
442 stream_class->close_finish = g_socket_connection_close_finish;
444 g_object_class_install_property (gobject_class,
446 g_param_spec_object ("socket",
448 P_("The underlying GSocket"),
450 G_PARAM_CONSTRUCT_ONLY |
452 G_PARAM_STATIC_STRINGS));
456 g_socket_connection_init (GSocketConnection *connection)
458 connection->priv = g_socket_connection_get_instance_private (connection);
462 g_socket_connection_close (GIOStream *stream,
463 GCancellable *cancellable,
466 GSocketConnection *connection = G_SOCKET_CONNECTION (stream);
468 if (connection->priv->output_stream)
469 g_output_stream_close (connection->priv->output_stream,
471 if (connection->priv->input_stream)
472 g_input_stream_close (connection->priv->input_stream,
475 /* Don't close the underlying socket if this is being called
476 * as part of dispose(); when destroying the GSocketConnection,
477 * we only want to close the socket if we're holding the last
478 * reference on it, and in that case it will close itself when
479 * we unref it in finalize().
481 if (connection->priv->in_dispose)
484 return g_socket_close (connection->priv->socket, error);
489 g_socket_connection_close_async (GIOStream *stream,
491 GCancellable *cancellable,
492 GAsyncReadyCallback callback,
496 GIOStreamClass *class;
499 class = G_IO_STREAM_GET_CLASS (stream);
501 task = g_task_new (stream, cancellable, callback, user_data);
503 /* socket close is not blocked, just do it! */
505 if (class->close_fn &&
506 !class->close_fn (stream, cancellable, &error))
507 g_task_return_error (task, error);
509 g_task_return_boolean (task, TRUE);
511 g_object_unref (task);
515 g_socket_connection_close_finish (GIOStream *stream,
516 GAsyncResult *result,
519 return g_task_propagate_boolean (G_TASK (result), error);
523 GSocketFamily socket_family;
524 GSocketType socket_type;
526 GType implementation;
530 connection_factory_hash (gconstpointer key)
532 const ConnectionFactory *factory = key;
535 h = factory->socket_family ^ (factory->socket_type << 4) ^ (factory->protocol << 8);
536 /* This is likely to be small, so spread over whole
537 hash space to get some distribution */
538 h = h ^ (h << 8) ^ (h << 16) ^ (h << 24);
544 connection_factory_equal (gconstpointer _a,
547 const ConnectionFactory *a = _a;
548 const ConnectionFactory *b = _b;
550 if (a->socket_family != b->socket_family)
553 if (a->socket_type != b->socket_type)
556 if (a->protocol != b->protocol)
562 static GHashTable *connection_factories = NULL;
563 G_LOCK_DEFINE_STATIC(connection_factories);
566 * g_socket_connection_factory_register_type:
567 * @g_type: a #GType, inheriting from %G_TYPE_SOCKET_CONNECTION
568 * @family: a #GSocketFamily
569 * @type: a #GSocketType
570 * @protocol: a protocol id
572 * Looks up the #GType to be used when creating socket connections on
573 * sockets with the specified @family, @type and @protocol.
575 * If no type is registered, the #GSocketConnection base type is returned.
580 g_socket_connection_factory_register_type (GType g_type,
581 GSocketFamily family,
585 ConnectionFactory *factory;
587 g_return_if_fail (g_type_is_a (g_type, G_TYPE_SOCKET_CONNECTION));
589 G_LOCK (connection_factories);
591 if (connection_factories == NULL)
592 connection_factories = g_hash_table_new_full (connection_factory_hash,
593 connection_factory_equal,
594 (GDestroyNotify)g_free,
597 factory = g_new0 (ConnectionFactory, 1);
598 factory->socket_family = family;
599 factory->socket_type = type;
600 factory->protocol = protocol;
601 factory->implementation = g_type;
603 g_hash_table_insert (connection_factories,
606 G_UNLOCK (connection_factories);
610 init_builtin_types (void)
613 g_type_ensure (G_TYPE_UNIX_CONNECTION);
615 g_type_ensure (G_TYPE_TCP_CONNECTION);
619 * g_socket_connection_factory_lookup_type:
620 * @family: a #GSocketFamily
621 * @type: a #GSocketType
622 * @protocol_id: a protocol id
624 * Looks up the #GType to be used when creating socket connections on
625 * sockets with the specified @family, @type and @protocol_id.
627 * If no type is registered, the #GSocketConnection base type is returned.
634 g_socket_connection_factory_lookup_type (GSocketFamily family,
638 ConnectionFactory *factory, key;
641 init_builtin_types ();
643 G_LOCK (connection_factories);
645 g_type = G_TYPE_SOCKET_CONNECTION;
647 if (connection_factories)
649 key.socket_family = family;
650 key.socket_type = type;
651 key.protocol = protocol_id;
653 factory = g_hash_table_lookup (connection_factories, &key);
655 g_type = factory->implementation;
658 G_UNLOCK (connection_factories);
664 * g_socket_connection_factory_create_connection:
665 * @socket: a #GSocket
667 * Creates a #GSocketConnection subclass of the right type for
670 * Returns: (transfer full): a #GSocketConnection
675 g_socket_connection_factory_create_connection (GSocket *socket)
679 type = g_socket_connection_factory_lookup_type (g_socket_get_family (socket),
680 g_socket_get_socket_type (socket),
681 g_socket_get_protocol (socket));
682 return g_object_new (type, "socket", socket, NULL);