Merge pull request #23339 from poettering/sockaddr-size-limit
tree-wide: add support for connecting to AF_UNIX sockets in the file system beyond the 108ch limit
This commit is contained in:
+9
-11
@@ -1,4 +1,6 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <poll.h>
|
||||
|
||||
#include "fd-util.h"
|
||||
@@ -18,17 +20,12 @@ struct nscdInvalidateRequest {
|
||||
char dbname[];
|
||||
};
|
||||
|
||||
static const union sockaddr_union nscd_sa = {
|
||||
.un.sun_family = AF_UNIX,
|
||||
.un.sun_path = "/run/nscd/socket",
|
||||
};
|
||||
|
||||
static int nscd_flush_cache_one(const char *database, usec_t end) {
|
||||
size_t req_size, has_written = 0, has_read = 0, l;
|
||||
struct nscdInvalidateRequest *req;
|
||||
_cleanup_close_ int fd = -1;
|
||||
int32_t resp;
|
||||
int events;
|
||||
int events, r;
|
||||
|
||||
assert(database);
|
||||
|
||||
@@ -60,11 +57,12 @@ static int nscd_flush_cache_one(const char *database, usec_t end) {
|
||||
* nice way to connect() to a server synchronously with a time limit that would also cover dealing with the
|
||||
* backlog limit. After all SO_RCVTIMEO and SR_SNDTIMEO don't apply to connect(), and alarm() is frickin' ugly
|
||||
* and not really reasonably usable from threads-aware code.) */
|
||||
if (connect(fd, &nscd_sa.sa, SOCKADDR_UN_LEN(nscd_sa.un)) < 0) {
|
||||
if (errno == EAGAIN)
|
||||
return log_debug_errno(errno, "nscd is overloaded (backlog limit reached) and refuses to take further connections: %m");
|
||||
if (errno != EINPROGRESS)
|
||||
return log_debug_errno(errno, "Failed to connect to nscd socket: %m");
|
||||
r = connect_unix_path(fd, AT_FDCWD, "/run/nscd/socket");
|
||||
if (r < 0) {
|
||||
if (r == -EAGAIN)
|
||||
return log_debug_errno(r, "nscd is overloaded (backlog limit reached) and refuses to take further connections: %m");
|
||||
if (r != -EINPROGRESS)
|
||||
return log_debug_errno(r, "Failed to connect to nscd socket: %m");
|
||||
|
||||
/* Continue in case of EINPROGRESS, but don't bother with send() or recv() until being notified that
|
||||
* establishing the connection is complete. */
|
||||
|
||||
+15
-9
@@ -271,17 +271,11 @@ static int varlink_new(Varlink **ret) {
|
||||
int varlink_connect_address(Varlink **ret, const char *address) {
|
||||
_cleanup_(varlink_unrefp) Varlink *v = NULL;
|
||||
union sockaddr_union sockaddr;
|
||||
socklen_t sockaddr_len;
|
||||
int r;
|
||||
|
||||
assert_return(ret, -EINVAL);
|
||||
assert_return(address, -EINVAL);
|
||||
|
||||
r = sockaddr_un_set_path(&sockaddr.un, address);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to set socket address '%s': %m", address);
|
||||
sockaddr_len = r;
|
||||
|
||||
r = varlink_new(&v);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to create varlink object: %m");
|
||||
@@ -292,9 +286,21 @@ int varlink_connect_address(Varlink **ret, const char *address) {
|
||||
|
||||
v->fd = fd_move_above_stdio(v->fd);
|
||||
|
||||
if (connect(v->fd, &sockaddr.sa, sockaddr_len) < 0) {
|
||||
if (!IN_SET(errno, EAGAIN, EINPROGRESS))
|
||||
return log_debug_errno(errno, "Failed to connect to %s: %m", address);
|
||||
r = sockaddr_un_set_path(&sockaddr.un, address);
|
||||
if (r < 0) {
|
||||
if (r != -ENAMETOOLONG)
|
||||
return log_debug_errno(r, "Failed to set socket address '%s': %m", address);
|
||||
|
||||
/* This is a file system path, and too long to fit into sockaddr_un. Let's connect via O_PATH
|
||||
* to this socket. */
|
||||
|
||||
r = connect_unix_path(v->fd, AT_FDCWD, address);
|
||||
} else
|
||||
r = RET_NERRNO(connect(v->fd, &sockaddr.sa, r));
|
||||
|
||||
if (r < 0) {
|
||||
if (!IN_SET(r, -EAGAIN, -EINPROGRESS))
|
||||
return log_debug_errno(r, "Failed to connect to %s: %m", address);
|
||||
|
||||
v->connecting = true; /* We are asynchronously connecting, i.e. the connect() is being
|
||||
* processed in the background. As long as that's the case the socket
|
||||
|
||||
Reference in New Issue
Block a user