| 
									
										
										
										
											2009-05-14 15:26:37 +02:00
										 |  |  |  | /* GIO - GLib Input, Output and Streaming Library
 | 
					
						
							|  |  |  |  |  * | 
					
						
							|  |  |  |  |  * Copyright © 2009 Codethink Limited | 
					
						
							|  |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2022-05-18 09:12:45 +01:00
										 |  |  |  |  * SPDX-License-Identifier: LGPL-2.1-or-later | 
					
						
							|  |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2017-05-27 18:21:30 +02:00
										 |  |  |  |  * This library is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  |  * modify it under the terms of the GNU Lesser General Public | 
					
						
							|  |  |  |  |  * License as published by the Free Software Foundation; either | 
					
						
							|  |  |  |  |  * version 2.1 of the License, or (at your option) any later version. | 
					
						
							| 
									
										
										
										
											2009-05-14 15:26:37 +02:00
										 |  |  |  |  * | 
					
						
							|  |  |  |  |  * See the included COPYING file for more information. | 
					
						
							|  |  |  |  |  * | 
					
						
							|  |  |  |  |  * Authors: Ryan Lortie <desrt@desrt.ca> | 
					
						
							|  |  |  |  |  */ | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2023-11-14 14:26:38 +00:00
										 |  |  |  |  * GSocketControlMessage: | 
					
						
							| 
									
										
										
										
											2009-05-14 15:26:37 +02:00
										 |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2023-11-14 14:26:38 +00:00
										 |  |  |  |  * A `GSocketControlMessage` is a special-purpose utility message that | 
					
						
							|  |  |  |  |  * can be sent to or received from a [class@Gio.Socket]. These types of | 
					
						
							|  |  |  |  |  * messages are often called ‘ancillary data’. | 
					
						
							| 
									
										
										
										
											2009-05-14 15:26:37 +02:00
										 |  |  |  |  * | 
					
						
							|  |  |  |  |  * The message can represent some sort of special instruction to or | 
					
						
							|  |  |  |  |  * information from the socket or can represent a special kind of | 
					
						
							| 
									
										
										
										
											2013-09-27 14:52:51 +12:00
										 |  |  |  |  * transfer to the peer (for example, sending a file descriptor over | 
					
						
							| 
									
										
										
										
											2009-05-14 15:26:37 +02:00
										 |  |  |  |  * a UNIX socket). | 
					
						
							|  |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2023-11-14 14:26:38 +00:00
										 |  |  |  |  * These messages are sent with [method@Gio.Socket.send_message] and received | 
					
						
							|  |  |  |  |  * with [method@Gio.Socket.receive_message]. | 
					
						
							| 
									
										
										
										
											2009-05-14 15:26:37 +02:00
										 |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2025-10-13 16:59:22 +01:00
										 |  |  |  |  * To extend the set of control messages that can be sent, subclass this | 
					
						
							| 
									
										
										
										
											2023-11-14 14:26:38 +00:00
										 |  |  |  |  * class and override the `get_size`, `get_level`, `get_type` and `serialize` | 
					
						
							| 
									
										
										
										
											2009-05-14 15:26:37 +02:00
										 |  |  |  |  * methods. | 
					
						
							|  |  |  |  |  * | 
					
						
							|  |  |  |  |  * To extend the set of control messages that can be received, subclass | 
					
						
							| 
									
										
										
										
											2023-11-14 14:26:38 +00:00
										 |  |  |  |  * this class and implement the `deserialize` method. Also, make sure your | 
					
						
							|  |  |  |  |  * class is registered with the [type@GObject.Type] type system before calling | 
					
						
							|  |  |  |  |  * [method@Gio.Socket.receive_message] to read such a message. | 
					
						
							| 
									
										
										
										
											2009-05-14 15:26:37 +02:00
										 |  |  |  |  * | 
					
						
							|  |  |  |  |  * Since: 2.22 | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-05-14 15:26:37 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | #include "config.h"
 | 
					
						
							|  |  |  |  | #include "gsocketcontrolmessage.h"
 | 
					
						
							| 
									
										
										
										
											2009-04-27 17:35:04 -04:00
										 |  |  |  | #include "gnetworkingprivate.h"
 | 
					
						
							| 
									
										
										
										
											2009-05-14 15:26:37 +02:00
										 |  |  |  | #include "glibintl.h"
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #ifndef G_OS_WIN32
 | 
					
						
							| 
									
										
										
										
											2010-09-22 06:45:02 -04:00
										 |  |  |  | #include "gunixcredentialsmessage.h"
 | 
					
						
							| 
									
										
										
										
											2009-05-14 15:26:37 +02:00
										 |  |  |  | #include "gunixfdmessage.h"
 | 
					
						
							|  |  |  |  | #endif
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-17 11:54:02 +01:00
										 |  |  |  | G_DEFINE_ABSTRACT_TYPE (GSocketControlMessage, g_socket_control_message, G_TYPE_OBJECT) | 
					
						
							| 
									
										
										
										
											2009-05-14 15:26:37 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | /**
 | 
					
						
							|  |  |  |  |  * g_socket_control_message_get_size: | 
					
						
							|  |  |  |  |  * @message: a #GSocketControlMessage | 
					
						
							|  |  |  |  |  * | 
					
						
							|  |  |  |  |  * Returns the space required for the control message, not including | 
					
						
							|  |  |  |  |  * headers or alignment. | 
					
						
							|  |  |  |  |  * | 
					
						
							|  |  |  |  |  * Returns: The number of bytes required. | 
					
						
							|  |  |  |  |  * | 
					
						
							|  |  |  |  |  * Since: 2.22 | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-05-14 15:26:37 +02:00
										 |  |  |  | gsize | 
					
						
							|  |  |  |  | g_socket_control_message_get_size (GSocketControlMessage *message) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   g_return_val_if_fail (G_IS_SOCKET_CONTROL_MESSAGE (message), 0); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   return G_SOCKET_CONTROL_MESSAGE_GET_CLASS (message)->get_size (message); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /**
 | 
					
						
							|  |  |  |  |  * g_socket_control_message_get_level: | 
					
						
							|  |  |  |  |  * @message: a #GSocketControlMessage | 
					
						
							|  |  |  |  |  * | 
					
						
							|  |  |  |  |  * Returns the "level" (i.e. the originating protocol) of the control message. | 
					
						
							|  |  |  |  |  * This is often SOL_SOCKET. | 
					
						
							|  |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  |  |  * Returns: an integer describing the level | 
					
						
							| 
									
										
										
										
											2009-05-14 15:26:37 +02:00
										 |  |  |  |  * | 
					
						
							|  |  |  |  |  * Since: 2.22 | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-05-14 15:26:37 +02:00
										 |  |  |  | int | 
					
						
							|  |  |  |  | g_socket_control_message_get_level (GSocketControlMessage *message) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   g_return_val_if_fail (G_IS_SOCKET_CONTROL_MESSAGE (message), 0); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   return G_SOCKET_CONTROL_MESSAGE_GET_CLASS (message)->get_level (message); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /**
 | 
					
						
							|  |  |  |  |  * g_socket_control_message_get_msg_type: | 
					
						
							|  |  |  |  |  * @message: a #GSocketControlMessage | 
					
						
							|  |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  |  |  * Returns the protocol specific type of the control message. | 
					
						
							|  |  |  |  |  * For instance, for UNIX fd passing this would be SCM_RIGHTS. | 
					
						
							| 
									
										
										
										
											2009-05-14 15:26:37 +02:00
										 |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  |  |  * Returns: an integer describing the type of control message | 
					
						
							| 
									
										
										
										
											2009-05-14 15:26:37 +02:00
										 |  |  |  |  * | 
					
						
							|  |  |  |  |  * Since: 2.22 | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-05-14 15:26:37 +02:00
										 |  |  |  | int | 
					
						
							|  |  |  |  | g_socket_control_message_get_msg_type (GSocketControlMessage *message) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   g_return_val_if_fail (G_IS_SOCKET_CONTROL_MESSAGE (message), 0); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   return G_SOCKET_CONTROL_MESSAGE_GET_CLASS (message)->get_type (message); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /**
 | 
					
						
							|  |  |  |  |  * g_socket_control_message_serialize: | 
					
						
							|  |  |  |  |  * @message: a #GSocketControlMessage | 
					
						
							| 
									
										
										
										
											2013-12-06 12:23:09 +00:00
										 |  |  |  |  * @data: (not nullable): A buffer to write data to | 
					
						
							| 
									
										
										
										
											2009-05-14 15:26:37 +02:00
										 |  |  |  |  * | 
					
						
							|  |  |  |  |  * Converts the data in the message to bytes placed in the | 
					
						
							|  |  |  |  |  * message. | 
					
						
							|  |  |  |  |  * | 
					
						
							|  |  |  |  |  * @data is guaranteed to have enough space to fit the size | 
					
						
							|  |  |  |  |  * returned by g_socket_control_message_get_size() on this | 
					
						
							|  |  |  |  |  * object. | 
					
						
							|  |  |  |  |  * | 
					
						
							|  |  |  |  |  * Since: 2.22 | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-05-14 15:26:37 +02:00
										 |  |  |  | void | 
					
						
							|  |  |  |  | g_socket_control_message_serialize (GSocketControlMessage *message, | 
					
						
							|  |  |  |  | 				    gpointer               data) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   g_return_if_fail (G_IS_SOCKET_CONTROL_MESSAGE (message)); | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-25 12:46:03 +02:00
										 |  |  |  |   G_SOCKET_CONTROL_MESSAGE_GET_CLASS (message)->serialize (message, data); | 
					
						
							| 
									
										
										
										
											2009-05-14 15:26:37 +02:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | static void | 
					
						
							|  |  |  |  | g_socket_control_message_init (GSocketControlMessage *message) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | static void | 
					
						
							|  |  |  |  | g_socket_control_message_class_init (GSocketControlMessageClass *class) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  |  | /**
 | 
					
						
							|  |  |  |  |  * g_socket_control_message_deserialize: | 
					
						
							| 
									
										
										
										
											2009-05-28 15:33:52 +02:00
										 |  |  |  |  * @level: a socket level | 
					
						
							|  |  |  |  |  * @type: a socket control message type for the given @level | 
					
						
							|  |  |  |  |  * @size: the size of the data in bytes | 
					
						
							| 
									
										
										
										
											2010-12-29 13:51:44 +01:00
										 |  |  |  |  * @data: (array length=size) (element-type guint8): pointer to the message data | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2009-05-28 15:33:52 +02:00
										 |  |  |  |  * Tries to deserialize a socket control message of a given | 
					
						
							|  |  |  |  |  * @level and @type. This will ask all known (to GType) subclasses | 
					
						
							|  |  |  |  |  * of #GSocketControlMessage if they can understand this kind | 
					
						
							|  |  |  |  |  * of message and if so deserialize it into a #GSocketControlMessage. | 
					
						
							|  |  |  |  |  * | 
					
						
							|  |  |  |  |  * If there is no implementation for this kind of control message, %NULL | 
					
						
							|  |  |  |  |  * will be returned. | 
					
						
							|  |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2022-11-29 17:46:16 -05:00
										 |  |  |  |  * Returns: (nullable) (transfer full): the deserialized message or %NULL | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  |  |  * | 
					
						
							|  |  |  |  |  * Since: 2.22 | 
					
						
							|  |  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-05-14 15:26:37 +02:00
										 |  |  |  | GSocketControlMessage * | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  |  | g_socket_control_message_deserialize (int      level, | 
					
						
							|  |  |  |  | 				      int      type, | 
					
						
							|  |  |  |  | 				      gsize    size, | 
					
						
							|  |  |  |  | 				      gpointer data) | 
					
						
							| 
									
										
										
										
											2009-05-14 15:26:37 +02:00
										 |  |  |  | { | 
					
						
							|  |  |  |  |   GSocketControlMessage *message; | 
					
						
							|  |  |  |  |   GType *message_types; | 
					
						
							|  |  |  |  |   guint n_message_types; | 
					
						
							| 
									
										
										
										
											2020-11-17 00:44:45 +01:00
										 |  |  |  |   guint i; | 
					
						
							| 
									
										
										
										
											2009-05-14 15:26:37 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   /* Ensure we know about the built in types */ | 
					
						
							|  |  |  |  | #ifndef G_OS_WIN32
 | 
					
						
							| 
									
										
										
										
											2010-01-03 14:47:56 -05:00
										 |  |  |  |   g_type_ensure (G_TYPE_UNIX_CREDENTIALS_MESSAGE); | 
					
						
							|  |  |  |  |   g_type_ensure (G_TYPE_UNIX_FD_MESSAGE); | 
					
						
							| 
									
										
										
										
											2009-05-14 15:26:37 +02:00
										 |  |  |  | #endif
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   message_types = g_type_children (G_TYPE_SOCKET_CONTROL_MESSAGE, &n_message_types); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   message = NULL; | 
					
						
							|  |  |  |  |   for (i = 0; i < n_message_types; i++) | 
					
						
							|  |  |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-09-22 06:45:02 -04:00
										 |  |  |  |       GSocketControlMessageClass *class; | 
					
						
							| 
									
										
										
										
											2009-05-14 15:26:37 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-22 06:45:02 -04:00
										 |  |  |  |       class = g_type_class_ref (message_types[i]); | 
					
						
							|  |  |  |  |       message = class->deserialize (level, type, size, data); | 
					
						
							|  |  |  |  |       g_type_class_unref (class); | 
					
						
							| 
									
										
										
										
											2009-05-14 15:26:37 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |       if (message != NULL) | 
					
						
							| 
									
										
										
										
											2010-09-22 06:45:02 -04:00
										 |  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2009-05-14 15:26:37 +02:00
										 |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   g_free (message_types); | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-14 12:29:30 -04:00
										 |  |  |  |   /* It's not a bug if we can't deserialize the control message - for
 | 
					
						
							|  |  |  |  |    * example, the control message may be be discarded if it is deemed | 
					
						
							|  |  |  |  |    * empty, see e.g. | 
					
						
							|  |  |  |  |    * | 
					
						
							| 
									
										
										
										
											2021-03-24 16:18:21 +05:30
										 |  |  |  |    *  https://gitlab.gnome.org/GNOME/glib/commit/ec91ed00f14c70cca9749347b8ebc19d72d9885b
 | 
					
						
							| 
									
										
										
										
											2012-04-14 12:29:30 -04:00
										 |  |  |  |    * | 
					
						
							|  |  |  |  |    * Therefore, it's not appropriate to print a warning about not | 
					
						
							|  |  |  |  |    * being able to deserialize the message. | 
					
						
							|  |  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2009-05-14 15:26:37 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   return message; | 
					
						
							|  |  |  |  | } |