mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-07-17 23:47:52 +02:00
GUnixSocketAddress: handle abstract sockets with non-0-padded names
There are apparently two incompatible ways of naming abstract sockets: pad the sockaddr with 0s and use the entire thing as the name, or else don't, and just pass a shorter length value to the relevant functions. We previously only supported the former method. Add support for the latter. Also correctly handle "anonymous" unix sockaddrs (eg, the client side of a connection, or a socketpair() socket), and add unix domain socket support to the socket-client and socket-server test programs to make sure this all works. https://bugzilla.gnome.org/show_bug.cgi?id=615960
This commit is contained in:
@@ -1,6 +1,10 @@
|
||||
#include <gio/gio.h>
|
||||
#include <gio/gunixsocketaddress.h>
|
||||
#include <glib.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "socket-common.c"
|
||||
|
||||
GMainLoop *loop;
|
||||
|
||||
@@ -11,6 +15,7 @@ gboolean non_blocking = FALSE;
|
||||
gboolean use_udp = FALSE;
|
||||
gboolean use_source = FALSE;
|
||||
int cancel_timeout = 0;
|
||||
gboolean unix_socket = FALSE;
|
||||
|
||||
static GOptionEntry cmd_entries[] = {
|
||||
{"port", 'p', 0, G_OPTION_ARG_INT, &port,
|
||||
@@ -27,24 +32,11 @@ static GOptionEntry cmd_entries[] = {
|
||||
"Enable non-blocking i/o", NULL},
|
||||
{"use-source", 's', 0, G_OPTION_ARG_NONE, &use_source,
|
||||
"Use GSource to wait for non-blocking i/o", NULL},
|
||||
{"unix", 'U', 0, G_OPTION_ARG_NONE, &unix_socket,
|
||||
"Use a unix socket instead of IP", NULL},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
static char *
|
||||
socket_address_to_string (GSocketAddress *address)
|
||||
{
|
||||
GInetAddress *inet_address;
|
||||
char *str, *res;
|
||||
int the_port;
|
||||
|
||||
inet_address = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (address));
|
||||
str = g_inet_address_to_string (inet_address);
|
||||
the_port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (address));
|
||||
res = g_strdup_printf ("%s:%d", str, the_port);
|
||||
g_free (str);
|
||||
return res;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
source_ready (gpointer data,
|
||||
GIOCondition condition)
|
||||
@@ -108,9 +100,11 @@ main (int argc,
|
||||
GSocketAddress *src_address;
|
||||
GSocketAddress *address;
|
||||
GSocketType socket_type;
|
||||
GSocketFamily socket_family;
|
||||
GError *error = NULL;
|
||||
GOptionContext *context;
|
||||
GCancellable *cancellable;
|
||||
char *display_addr;
|
||||
|
||||
g_thread_init (NULL);
|
||||
|
||||
@@ -124,6 +118,12 @@ main (int argc,
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (unix_socket && argc != 2)
|
||||
{
|
||||
g_printerr ("%s: %s\n", argv[0], "Need to specify unix socket name");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (cancel_timeout)
|
||||
{
|
||||
cancellable = g_cancellable_new ();
|
||||
@@ -141,7 +141,12 @@ main (int argc,
|
||||
else
|
||||
socket_type = G_SOCKET_TYPE_STREAM;
|
||||
|
||||
socket = g_socket_new (G_SOCKET_FAMILY_IPV4, socket_type, 0, &error);
|
||||
if (unix_socket)
|
||||
socket_family = G_SOCKET_FAMILY_UNIX;
|
||||
else
|
||||
socket_family = G_SOCKET_FAMILY_IPV4;
|
||||
|
||||
socket = g_socket_new (socket_family, socket_type, 0, &error);
|
||||
|
||||
if (socket == NULL)
|
||||
{
|
||||
@@ -152,7 +157,20 @@ main (int argc,
|
||||
if (non_blocking)
|
||||
g_socket_set_blocking (socket, FALSE);
|
||||
|
||||
src_address = g_inet_socket_address_new (g_inet_address_new_any (G_SOCKET_FAMILY_IPV4), port);
|
||||
if (unix_socket)
|
||||
{
|
||||
src_address = socket_address_from_string (argv[1]);
|
||||
if (src_address == NULL)
|
||||
{
|
||||
g_printerr ("%s: Could not parse '%s' as unix socket name\n", argv[0], argv[1]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
src_address = g_inet_socket_address_new (g_inet_address_new_any (G_SOCKET_FAMILY_IPV4), port);
|
||||
}
|
||||
|
||||
if (!g_socket_bind (socket, src_address, !dont_reuse_address, &error))
|
||||
{
|
||||
g_printerr ("Can't bind socket: %s\n", error->message);
|
||||
@@ -168,7 +186,16 @@ main (int argc,
|
||||
return 1;
|
||||
}
|
||||
|
||||
g_print ("listening on port %d...\n", port);
|
||||
address = g_socket_get_local_address (socket, &error);
|
||||
if (!address)
|
||||
{
|
||||
g_printerr ("Error getting local address: %s\n",
|
||||
error->message);
|
||||
return 1;
|
||||
}
|
||||
display_addr = socket_address_to_string (address);
|
||||
g_print ("listening on %s...\n", display_addr);
|
||||
g_free (display_addr);
|
||||
|
||||
ensure_condition (socket, "accept", cancellable, G_IO_IN);
|
||||
new_socket = g_socket_accept (socket, cancellable, &error);
|
||||
@@ -190,8 +217,9 @@ main (int argc,
|
||||
return 1;
|
||||
}
|
||||
|
||||
g_print ("got a new connection from %s\n",
|
||||
socket_address_to_string (address));
|
||||
display_addr = socket_address_to_string (address);
|
||||
g_print ("got a new connection from %s\n", display_addr);
|
||||
g_free(display_addr);
|
||||
g_object_unref (address);
|
||||
|
||||
recv_socket = new_socket;
|
||||
|
Reference in New Issue
Block a user