@cryptotaxi247 / netdata-1 / commits / db63ab822

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

Stelios Fragkakis committed Mar 15, 2024 at 15:28 UTC db63ab82265f0606e33600a350e4ee6cc2dda687
5 files changed +55 -25
src/aclk/mqtt_websockets/mqtt_wss_client.c
+7 -1
@@ -583,12 +583,18 @@ int mqtt_wss_connect(mqtt_wss_client client, char *host, int port, struct mqtt_c
583
584 if (client->sockfd > 0)
585 close(client->sockfd);
586 - client->sockfd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
586 + client->sockfd = socket(AF_INET, SOCK_STREAM | DEFAULT_SOCKET_FLAGS, 0);
587 if (client->sockfd < 0) {
588 mws_error(client->log, "Couldn't create socket()");
589 return -1;
590 }
591
592 +#ifndef SOCK_CLOEXEC
593 + int flags = fcntl(client->sockfd, F_GETFD);
594 + if (flags != -1)
595 + (void) fcntl(client->sockfd, F_SETFD, flags| FD_CLOEXEC);
596 +#endif
597 +
598 int flag = 1;
599 int result = setsockopt(client->sockfd,
600 IPPROTO_TCP,
src/libnetdata/log/journal.c
+3 -1
@@ -48,9 +48,11 @@ int journal_direct_fd(const char *path) {
48 if(!is_path_unix_socket(path))
49 return -1;
50
51 - int fd = socket(AF_UNIX, SOCK_DGRAM| SOCK_CLOEXEC, 0);
51 + int fd = socket(AF_UNIX, SOCK_DGRAM| DEFAULT_SOCKET_FLAGS, 0);
52 if (fd < 0) return -1;
53
54 + sock_setcloexec(fd);
55 +
56 struct sockaddr_un addr;
57 memset(&addr, 0, sizeof(struct sockaddr_un));
58 addr.sun_family = AF_UNIX;
src/libnetdata/socket/socket.c
+37 -14
@@ -191,6 +191,16 @@ int sock_setreuse(int fd, int reuse) {
191 return ret;
192 }
193
194 +void sock_setcloexec(int fd)
195 +{
196 + UNUSED(fd);
197 +#ifndef SOCK_CLOEXEC
198 + int flags = fcntl(fd, F_GETFD);
199 + if (flags != -1)
200 + (void) fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
201 +#endif
202 +}
203 +
204 int sock_setreuse_port(int fd, int reuse) {
205 int ret;
206
@@ -262,7 +272,7 @@ char *strdup_client_description(int family, const char *protocol, const char *ip
272 int create_listen_socket_unix(const char *path, int listen_backlog) {
273 int sock;
274
265 - sock = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
275 + sock = socket(AF_UNIX, SOCK_STREAM | DEFAULT_SOCKET_FLAGS, 0);
276 if(sock < 0) {
277 nd_log(NDLS_DAEMON, NDLP_ERR,
278 "LISTENER: UNIX socket() on path '%s' failed.",
@@ -272,6 +282,7 @@ int create_listen_socket_unix(const char *path, int listen_backlog) {
282 }
283
284 sock_setnonblock(sock);
285 + sock_setcloexec(sock);
286 sock_enlarge_in(sock);
287
288 struct sockaddr_un name;
@@ -316,7 +327,7 @@ int create_listen_socket_unix(const char *path, int listen_backlog) {
327 int create_listen_socket4(int socktype, const char *ip, uint16_t port, int listen_backlog) {
328 int sock;
329
319 - sock = socket(AF_INET, socktype | SOCK_CLOEXEC, 0);
330 + sock = socket(AF_INET, socktype | DEFAULT_SOCKET_FLAGS, 0);
331 if(sock < 0) {
332 nd_log(NDLS_DAEMON, NDLP_ERR,
333 "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
335
336 return -1;
337 }
327 -
338 sock_setreuse(sock, 1);
339 sock_setreuse_port(sock, 0);
340 sock_setnonblock(sock);
341 + sock_setcloexec(sock);
342 sock_enlarge_in(sock);
343
344 struct sockaddr_in name;
@@ -374,7 +385,7 @@ int create_listen_socket6(int socktype, uint32_t scope_id, const char *ip, int p
385 int sock;
386 int ipv6only = 1;
387
377 - sock = socket(AF_INET6, socktype | SOCK_CLOEXEC, 0);
388 + sock = socket(AF_INET6, socktype | DEFAULT_SOCKET_FLAGS, 0);
389 if (sock < 0) {
390 nd_log(NDLS_DAEMON, NDLP_ERR,
391 "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
393
394 return -1;
395 }
385 -
396 sock_setreuse(sock, 1);
397 sock_setreuse_port(sock, 0);
398 sock_setnonblock(sock);
399 + sock_setcloexec(sock);
400 sock_enlarge_in(sock);
401
402 /* IPv6 only */
@@ -781,7 +792,7 @@ int listen_sockets_setup(LISTEN_SOCKETS *sockets) {
792 // timeout the timeout for establishing a connection
793
794 static inline int connect_to_unix(const char *path, struct timeval *timeout) {
784 - int fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
795 + int fd = socket(AF_UNIX, SOCK_STREAM | DEFAULT_SOCKET_FLAGS, 0);
796 if(fd == -1) {
797 nd_log(NDLS_DAEMON, NDLP_ERR,
798 "Failed to create UNIX socket() for '%s'",
@@ -797,6 +808,8 @@ static inline int connect_to_unix(const char *path, struct timeval *timeout) {
808 path);
809 }
810
811 + sock_setcloexec(fd);
812 +
813 struct sockaddr_un addr;
814 memset(&addr, 0, sizeof(addr));
815 addr.sun_family = AF_UNIX;
@@ -894,7 +907,7 @@ int connect_to_this_ip46(int protocol, int socktype, const char *host, uint32_t
907 }
908 }
909
897 - fd = socket(ai->ai_family, ai->ai_socktype | SOCK_CLOEXEC, ai->ai_protocol);
910 + fd = socket(ai->ai_family, ai->ai_socktype | DEFAULT_SOCKET_FLAGS, ai->ai_protocol);
911 if(fd != -1) {
912 if(timeout) {
913 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
915 "Failed to set timeout on the socket to ip '%s' port '%s'",
916 hostBfr, servBfr);
917 }
918 + sock_setcloexec(fd);
919
920 errno = 0;
921 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) {
1280
1281 if (fd < 0) return fd;
1282
1269 - if (flags & SOCK_NONBLOCK) {
1270 - newflags |= O_NONBLOCK;
1271 - flags &= ~SOCK_NONBLOCK;
1272 - }
1273 -
1283 #ifdef SOCK_CLOEXEC
1284 #ifdef O_CLOEXEC
1285 if (flags & SOCK_CLOEXEC) {
@@ -1387,7 +1396,7 @@ int accept_socket(int fd, int flags, char *client_ip, size_t ipsize, char *clien
1396 struct sockaddr_storage sadr;
1397 socklen_t addrlen = sizeof(sadr);
1398
1390 - int nfd = accept4(fd, (struct sockaddr *)&sadr, &addrlen, flags | SOCK_CLOEXEC);
1399 + int nfd = accept4(fd, (struct sockaddr *)&sadr, &addrlen, flags | DEFAULT_SOCKET_FLAGS);
1400 if (likely(nfd >= 0)) {
1401 if (getnameinfo((struct sockaddr *)&sadr, addrlen, client_ip, (socklen_t)ipsize,
1402 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
1410 if (!strcmp(client_ip, "127.0.0.1") || !strcmp(client_ip, "::1")) {
1411 strncpyz(client_ip, "localhost", ipsize);
1412 }
1413 + sock_setcloexec(nfd);
1414
1415 #ifdef __FreeBSD__
1416 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
1795 char client_port[NI_MAXSERV] = "";
1796 char client_host[NI_MAXHOST] = "";
1797
1798 +#ifdef SOCK_NONBLOCK
1799 + int flags = SOCK_NONBLOCK;
1800 +#else
1801 + int flags = 0;
1802 +#endif
1803 +
1804 int nfd = accept_socket(
1789 - pf->fd,SOCK_NONBLOCK,
1805 + pf->fd, flags,
1806 client_ip, INET6_ADDRSTRLEN, client_port,NI_MAXSERV, client_host, NI_MAXHOST,
1807 p->access_list, p->allow_dns
1808 );
1809
1810 +#ifndef SOCK_NONBLOCK
1811 + if (nfd > 0) {
1812 + int flags = fcntl(nfd, F_GETFL);
1813 + (void)fcntl(nfd, F_SETFL, flags| O_NONBLOCK);
1814 + }
1815 +#endif
1816 +
1817 if (unlikely(nfd < 0)) {
1818 // accept failed
1819
src/libnetdata/socket/socket.h
+7 -9
@@ -51,6 +51,7 @@ bool sock_has_output_error(int fd);
51 int sock_setnonblock(int fd);
52 int sock_delnonblock(int fd);
53 int sock_setreuse(int fd, int reuse);
54 +void sock_setcloexec(int fd);
55 int sock_setreuse_port(int fd, int reuse);
56 int sock_enlarge_in(int fd);
57 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
63
64 #ifndef HAVE_ACCEPT4
65 int accept4(int sock, struct sockaddr *addr, socklen_t *addrlen, int flags);
65 -
66 -#ifndef SOCK_NONBLOCK
67 -#define SOCK_NONBLOCK 00004000
68 -#endif /* #ifndef SOCK_NONBLOCK */
69 -
70 -#ifndef SOCK_CLOEXEC
71 -#define SOCK_CLOEXEC 02000000
72 -#endif /* #ifndef SOCK_CLOEXEC */
73 -
66 #endif /* #ifndef HAVE_ACCEPT4 */
67
68 +#ifdef SOCK_CLOEXEC
69 +#define DEFAULT_SOCKET_FLAGS SOCK_CLOEXEC
70 +#else
71 +#define DEFAULT_SOCKET_FLAGS 0
72 +#endif
73 +
74
75 // ----------------------------------------------------------------------------
76 // poll() based listener
src/streaming/sender.c
+1
@@ -947,6 +947,7 @@ static bool rrdpush_sender_thread_connect_to_parent(RRDHOST *host, int default_p
947 nd_log(NDLS_DAEMON, NDLP_WARNING,
948 "STREAM %s [send to %s]: cannot set non-blocking mode for socket.",
949 rrdhost_hostname(host), s->connected_to);
950 + sock_setcloexec(s->rrdpush_sender_socket);
951
952 if(sock_enlarge_out(s->rrdpush_sender_socket) < 0)
953 nd_log(NDLS_DAEMON, NDLP_WARNING,