branch-merge: clean up socket name

The plymouth client talks to the plymouth daemon via
an abstract socket.  There aren't a lot of "rules" for
the name of the abstract socket, and so plymouth has just
used "/ply-boot-protocol" for the name.  While this is
perfectly valid, a number programs (hal, udev, etc) use
the convention "/org/freedesktop/program".

"/org/freedesktop/plymouthd" is certainly much nicer than
"/ply-boot-protocol" so we're going to change to that, and
fall back to the old name for compatibility.

One other niggle is trailing zeros in the name.  The socket
address is stored in a fixed size buffer.  Traditionally,
programms would pass the size of the entire socket structure,
including the full size of the aaddress buffer to bind and
connect.  This means that any NUL bytes in the address buffer
after the address become part of the address.  This means users
looking at /proc/net/unix will see all the extra NUL bytes.

One trick that some programs employee to skirt around this problem,
is to pass only the size of the structure less the trailing
NUL bytes of the address buffer to bind and connected.  While maybe
not 100% kosher, this works okay in practice.

plymouth will now use that trick as well.
This commit is contained in:
Ray Strode 2010-10-06 18:07:08 -04:00
commit ace1c6675c
5 changed files with 56 additions and 23 deletions

View file

@ -179,11 +179,21 @@ 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_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;

View file

@ -29,6 +29,7 @@
#include <fcntl.h>
#include <limits.h>
#include <poll.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -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)
{

View file

@ -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,

View file

@ -22,7 +22,8 @@
#ifndef PLY_BOOT_PROTOCOL_H
#define PLY_BOOT_PROTOCOL_H
#define PLY_BOOT_PROTOCOL_SOCKET_PATH "\0/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"

View file

@ -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_TRIMMED_ABSTRACT_SOCKET_PATH,
PLY_UNIX_SOCKET_TYPE_TRIMMED_ABSTRACT);
if (server->socket_fd < 0)
return false;