diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-05 12:08:03 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-05 12:08:18 +0000 |
commit | 5da14042f70711ea5cf66e034699730335462f66 (patch) | |
tree | 0f6354ccac934ed87a2d555f45be4c831cf92f4a /src/libnetdata/socket/socket.c | |
parent | Releasing debian version 1.44.3-2. (diff) | |
download | netdata-5da14042f70711ea5cf66e034699730335462f66.tar.xz netdata-5da14042f70711ea5cf66e034699730335462f66.zip |
Merging upstream version 1.45.3+dfsg.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | src/libnetdata/socket/socket.c (renamed from libnetdata/socket/socket.c) | 92 |
1 files changed, 59 insertions, 33 deletions
diff --git a/libnetdata/socket/socket.c b/src/libnetdata/socket/socket.c index 605e85635..b157b157b 100644 --- a/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, 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, 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, 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 */ @@ -500,7 +511,7 @@ void listen_sockets_close(LISTEN_SOCKETS *sockets) { * * @param acl is the acl given by the user. */ -WEB_CLIENT_ACL socket_ssl_acl(char *acl) { +HTTP_ACL socket_ssl_acl(char *acl) { char *ssl = strchr(acl,'^'); if(ssl) { //Due the format of the SSL command it is always the last command, @@ -511,34 +522,34 @@ WEB_CLIENT_ACL socket_ssl_acl(char *acl) { if (!strncmp("SSL=",ssl,4)) { ssl += 4; if (!strcmp(ssl,"optional")) { - return WEB_CLIENT_ACL_SSL_OPTIONAL; + return HTTP_ACL_SSL_OPTIONAL; } else if (!strcmp(ssl,"force")) { - return WEB_CLIENT_ACL_SSL_FORCE; + return HTTP_ACL_SSL_FORCE; } } #endif } - return WEB_CLIENT_ACL_NONE; + return HTTP_ACL_NONE; } -WEB_CLIENT_ACL read_acl(char *st) { - WEB_CLIENT_ACL ret = socket_ssl_acl(st); +HTTP_ACL read_acl(char *st) { + HTTP_ACL ret = socket_ssl_acl(st); - if (!strcmp(st,"dashboard")) ret |= WEB_CLIENT_ACL_DASHBOARD; - if (!strcmp(st,"registry")) ret |= WEB_CLIENT_ACL_REGISTRY; - if (!strcmp(st,"badges")) ret |= WEB_CLIENT_ACL_BADGE; - if (!strcmp(st,"management")) ret |= WEB_CLIENT_ACL_MGMT; - if (!strcmp(st,"streaming")) ret |= WEB_CLIENT_ACL_STREAMING; - if (!strcmp(st,"netdata.conf")) ret |= WEB_CLIENT_ACL_NETDATACONF; + if (!strcmp(st,"dashboard")) ret |= HTTP_ACL_DASHBOARD; + if (!strcmp(st,"registry")) ret |= HTTP_ACL_REGISTRY; + if (!strcmp(st,"badges")) ret |= HTTP_ACL_BADGES; + if (!strcmp(st,"management")) ret |= HTTP_ACL_MANAGEMENT; + if (!strcmp(st,"streaming")) ret |= HTTP_ACL_STREAMING; + if (!strcmp(st,"netdata.conf")) ret |= HTTP_ACL_NETDATACONF; return ret; } static inline int bind_to_this(LISTEN_SOCKETS *sockets, const char *definition, uint16_t default_port, int listen_backlog) { int added = 0; - WEB_CLIENT_ACL acl_flags = WEB_CLIENT_ACL_NONE; + HTTP_ACL acl_flags = HTTP_ACL_NONE; struct addrinfo hints; struct addrinfo *result = NULL, *rp = NULL; @@ -549,7 +560,7 @@ static inline int bind_to_this(LISTEN_SOCKETS *sockets, const char *definition, char buffer2[10 + 1]; snprintfz(buffer2, 10, "%d", default_port); - char *ip = buffer, *port = buffer2, *interface = "", *portconfig;; + char *ip = buffer, *port = buffer2, *interface = "", *portconfig; int protocol = IPPROTO_TCP, socktype = SOCK_STREAM; const char *protocol_str = "tcp"; @@ -559,12 +570,14 @@ static inline int bind_to_this(LISTEN_SOCKETS *sockets, const char *definition, protocol = IPPROTO_TCP; socktype = SOCK_STREAM; protocol_str = "tcp"; + acl_flags |= HTTP_ACL_API; } else if(strncmp(ip, "udp:", 4) == 0) { ip += 4; protocol = IPPROTO_UDP; socktype = SOCK_DGRAM; protocol_str = "udp"; + acl_flags |= HTTP_ACL_API_UDP; } else if(strncmp(ip, "unix:", 5) == 0) { char *path = ip + 5; @@ -578,7 +591,8 @@ static inline int bind_to_this(LISTEN_SOCKETS *sockets, const char *definition, sockets->failed++; } else { - acl_flags = WEB_CLIENT_ACL_DASHBOARD | WEB_CLIENT_ACL_REGISTRY | WEB_CLIENT_ACL_BADGE | WEB_CLIENT_ACL_MGMT | WEB_CLIENT_ACL_NETDATACONF | WEB_CLIENT_ACL_STREAMING | WEB_CLIENT_ACL_SSL_DEFAULT; + acl_flags = HTTP_ACL_API_UNIX | HTTP_ACL_DASHBOARD | HTTP_ACL_REGISTRY | HTTP_ACL_BADGES | + HTTP_ACL_MANAGEMENT | HTTP_ACL_NETDATACONF | HTTP_ACL_STREAMING | HTTP_ACL_SSL_DEFAULT; listen_sockets_add(sockets, fd, AF_UNIX, socktype, protocol_str, path, 0, acl_flags); added++; } @@ -628,13 +642,13 @@ static inline int bind_to_this(LISTEN_SOCKETS *sockets, const char *definition, } acl_flags |= read_acl(portconfig); } else { - acl_flags = WEB_CLIENT_ACL_DASHBOARD | WEB_CLIENT_ACL_REGISTRY | WEB_CLIENT_ACL_BADGE | WEB_CLIENT_ACL_MGMT | WEB_CLIENT_ACL_NETDATACONF | WEB_CLIENT_ACL_STREAMING | WEB_CLIENT_ACL_SSL_DEFAULT; + acl_flags |= HTTP_ACL_DASHBOARD | HTTP_ACL_REGISTRY | HTTP_ACL_BADGES | HTTP_ACL_MANAGEMENT | HTTP_ACL_NETDATACONF | HTTP_ACL_STREAMING | HTTP_ACL_SSL_DEFAULT; } //Case the user does not set the option SSL in the "bind to", but he has //the certificates, I must redirect, so I am assuming here the default option - if(!(acl_flags & WEB_CLIENT_ACL_SSL_OPTIONAL) && !(acl_flags & WEB_CLIENT_ACL_SSL_FORCE)) { - acl_flags |= WEB_CLIENT_ACL_SSL_DEFAULT; + if(!(acl_flags & HTTP_ACL_SSL_OPTIONAL) && !(acl_flags & HTTP_ACL_SSL_FORCE)) { + acl_flags |= HTTP_ACL_SSL_DEFAULT; } uint32_t scope_id = 0; @@ -778,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, 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'", @@ -794,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; @@ -891,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, 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) @@ -899,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) { @@ -1263,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) { @@ -1384,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); + 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) { @@ -1398,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) @@ -1463,7 +1476,7 @@ int accept_socket(int fd, int flags, char *client_ip, size_t ipsize, char *clien inline POLLINFO *poll_add_fd(POLLJOB *p , int fd , int socktype - , WEB_CLIENT_ACL port_acl + , HTTP_ACL port_acl , uint32_t flags , const char *client_ip , const char *client_port @@ -1782,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 |