mirror of
				https://gitlab.gnome.org/GNOME/glib.git
				synced 2025-11-04 01:58:54 +01:00 
			
		
		
		
	GSocketClient: For _CONNECTING event, make remote address accessible
My application (hotssh) would like to get the resolved address from DNS, before we start the connect(). We could add a new event, but it's easy enough to just cache it on the GSocketConnection; this avoids any new API. https://bugzilla.gnome.org/show_bug.cgi?id=712547
This commit is contained in:
		@@ -23,12 +23,18 @@
 | 
			
		||||
 | 
			
		||||
#include "ginputstream.h"
 | 
			
		||||
#include "goutputstream.h"
 | 
			
		||||
#include "gsocketconnection.h"
 | 
			
		||||
#include "gsocketaddress.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
gboolean g_input_stream_async_read_is_via_threads (GInputStream *stream);
 | 
			
		||||
gboolean g_output_stream_async_write_is_via_threads (GOutputStream *stream);
 | 
			
		||||
 | 
			
		||||
void g_socket_connection_set_cached_remote_address (GSocketConnection *connection,
 | 
			
		||||
                                                    GSocketAddress    *address);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __G_IO_PRIVATE__ */
 | 
			
		||||
 
 | 
			
		||||
@@ -32,6 +32,7 @@
 | 
			
		||||
#include <gio/gsocketaddressenumerator.h>
 | 
			
		||||
#include <gio/gsocketconnectable.h>
 | 
			
		||||
#include <gio/gsocketconnection.h>
 | 
			
		||||
#include <gio/gioprivate.h>
 | 
			
		||||
#include <gio/gproxyaddressenumerator.h>
 | 
			
		||||
#include <gio/gproxyaddress.h>
 | 
			
		||||
#include <gio/gtask.h>
 | 
			
		||||
@@ -796,7 +797,8 @@ g_socket_client_class_init (GSocketClientClass *class)
 | 
			
		||||
   *       @client is about to make a connection to a remote host;
 | 
			
		||||
   *       either a proxy server or the destination server itself.
 | 
			
		||||
   *       @connection is the #GSocketConnection, which is not yet
 | 
			
		||||
   *       connected.
 | 
			
		||||
   *       connected.  Since GLib 2.40, you can access the remote
 | 
			
		||||
   *       address via g_socket_connection_get_remote_address().
 | 
			
		||||
   *     </para></listitem>
 | 
			
		||||
   *   </varlistentry>
 | 
			
		||||
   *   <varlistentry>
 | 
			
		||||
@@ -1084,11 +1086,13 @@ g_socket_client_connect (GSocketClient       *client,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
      connection = (GIOStream *)g_socket_connection_factory_create_connection (socket);
 | 
			
		||||
      g_socket_connection_set_cached_remote_address ((GSocketConnection*)connection, address);
 | 
			
		||||
      g_socket_client_emit_event (client, G_SOCKET_CLIENT_CONNECTING, connectable, connection);
 | 
			
		||||
 | 
			
		||||
      if (g_socket_connection_connect (G_SOCKET_CONNECTION (connection),
 | 
			
		||||
				       address, cancellable, &last_error))
 | 
			
		||||
	{
 | 
			
		||||
          g_socket_connection_set_cached_remote_address ((GSocketConnection*)connection, NULL);
 | 
			
		||||
	  g_socket_client_emit_event (client, G_SOCKET_CLIENT_CONNECTED, connectable, connection);
 | 
			
		||||
	}
 | 
			
		||||
      else
 | 
			
		||||
@@ -1542,6 +1546,7 @@ g_socket_client_connected_callback (GObject      *source,
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_socket_connection_set_cached_remote_address ((GSocketConnection*)data->connection, NULL);
 | 
			
		||||
  g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_CONNECTED, data->connectable, data->connection);
 | 
			
		||||
 | 
			
		||||
  /* wrong, but backward compatible */
 | 
			
		||||
@@ -1657,6 +1662,7 @@ g_socket_client_enumerator_callback (GObject      *object,
 | 
			
		||||
  data->current_addr = address;
 | 
			
		||||
  data->connection = (GIOStream *) g_socket_connection_factory_create_connection (socket);
 | 
			
		||||
 | 
			
		||||
  g_socket_connection_set_cached_remote_address ((GSocketConnection*)data->connection, address);
 | 
			
		||||
  g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_CONNECTING, data->connectable, data->connection);
 | 
			
		||||
  g_socket_connection_connect_async (G_SOCKET_CONNECTION (data->connection),
 | 
			
		||||
				     address,
 | 
			
		||||
 
 | 
			
		||||
@@ -31,6 +31,7 @@
 | 
			
		||||
 | 
			
		||||
#include "gsocketoutputstream.h"
 | 
			
		||||
#include "gsocketinputstream.h"
 | 
			
		||||
#include "gioprivate.h"
 | 
			
		||||
#include <gio/giostream.h>
 | 
			
		||||
#include <gio/gtask.h>
 | 
			
		||||
#include "gunixconnection.h"
 | 
			
		||||
@@ -72,6 +73,8 @@ struct _GSocketConnectionPrivate
 | 
			
		||||
  GInputStream  *input_stream;
 | 
			
		||||
  GOutputStream *output_stream;
 | 
			
		||||
 | 
			
		||||
  GSocketAddress *cached_remote_address;
 | 
			
		||||
 | 
			
		||||
  gboolean       in_dispose;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -305,6 +308,13 @@ g_socket_connection_get_local_address (GSocketConnection  *connection,
 | 
			
		||||
 *
 | 
			
		||||
 * Try to get the remote address of a socket connection.
 | 
			
		||||
 *
 | 
			
		||||
 * Since GLib 2.40, when used with g_socket_client_connect() or
 | 
			
		||||
 * g_socket_client_connect_async(), during emission of
 | 
			
		||||
 * %G_SOCKET_CLIENT_CONNECTING, this function will return the remote
 | 
			
		||||
 * address that will be used for the connection.  This allows
 | 
			
		||||
 * applications to print e.g. "Connecting to example.com
 | 
			
		||||
 * (10.42.77.3)...".
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: (transfer full): a #GSocketAddress or %NULL on error.
 | 
			
		||||
 *     Free the returned object with g_object_unref().
 | 
			
		||||
 *
 | 
			
		||||
@@ -314,9 +324,27 @@ GSocketAddress *
 | 
			
		||||
g_socket_connection_get_remote_address (GSocketConnection  *connection,
 | 
			
		||||
					GError            **error)
 | 
			
		||||
{
 | 
			
		||||
  if (!g_socket_is_connected (connection->priv->socket))
 | 
			
		||||
    {
 | 
			
		||||
      return connection->priv->cached_remote_address ?
 | 
			
		||||
        g_object_ref (connection->priv->cached_remote_address) : NULL;
 | 
			
		||||
    }
 | 
			
		||||
  return g_socket_get_remote_address (connection->priv->socket, error);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Private API allowing applications to retrieve the resolved address
 | 
			
		||||
 * now, before we start connecting.
 | 
			
		||||
 *
 | 
			
		||||
 * https://bugzilla.gnome.org/show_bug.cgi?id=712547
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
g_socket_connection_set_cached_remote_address (GSocketConnection *connection,
 | 
			
		||||
                                               GSocketAddress    *address)
 | 
			
		||||
{
 | 
			
		||||
  g_clear_object (&connection->priv->cached_remote_address);
 | 
			
		||||
  connection->priv->cached_remote_address = address ? g_object_ref (address) : NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_socket_connection_get_property (GObject    *object,
 | 
			
		||||
                                  guint       prop_id,
 | 
			
		||||
@@ -370,6 +398,8 @@ g_socket_connection_dispose (GObject *object)
 | 
			
		||||
 | 
			
		||||
  connection->priv->in_dispose = TRUE;
 | 
			
		||||
 | 
			
		||||
  g_clear_object (&connection->priv->cached_remote_address);
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (g_socket_connection_parent_class)
 | 
			
		||||
    ->dispose (object);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user