From 9de731ed29db4670c1641aedd945c56fd1a3feed Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Wed, 6 Oct 2010 17:43:50 -0400 Subject: [PATCH 1/3] utils: add support for "trimmed abstract" sockets Right now plymouth listens on an abstract socket with a name that has a bunch of trailing NUL bytes. These zeroes uglify the output of /proc/net/unix among other things. This commit adds support for a new "trimmed abstract" socket type, which drops the zeroes. A subsequent commit will actually change plymouthd to use the new api. --- src/client/ply-boot-client.c | 5 ++-- src/libply/ply-utils.c | 44 ++++++++++++++++++++++++------------ src/libply/ply-utils.h | 13 ++++++++--- src/ply-boot-server.c | 3 ++- 4 files changed, 44 insertions(+), 21 deletions(-) diff --git a/src/client/ply-boot-client.c b/src/client/ply-boot-client.c index 48f32583..5fe30132 100644 --- a/src/client/ply-boot-client.c +++ b/src/client/ply-boot-client.c @@ -179,8 +179,9 @@ ply_boot_client_connect (ply_boot_client_t *client, assert (client->disconnect_handler == NULL); assert (client->disconnect_handler_user_data == NULL); - client->socket_fd = - ply_connect_to_unix_socket (PLY_BOOT_PROTOCOL_SOCKET_PATH + 1, true); + client->socket_fd = + ply_connect_to_unix_socket (PLY_BOOT_PROTOCOL_SOCKET_PATH + 1, + PLY_UNIX_SOCKET_TYPE_ABSTRACT); if (client->socket_fd < 0) return false; diff --git a/src/libply/ply-utils.c b/src/libply/ply-utils.c index a65c469a..633ff1c8 100644 --- a/src/libply/ply-utils.c +++ b/src/libply/ply-utils.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -146,9 +147,9 @@ ply_open_unix_socket (void) } static struct sockaddr * -create_unix_address_from_path (const char *path, - bool is_abstract, - size_t *address_size) +create_unix_address_from_path (const char *path, + ply_unix_socket_type_t type, + size_t *address_size) { struct sockaddr_un *address; @@ -159,26 +160,39 @@ create_unix_address_from_path (const char *path, address->sun_family = AF_UNIX; /* a socket is marked as abstract if its path has the - * NUL byte at the beginning of the buffer instead of - * the end + * NUL byte at the beginning of the buffer. * * Note, we depend on the memory being zeroed by the calloc * call above. */ - if (!is_abstract) + if (type == PLY_UNIX_SOCKET_TYPE_ABSTRACT) strncpy (address->sun_path, path, sizeof (address->sun_path) - 1); else strncpy (address->sun_path + 1, path, sizeof (address->sun_path) - 1); - if (address_size != NULL) - *address_size = sizeof (struct sockaddr_un); + assert (address_size != NULL); + + /* it's very popular to trim the trailing zeros off the end of the path these + * days for abstract sockets. Unfortunately, the 0s are part of the name, so + * both client and server have to agree. + */ + if (type == PLY_UNIX_SOCKET_TYPE_TRIMMED_ABSTRACT) + { + *address_size = offsetof (struct sockaddr_un, sun_path) + + 1 /* NUL */ + + strlen (address->sun_path + 1) /* path */; + } + else + { + *address_size = sizeof (struct sockaddr_un); + } return (struct sockaddr *) address; } int -ply_connect_to_unix_socket (const char *path, - bool is_abstract) +ply_connect_to_unix_socket (const char *path, + ply_unix_socket_type_t type) { struct sockaddr *address; size_t address_size; @@ -192,7 +206,7 @@ ply_connect_to_unix_socket (const char *path, if (fd < 0) return -1; - address = create_unix_address_from_path (path, is_abstract, &address_size); + address = create_unix_address_from_path (path, type, &address_size); if (connect (fd, address, address_size) < 0) { @@ -209,8 +223,8 @@ ply_connect_to_unix_socket (const char *path, } int -ply_listen_to_unix_socket (const char *path, - bool is_abstract) +ply_listen_to_unix_socket (const char *path, + ply_unix_socket_type_t type) { struct sockaddr *address; size_t address_size; @@ -224,7 +238,7 @@ ply_listen_to_unix_socket (const char *path, if (fd < 0) return -1; - address = create_unix_address_from_path (path, is_abstract, &address_size); + address = create_unix_address_from_path (path, type, &address_size); if (bind (fd, address, address_size) < 0) { @@ -246,7 +260,7 @@ ply_listen_to_unix_socket (const char *path, return -1; } - if (!is_abstract) + if (type == PLY_UNIX_SOCKET_TYPE_CONCRETE) { if (fchmod (fd, 0600) < 0) { diff --git a/src/libply/ply-utils.h b/src/libply/ply-utils.h index 8af8172d..25500107 100644 --- a/src/libply/ply-utils.h +++ b/src/libply/ply-utils.h @@ -45,16 +45,23 @@ typedef void (* ply_module_function_t) (void); typedef intptr_t ply_daemon_handle_t; +typedef enum +{ + PLY_UNIX_SOCKET_TYPE_CONCRETE = 0, + PLY_UNIX_SOCKET_TYPE_ABSTRACT, + PLY_UNIX_SOCKET_TYPE_TRIMMED_ABSTRACT +} ply_unix_socket_type_t; + #ifndef PLY_HIDE_FUNCTION_DECLARATIONS #define ply_round_to_multiple(n, m) (((n) + (((m) - 1))) & ~((m) - 1)) bool ply_open_unidirectional_pipe (int *sender_fd, int *receiver_fd); -int ply_connect_to_unix_socket (const char *path, - bool is_abstract); +int ply_connect_to_unix_socket (const char *path, + ply_unix_socket_type_t type); int ply_listen_to_unix_socket (const char *path, - bool is_abstract); + ply_unix_socket_type_t type); bool ply_get_credentials_from_fd (int fd, pid_t *pid, uid_t *uid, diff --git a/src/ply-boot-server.c b/src/ply-boot-server.c index 297074ec..337d22a4 100644 --- a/src/ply-boot-server.c +++ b/src/ply-boot-server.c @@ -179,7 +179,8 @@ ply_boot_server_listen (ply_boot_server_t *server) assert (server != NULL); server->socket_fd = - ply_listen_to_unix_socket (PLY_BOOT_PROTOCOL_SOCKET_PATH + 1, true); + ply_listen_to_unix_socket (PLY_BOOT_PROTOCOL_SOCKET_PATH + 1, + PLY_UNIX_SOCKET_TYPE_ABSTRACT); if (server->socket_fd < 0) return false; From f0da04ca88975f0c0a06d6a0f6568b255c5e1cb3 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Wed, 6 Oct 2010 17:57:34 -0400 Subject: [PATCH 2/3] protocol: drop leading \0 from socket path The socket path is currently defined to be: #define PLY_BOOT_PROTOCOL_SOCKET_PATH "\0/ply-boot-protocol" The \0 is because it's an abstract socket, and abstract sockets have a leading NUL. The code always ignores the NUL though and adds it back later, so it's not needed. This commit just drops it. --- src/client/ply-boot-client.c | 2 +- src/ply-boot-protocol.h | 2 +- src/ply-boot-server.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/client/ply-boot-client.c b/src/client/ply-boot-client.c index 5fe30132..5871a988 100644 --- a/src/client/ply-boot-client.c +++ b/src/client/ply-boot-client.c @@ -180,7 +180,7 @@ ply_boot_client_connect (ply_boot_client_t *client, assert (client->disconnect_handler_user_data == NULL); client->socket_fd = - ply_connect_to_unix_socket (PLY_BOOT_PROTOCOL_SOCKET_PATH + 1, + ply_connect_to_unix_socket (PLY_BOOT_PROTOCOL_SOCKET_PATH, PLY_UNIX_SOCKET_TYPE_ABSTRACT); if (client->socket_fd < 0) diff --git a/src/ply-boot-protocol.h b/src/ply-boot-protocol.h index 97d5a421..8b6d4fc7 100644 --- a/src/ply-boot-protocol.h +++ b/src/ply-boot-protocol.h @@ -22,7 +22,7 @@ #ifndef PLY_BOOT_PROTOCOL_H #define PLY_BOOT_PROTOCOL_H -#define PLY_BOOT_PROTOCOL_SOCKET_PATH "\0/ply-boot-protocol" +#define PLY_BOOT_PROTOCOL_SOCKET_PATH "/ply-boot-protocol" #define PLY_BOOT_PROTOCOL_REQUEST_TYPE_PING "P" #define PLY_BOOT_PROTOCOL_REQUEST_TYPE_UPDATE "U" #define PLY_BOOT_PROTOCOL_REQUEST_TYPE_SYSTEM_INITIALIZED "S" diff --git a/src/ply-boot-server.c b/src/ply-boot-server.c index 337d22a4..30d4b646 100644 --- a/src/ply-boot-server.c +++ b/src/ply-boot-server.c @@ -179,7 +179,7 @@ ply_boot_server_listen (ply_boot_server_t *server) assert (server != NULL); server->socket_fd = - ply_listen_to_unix_socket (PLY_BOOT_PROTOCOL_SOCKET_PATH + 1, + ply_listen_to_unix_socket (PLY_BOOT_PROTOCOL_SOCKET_PATH, PLY_UNIX_SOCKET_TYPE_ABSTRACT); if (server->socket_fd < 0) From 3ec007a4820e53aed6713620173bd997957754ec Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Wed, 6 Oct 2010 18:03:25 -0400 Subject: [PATCH 3/3] protocol: change socket path Before we were using /ply-boot-protocol\0\0\0\0...\0 for our address which really uglifies /proc/net/unix and doesn't match what a lot of other programs do. This commit changes the address to just /org/freedesktop/plymouthd which is much nicer. --- src/client/ply-boot-client.c | 15 ++++++++++++--- src/ply-boot-protocol.h | 3 ++- src/ply-boot-server.c | 4 ++-- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/client/ply-boot-client.c b/src/client/ply-boot-client.c index 5871a988..74979c9a 100644 --- a/src/client/ply-boot-client.c +++ b/src/client/ply-boot-client.c @@ -180,11 +180,20 @@ ply_boot_client_connect (ply_boot_client_t *client, assert (client->disconnect_handler_user_data == NULL); client->socket_fd = - ply_connect_to_unix_socket (PLY_BOOT_PROTOCOL_SOCKET_PATH, - PLY_UNIX_SOCKET_TYPE_ABSTRACT); + ply_connect_to_unix_socket (PLY_BOOT_PROTOCOL_TRIMMED_ABSTRACT_SOCKET_PATH, + PLY_UNIX_SOCKET_TYPE_TRIMMED_ABSTRACT); if (client->socket_fd < 0) - return false; + { + ply_trace ("could not connect to " PLY_BOOT_PROTOCOL_TRIMMED_ABSTRACT_SOCKET_PATH ": %m"); + ply_trace ("trying old fallback path " PLY_BOOT_PROTOCOL_OLD_ABSTRACT_SOCKET_PATH); + + client->socket_fd = + ply_connect_to_unix_socket (PLY_BOOT_PROTOCOL_OLD_ABSTRACT_SOCKET_PATH, + PLY_UNIX_SOCKET_TYPE_ABSTRACT); + ply_trace ("could not connect to " PLY_BOOT_PROTOCOL_OLD_ABSTRACT_SOCKET_PATH ": %m"); + return false; + } client->disconnect_handler = disconnect_handler; client->disconnect_handler_user_data = user_data; diff --git a/src/ply-boot-protocol.h b/src/ply-boot-protocol.h index 8b6d4fc7..11aa1fb8 100644 --- a/src/ply-boot-protocol.h +++ b/src/ply-boot-protocol.h @@ -22,7 +22,8 @@ #ifndef PLY_BOOT_PROTOCOL_H #define PLY_BOOT_PROTOCOL_H -#define PLY_BOOT_PROTOCOL_SOCKET_PATH "/ply-boot-protocol" +#define PLY_BOOT_PROTOCOL_TRIMMED_ABSTRACT_SOCKET_PATH "/org/freedesktop/plymouthd" +#define PLY_BOOT_PROTOCOL_OLD_ABSTRACT_SOCKET_PATH "/ply-boot-protocol" #define PLY_BOOT_PROTOCOL_REQUEST_TYPE_PING "P" #define PLY_BOOT_PROTOCOL_REQUEST_TYPE_UPDATE "U" #define PLY_BOOT_PROTOCOL_REQUEST_TYPE_SYSTEM_INITIALIZED "S" diff --git a/src/ply-boot-server.c b/src/ply-boot-server.c index 30d4b646..b49f9b9f 100644 --- a/src/ply-boot-server.c +++ b/src/ply-boot-server.c @@ -179,8 +179,8 @@ ply_boot_server_listen (ply_boot_server_t *server) assert (server != NULL); server->socket_fd = - ply_listen_to_unix_socket (PLY_BOOT_PROTOCOL_SOCKET_PATH, - PLY_UNIX_SOCKET_TYPE_ABSTRACT); + ply_listen_to_unix_socket (PLY_BOOT_PROTOCOL_TRIMMED_ABSTRACT_SOCKET_PATH, + PLY_UNIX_SOCKET_TYPE_TRIMMED_ABSTRACT); if (server->socket_fd < 0) return false;