Commit 69130db8 authored by Alexander Larsson's avatar Alexander Larsson

Read socket state in g_socket_get_local/remote_address

Previously we saved the location in various places which is unnecessary
and sometimes even wrong. For instance, we saved the address we bound to
which may not have the final port set.
parent f8cd1c53
...@@ -136,12 +136,11 @@ struct _GSocketPrivate ...@@ -136,12 +136,11 @@ struct _GSocketPrivate
gint fd; gint fd;
gint listen_backlog; gint listen_backlog;
GError *construct_error; GError *construct_error;
GSocketAddress *local_address;
GSocketAddress *remote_address;
guint inited : 1; guint inited : 1;
guint blocking : 1; guint blocking : 1;
guint keepalive : 1; guint keepalive : 1;
guint closed : 1; guint closed : 1;
guint connected : 1;
#ifdef G_OS_WIN32 #ifdef G_OS_WIN32
WSAEVENT event; WSAEVENT event;
int current_events; int current_events;
...@@ -373,13 +372,9 @@ g_socket_details_from_fd (GSocket *socket) ...@@ -373,13 +372,9 @@ g_socket_details_from_fd (GSocket *socket)
if (socket->priv->family != G_SOCKET_FAMILY_INVALID) if (socket->priv->family != G_SOCKET_FAMILY_INVALID)
{ {
socket->priv->local_address =
g_socket_address_new_from_native (&address, addrlen);
addrlen = sizeof address; addrlen = sizeof address;
if (getpeername (fd, (struct sockaddr *) &address, &addrlen) >= 0) if (getpeername (fd, (struct sockaddr *) &address, &addrlen) >= 0)
socket->priv->remote_address = socket->priv->connected = TRUE;
g_socket_address_new_from_native (&address, addrlen);
} }
optlen = sizeof bool_val; optlen = sizeof bool_val;
...@@ -580,6 +575,7 @@ g_socket_get_property (GObject *object, ...@@ -580,6 +575,7 @@ g_socket_get_property (GObject *object,
GParamSpec *pspec) GParamSpec *pspec)
{ {
GSocket *socket = G_SOCKET (object); GSocket *socket = G_SOCKET (object);
GSocketAddress *address;
switch (prop_id) switch (prop_id)
{ {
...@@ -612,11 +608,13 @@ g_socket_get_property (GObject *object, ...@@ -612,11 +608,13 @@ g_socket_get_property (GObject *object,
break; break;
case PROP_LOCAL_ADDRESS: case PROP_LOCAL_ADDRESS:
g_value_set_object (value, socket->priv->local_address); address = g_socket_get_local_address (socket, NULL);
g_value_take_object (value, address);
break; break;
case PROP_REMOTE_ADDRESS: case PROP_REMOTE_ADDRESS:
g_value_set_object (value, socket->priv->remote_address); address = g_socket_get_remote_address (socket, NULL);
g_value_take_object (value, address);
break; break;
default: default:
...@@ -686,27 +684,6 @@ g_socket_finalize (GObject *object) ...@@ -686,27 +684,6 @@ g_socket_finalize (GObject *object)
(*G_OBJECT_CLASS (g_socket_parent_class)->finalize) (object); (*G_OBJECT_CLASS (g_socket_parent_class)->finalize) (object);
} }
static void
g_socket_dispose (GObject *object)
{
GSocket *socket = G_SOCKET (object);
if (socket->priv->local_address)
{
g_object_unref (socket->priv->local_address);
socket->priv->local_address = NULL;
}
if (socket->priv->remote_address)
{
g_object_unref (socket->priv->remote_address);
socket->priv->remote_address = NULL;
}
if (G_OBJECT_CLASS (g_socket_parent_class)->dispose)
(*G_OBJECT_CLASS (g_socket_parent_class)->dispose) (object);
}
static void static void
g_socket_class_init (GSocketClass *klass) g_socket_class_init (GSocketClass *klass)
{ {
...@@ -719,7 +696,6 @@ g_socket_class_init (GSocketClass *klass) ...@@ -719,7 +696,6 @@ g_socket_class_init (GSocketClass *klass)
g_type_class_add_private (klass, sizeof (GSocketPrivate)); g_type_class_add_private (klass, sizeof (GSocketPrivate));
gobject_class->finalize = g_socket_finalize; gobject_class->finalize = g_socket_finalize;
gobject_class->dispose = g_socket_dispose;
gobject_class->constructed = g_socket_constructed; gobject_class->constructed = g_socket_constructed;
gobject_class->set_property = g_socket_set_property; gobject_class->set_property = g_socket_set_property;
gobject_class->get_property = g_socket_get_property; gobject_class->get_property = g_socket_get_property;
...@@ -811,8 +787,6 @@ g_socket_init (GSocket *socket) ...@@ -811,8 +787,6 @@ g_socket_init (GSocket *socket)
socket->priv->blocking = TRUE; socket->priv->blocking = TRUE;
socket->priv->listen_backlog = 10; socket->priv->listen_backlog = 10;
socket->priv->construct_error = NULL; socket->priv->construct_error = NULL;
socket->priv->remote_address = NULL;
socket->priv->local_address = NULL;
#ifdef G_OS_WIN32 #ifdef G_OS_WIN32
socket->priv->event = WSA_INVALID_EVENT; socket->priv->event = WSA_INVALID_EVENT;
#endif #endif
...@@ -1175,9 +1149,11 @@ g_socket_get_fd (GSocket *socket) ...@@ -1175,9 +1149,11 @@ g_socket_get_fd (GSocket *socket)
* @error: #GError for error reporting, or %NULL to ignore. * @error: #GError for error reporting, or %NULL to ignore.
* *
* Try to get the local address of a bound socket. This is only * Try to get the local address of a bound socket. This is only
* useful if the socket has been bound to a local address. * useful if the socket has been bound to a local address,
* either explicitly or implicitly when connecting.
* *
* Returns: a #GSocketAddress or %NULL on error. * Returns: a #GSocketAddress or %NULL on error.
* Free the returned object with g_object_unref().
* *
* Since: 2.22 * Since: 2.22
**/ **/
...@@ -1185,15 +1161,12 @@ GSocketAddress * ...@@ -1185,15 +1161,12 @@ GSocketAddress *
g_socket_get_local_address (GSocket *socket, g_socket_get_local_address (GSocket *socket,
GError **error) GError **error)
{ {
gchar buffer[256]; struct sockaddr_storage buffer;
guint32 len = 256; guint32 len = sizeof (buffer);
g_return_val_if_fail (G_IS_SOCKET (socket), NULL); g_return_val_if_fail (G_IS_SOCKET (socket), NULL);
if (socket->priv->local_address) if (getsockname (socket->priv->fd, (struct sockaddr *) &buffer, &len) < 0)
return socket->priv->local_address;
if (getsockname (socket->priv->fd, (struct sockaddr *) buffer, &len) < 0)
{ {
int errsv = get_socket_errno (); int errsv = get_socket_errno ();
g_set_error (error, G_IO_ERROR, socket_io_error_from_errno (errsv), g_set_error (error, G_IO_ERROR, socket_io_error_from_errno (errsv),
...@@ -1201,8 +1174,7 @@ g_socket_get_local_address (GSocket *socket, ...@@ -1201,8 +1174,7 @@ g_socket_get_local_address (GSocket *socket,
return NULL; return NULL;
} }
socket->priv->local_address = g_socket_address_new_from_native (buffer, len); return g_socket_address_new_from_native (&buffer, len);
return socket->priv->local_address;
} }
/** /**
...@@ -1214,6 +1186,7 @@ g_socket_get_local_address (GSocket *socket, ...@@ -1214,6 +1186,7 @@ g_socket_get_local_address (GSocket *socket,
* useful for connection oriented sockets that have been connected. * useful for connection oriented sockets that have been connected.
* *
* Returns: a #GSocketAddress or %NULL on error. * Returns: a #GSocketAddress or %NULL on error.
* Free the returned object with g_object_unref().
* *
* Since: 2.22 * Since: 2.22
**/ **/
...@@ -1221,15 +1194,12 @@ GSocketAddress * ...@@ -1221,15 +1194,12 @@ GSocketAddress *
g_socket_get_remote_address (GSocket *socket, g_socket_get_remote_address (GSocket *socket,
GError **error) GError **error)
{ {
gchar buffer[256]; struct sockaddr_storage buffer;
guint32 len = 256; guint32 len = sizeof (buffer);
g_return_val_if_fail (G_IS_SOCKET (socket), NULL); g_return_val_if_fail (G_IS_SOCKET (socket), NULL);
if (socket->priv->remote_address) if (getpeername (socket->priv->fd, (struct sockaddr *) &buffer, &len) < 0)
return socket->priv->remote_address;
if (getpeername (socket->priv->fd, (struct sockaddr *) buffer, &len) < 0)
{ {
int errsv = get_socket_errno (); int errsv = get_socket_errno ();
g_set_error (error, G_IO_ERROR, socket_io_error_from_errno (errsv), g_set_error (error, G_IO_ERROR, socket_io_error_from_errno (errsv),
...@@ -1237,8 +1207,7 @@ g_socket_get_remote_address (GSocket *socket, ...@@ -1237,8 +1207,7 @@ g_socket_get_remote_address (GSocket *socket,
return NULL; return NULL;
} }
socket->priv->remote_address = g_socket_address_new_from_native (buffer, len); return g_socket_address_new_from_native (&buffer, len);
return socket->priv->remote_address;
} }
/** /**
...@@ -1257,7 +1226,7 @@ g_socket_is_connected (GSocket *socket) ...@@ -1257,7 +1226,7 @@ g_socket_is_connected (GSocket *socket)
{ {
g_return_val_if_fail (G_IS_SOCKET (socket), FALSE); g_return_val_if_fail (G_IS_SOCKET (socket), FALSE);
return socket->priv->remote_address != NULL; return socket->priv->connected;
} }
/** /**
...@@ -1330,7 +1299,7 @@ g_socket_bind (GSocket *socket, ...@@ -1330,7 +1299,7 @@ g_socket_bind (GSocket *socket,
gboolean reuse_address, gboolean reuse_address,
GError **error) GError **error)
{ {
gchar addr[256]; struct sockaddr_storage addr;
int value; int value;
g_return_val_if_fail (G_IS_SOCKET (socket) && G_IS_SOCKET_ADDRESS (address), FALSE); g_return_val_if_fail (G_IS_SOCKET (socket) && G_IS_SOCKET_ADDRESS (address), FALSE);
...@@ -1348,10 +1317,10 @@ g_socket_bind (GSocket *socket, ...@@ -1348,10 +1317,10 @@ g_socket_bind (GSocket *socket,
(gpointer) &value, sizeof (value)); (gpointer) &value, sizeof (value));
#endif #endif
if (!g_socket_address_to_native (address, addr, sizeof addr, error)) if (!g_socket_address_to_native (address, &addr, sizeof addr, error))
return FALSE; return FALSE;
if (bind (socket->priv->fd, (struct sockaddr *) addr, if (bind (socket->priv->fd, (struct sockaddr *) &addr,
g_socket_address_get_native_size (address)) < 0) g_socket_address_get_native_size (address)) < 0)
{ {
int errsv = get_socket_errno (); int errsv = get_socket_errno ();
...@@ -1361,8 +1330,6 @@ g_socket_bind (GSocket *socket, ...@@ -1361,8 +1330,6 @@ g_socket_bind (GSocket *socket,
return FALSE; return FALSE;
} }
socket->priv->local_address = g_object_ref (address);
return TRUE; return TRUE;
} }
...@@ -1506,14 +1473,14 @@ g_socket_connect (GSocket *socket, ...@@ -1506,14 +1473,14 @@ g_socket_connect (GSocket *socket,
GSocketAddress *address, GSocketAddress *address,
GError **error) GError **error)
{ {
gchar buffer[256]; struct sockaddr_storage buffer;
g_return_val_if_fail (G_IS_SOCKET (socket) && G_IS_SOCKET_ADDRESS (address), FALSE); g_return_val_if_fail (G_IS_SOCKET (socket) && G_IS_SOCKET_ADDRESS (address), FALSE);
if (!check_socket (socket, error)) if (!check_socket (socket, error))
return FALSE; return FALSE;
if (!g_socket_address_to_native (address, buffer, sizeof buffer, error)) if (!g_socket_address_to_native (address, &buffer, sizeof buffer, error))
return FALSE; return FALSE;
while (1) while (1)
...@@ -1523,7 +1490,7 @@ g_socket_connect (GSocket *socket, ...@@ -1523,7 +1490,7 @@ g_socket_connect (GSocket *socket,
G_IO_IN, NULL, error)) G_IO_IN, NULL, error))
return FALSE; return FALSE;
if (connect (socket->priv->fd, (struct sockaddr *) buffer, if (connect (socket->priv->fd, (struct sockaddr *) &buffer,
g_socket_address_get_native_size (address)) < 0) g_socket_address_get_native_size (address)) < 0)
{ {
int errsv = get_socket_errno (); int errsv = get_socket_errno ();
...@@ -1561,7 +1528,7 @@ g_socket_connect (GSocket *socket, ...@@ -1561,7 +1528,7 @@ g_socket_connect (GSocket *socket,
win32_unset_event_mask (socket, FD_CONNECT); win32_unset_event_mask (socket, FD_CONNECT);
socket->priv->remote_address = g_object_ref (address); socket->priv->connected = TRUE;
return TRUE; return TRUE;
} }
...@@ -1928,6 +1895,7 @@ g_socket_close (GSocket *socket, ...@@ -1928,6 +1895,7 @@ g_socket_close (GSocket *socket,
} }
#endif #endif
socket->priv->connected = FALSE;
socket->priv->closed = TRUE; socket->priv->closed = TRUE;
return TRUE; return TRUE;
......
...@@ -141,6 +141,7 @@ g_socket_connection_get_socket (GSocketConnection *connection) ...@@ -141,6 +141,7 @@ g_socket_connection_get_socket (GSocketConnection *connection)
* Try to get the local address of a socket connection. * Try to get the local address of a socket connection.
* *
* Returns: a #GSocketAddress or %NULL on error. * Returns: a #GSocketAddress or %NULL on error.
* Free the returned object with g_object_unref().
* *
* Since: 2.22 * Since: 2.22
**/ **/
...@@ -159,6 +160,7 @@ g_socket_connection_get_local_address (GSocketConnection *connection, ...@@ -159,6 +160,7 @@ g_socket_connection_get_local_address (GSocketConnection *connection,
* Try to get the remove address of a socket connection. * Try to get the remove address of a socket connection.
* *
* Returns: a #GSocketAddress or %NULL on error. * Returns: a #GSocketAddress or %NULL on error.
* Free the returned object with g_object_unref().
* *
* Since: 2.22 * Since: 2.22
**/ **/
......
...@@ -191,6 +191,7 @@ main (int argc, ...@@ -191,6 +191,7 @@ main (int argc,
g_print ("got a new connection from %s\n", g_print ("got a new connection from %s\n",
socket_address_to_string (address)); socket_address_to_string (address));
g_object_unref (address);
recv_socket = new_socket; recv_socket = new_socket;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment