summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStelios Fragkakis <52996999+stelfrag@users.noreply.github.com>2024-03-15 15:28:13 +0200
committerGitHub <noreply@github.com>2024-03-15 15:28:13 +0200
commitdb63ab82265f0606e33600a350e4ee6cc2dda687 (patch)
tree1c4395e38d544fadf4bee2ce48b04484f63a9159
parent460577b70ab85e2c5e2f32220789096e7c78de07 (diff)
Fix macOS issue with SOCK_CLOEXEC (#17151)
* Fix macos issue with SOCK_CLOEXEC * Code cleanup * Fix SOCK_NONBLOCK not available * Fix compilation error * Code simplify * Properly check return code
-rw-r--r--src/aclk/mqtt_websockets/mqtt_wss_client.c8
-rw-r--r--src/libnetdata/log/journal.c4
-rw-r--r--src/libnetdata/socket/socket.c51
-rw-r--r--src/libnetdata/socket/socket.h16
-rw-r--r--src/streaming/sender.c1
5 files changed, 55 insertions, 25 deletions
diff --git a/src/aclk/mqtt_websockets/mqtt_wss_client.c b/src/aclk/mqtt_websockets/mqtt_wss_client.c
index c37a47356c..a2aef80ceb 100644
--- a/src/aclk/mqtt_websockets/mqtt_wss_client.c
+++ b/src/aclk/mqtt_websockets/mqtt_wss_client.c
@@ -583,12 +583,18 @@ int mqtt_wss_connect(mqtt_wss_client client, char *host, int port, struct mqtt_c
if (client->sockfd > 0)
close(client->sockfd);
- client->sockfd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
+ client->sockfd = socket(AF_INET, SOCK_STREAM | DEFAULT_SOCKET_FLAGS, 0);
if (client->sockfd < 0) {
mws_error(client->log, "Couldn't create socket()");
return -1;
}
+#ifndef SOCK_CLOEXEC
+ int flags = fcntl(client->sockfd, F_GETFD);
+ if (flags != -1)
+ (void) fcntl(client->sockfd, F_SETFD, flags| FD_CLOEXEC);
+#endif
+
int flag = 1;
int result = setsockopt(client->sockfd,
IPPROTO_TCP,
diff --git a/src/libnetdata/log/journal.c b/src/libnetdata/log/journal.c
index 52e3960acc..0f1248de7f 100644
--- a/src/libnetdata/log/journal.c
+++ b/src/libnetdata/log/journal.c
@@ -48,9 +48,11 @@ int journal_direct_fd(const char *path) {
if(!is_path_unix_socket(path))
return -1;
- int fd = socket(AF_UNIX, SOCK_DGRAM| SOCK_CLOEXEC, 0);
+ int fd = socket(AF_UNIX, SOCK_DGRAM| DEFAULT_SOCKET_FLAGS, 0);
if (fd < 0) return -1;
+ sock_setcloexec(fd);
+
struct sockaddr_un addr;
memset(&addr, 0, sizeof(struct sockaddr_un));
addr.sun_family = AF_UNIX;
diff --git a/src/libnetdata/socket/socket.c b/src/libnetdata/socket/socket.c
index 17e9f6fb49..b157b157bd 100644
--- a/src/libnetdata/socket/socket.c
+++ b/src/libnetdata/socket/socket.c
@@ -191,6 +191,16 @@ int sock_setreuse(int fd, int reuse) {
return ret;
}
+void sock_setcloexec(int fd)
+{
+ UNUSED(fd);
+#ifndef SOCK_CLOEXEC
+ int flags = fcntl(fd, F_GETFD);
+ if (flags != -1)
+ (void) fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
+#endif
+}
+
int sock_setreuse_port(int fd, int reuse) {
int ret;
@@ -262,7 +272,7 @@ char *strdup_client_description(int family, const char *protocol, const char *ip
int create_listen_socket_unix(const char *path, int listen_backlog) {
int sock;
- sock = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
+ sock = socket(AF_UNIX, SOCK_STREAM | DEFAULT_SOCKET_FLAGS, 0);
if(sock < 0) {
nd_log(NDLS_DAEMON, NDLP_ERR,
"LISTENER: UNIX socket() on path '%s' failed.",
@@ -272,6 +282,7 @@ int create_listen_socket_unix(const char *path, int listen_backlog) {
}
sock_setnonblock(sock);
+ sock_setcloexec(sock);
sock_enlarge_in(sock);
struct sockaddr_un name;
@@ -316,7 +327,7 @@ int create_listen_socket_unix(const char *path, int listen_backlog) {
int create_listen_socket4(int socktype, const char *ip, uint16_t port, int listen_backlog) {
int sock;
- sock = socket(AF_INET, socktype | SOCK_CLOEXEC, 0);
+ sock = socket(AF_INET, socktype | DEFAULT_SOCKET_FLAGS, 0);
if(sock < 0) {
nd_log(NDLS_DAEMON, NDLP_ERR,
"LISTENER: IPv4 socket() on ip '%s' port %d, socktype %d failed.",
@@ -324,10 +335,10 @@ int create_listen_socket4(int socktype, const char *ip, uint16_t port, int liste
return -1;
}
-
sock_setreuse(sock, 1);
sock_setreuse_port(sock, 0);
sock_setnonblock(sock);
+ sock_setcloexec(sock);
sock_enlarge_in(sock);
struct sockaddr_in name;
@@ -374,7 +385,7 @@ int create_listen_socket6(int socktype, uint32_t scope_id, const char *ip, int p
int sock;
int ipv6only = 1;
- sock = socket(AF_INET6, socktype | SOCK_CLOEXEC, 0);
+ sock = socket(AF_INET6, socktype | DEFAULT_SOCKET_FLAGS, 0);
if (sock < 0) {
nd_log(NDLS_DAEMON, NDLP_ERR,
"LISTENER: IPv6 socket() on ip '%s' port %d, socktype %d, failed.",
@@ -382,10 +393,10 @@ int create_listen_socket6(int socktype, uint32_t scope_id, const char *ip, int p
return -1;
}
-
sock_setreuse(sock, 1);
sock_setreuse_port(sock, 0);
sock_setnonblock(sock);
+ sock_setcloexec(sock);
sock_enlarge_in(sock);
/* IPv6 only */
@@ -781,7 +792,7 @@ int listen_sockets_setup(LISTEN_SOCKETS *sockets) {
// timeout the timeout for establishing a connection
static inline int connect_to_unix(const char *path, struct timeval *timeout) {
- int fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
+ int fd = socket(AF_UNIX, SOCK_STREAM | DEFAULT_SOCKET_FLAGS, 0);
if(fd == -1) {
nd_log(NDLS_DAEMON, NDLP_ERR,
"Failed to create UNIX socket() for '%s'",
@@ -797,6 +808,8 @@ static inline int connect_to_unix(const char *path, struct timeval *timeout) {
path);
}
+ sock_setcloexec(fd);
+
struct sockaddr_un addr;
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
@@ -894,7 +907,7 @@ int connect_to_this_ip46(int protocol, int socktype, const char *host, uint32_t
}
}
- fd = socket(ai->ai_family, ai->ai_socktype | SOCK_CLOEXEC, ai->ai_protocol);
+ fd = socket(ai->ai_family, ai->ai_socktype | DEFAULT_SOCKET_FLAGS, ai->ai_protocol);
if(fd != -1) {
if(timeout) {
if(setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char *) timeout, sizeof(struct timeval)) < 0)
@@ -902,6 +915,7 @@ int connect_to_this_ip46(int protocol, int socktype, const char *host, uint32_t
"Failed to set timeout on the socket to ip '%s' port '%s'",
hostBfr, servBfr);
}
+ sock_setcloexec(fd);
errno = 0;
if(connect(fd, ai->ai_addr, ai->ai_addrlen) < 0) {
@@ -1266,11 +1280,6 @@ int accept4(int sock, struct sockaddr *addr, socklen_t *addrlen, int flags) {
if (fd < 0) return fd;
- if (flags & SOCK_NONBLOCK) {
- newflags |= O_NONBLOCK;
- flags &= ~SOCK_NONBLOCK;
- }
-
#ifdef SOCK_CLOEXEC
#ifdef O_CLOEXEC
if (flags & SOCK_CLOEXEC) {
@@ -1387,7 +1396,7 @@ int accept_socket(int fd, int flags, char *client_ip, size_t ipsize, char *clien
struct sockaddr_storage sadr;
socklen_t addrlen = sizeof(sadr);
- int nfd = accept4(fd, (struct sockaddr *)&sadr, &addrlen, flags | SOCK_CLOEXEC);
+ int nfd = accept4(fd, (struct sockaddr *)&sadr, &addrlen, flags | DEFAULT_SOCKET_FLAGS);
if (likely(nfd >= 0)) {
if (getnameinfo((struct sockaddr *)&sadr, addrlen, client_ip, (socklen_t)ipsize,
client_port, (socklen_t)portsize, NI_NUMERICHOST | NI_NUMERICSERV) != 0) {
@@ -1401,6 +1410,7 @@ int accept_socket(int fd, int flags, char *client_ip, size_t ipsize, char *clien
if (!strcmp(client_ip, "127.0.0.1") || !strcmp(client_ip, "::1")) {
strncpyz(client_ip, "localhost", ipsize);
}
+ sock_setcloexec(nfd);
#ifdef __FreeBSD__
if(((struct sockaddr *)&sadr)->sa_family == AF_LOCAL)
@@ -1785,12 +1795,25 @@ static int poll_process_new_tcp_connection(POLLJOB *p, POLLINFO *pi, struct poll
char client_port[NI_MAXSERV] = "";
char client_host[NI_MAXHOST] = "";
+#ifdef SOCK_NONBLOCK
+ int flags = SOCK_NONBLOCK;
+#else
+ int flags = 0;
+#endif
+
int nfd = accept_socket(
- pf->fd,SOCK_NONBLOCK,
+ pf->fd, flags,
client_ip, INET6_ADDRSTRLEN, client_port,NI_MAXSERV, client_host, NI_MAXHOST,
p->access_list, p->allow_dns
);
+#ifndef SOCK_NONBLOCK
+ if (nfd > 0) {
+ int flags = fcntl(nfd, F_GETFL);
+ (void)fcntl(nfd, F_SETFL, flags| O_NONBLOCK);
+ }
+#endif
+
if (unlikely(nfd < 0)) {
// accept failed
diff --git a/src/libnetdata/socket/socket.h b/src/libnetdata/socket/socket.h
index debbd766d9..d506f7aae1 100644
--- a/src/libnetdata/socket/socket.h
+++ b/src/libnetdata/socket/socket.h
@@ -51,6 +51,7 @@ bool sock_has_output_error(int fd);
int sock_setnonblock(int fd);
int sock_delnonblock(int fd);
int sock_setreuse(int fd, int reuse);
+void sock_setcloexec(int fd);
int sock_setreuse_port(int fd, int reuse);
int sock_enlarge_in(int fd);
int sock_enlarge_out(int fd);
@@ -62,17 +63,14 @@ int accept_socket(int fd, int flags, char *client_ip, size_t ipsize, char *clien
#ifndef HAVE_ACCEPT4
int accept4(int sock, struct sockaddr *addr, socklen_t *addrlen, int flags);
-
-#ifndef SOCK_NONBLOCK
-#define SOCK_NONBLOCK 00004000
-#endif /* #ifndef SOCK_NONBLOCK */
-
-#ifndef SOCK_CLOEXEC
-#define SOCK_CLOEXEC 02000000
-#endif /* #ifndef SOCK_CLOEXEC */
-
#endif /* #ifndef HAVE_ACCEPT4 */
+#ifdef SOCK_CLOEXEC
+#define DEFAULT_SOCKET_FLAGS SOCK_CLOEXEC
+#else
+#define DEFAULT_SOCKET_FLAGS 0
+#endif
+
// ----------------------------------------------------------------------------
// poll() based listener
diff --git a/src/streaming/sender.c b/src/streaming/sender.c
index 31eed95fa1..bb617c5fd7 100644
--- a/src/streaming/sender.c
+++ b/src/streaming/sender.c
@@ -947,6 +947,7 @@ static bool rrdpush_sender_thread_connect_to_parent(RRDHOST *host, int default_p
nd_log(NDLS_DAEMON, NDLP_WARNING,
"STREAM %s [send to %s]: cannot set non-blocking mode for socket.",
rrdhost_hostname(host), s->connected_to);
+ sock_setcloexec(s->rrdpush_sender_socket);
if(sock_enlarge_out(s->rrdpush_sender_socket) < 0)
nd_log(NDLS_DAEMON, NDLP_WARNING,