summaryrefslogtreecommitdiffstats
path: root/src/libnetdata/socket/socket.c
diff options
context:
space:
mode:
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