summaryrefslogtreecommitdiffstats
path: root/libnetdata/socket/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'libnetdata/socket/socket.c')
-rw-r--r--libnetdata/socket/socket.c67
1 files changed, 53 insertions, 14 deletions
diff --git a/libnetdata/socket/socket.c b/libnetdata/socket/socket.c
index c266efeb..6b0b3b67 100644
--- a/libnetdata/socket/socket.c
+++ b/libnetdata/socket/socket.c
@@ -248,7 +248,7 @@ int create_listen_socket6(int socktype, uint32_t scope_id, const char *ip, int p
return sock;
}
-static inline int listen_sockets_add(LISTEN_SOCKETS *sockets, int fd, int family, int socktype, const char *protocol, const char *ip, uint16_t port) {
+static inline int listen_sockets_add(LISTEN_SOCKETS *sockets, int fd, int family, int socktype, const char *protocol, const char *ip, uint16_t port, int acl_flags) {
if(sockets->opened >= MAX_LISTEN_FDS) {
error("LISTENER: Too many listening sockets. Failed to add listening %s socket at ip '%s' port %d, protocol %s, socktype %d", protocol, ip, port, protocol, socktype);
close(fd);
@@ -259,6 +259,7 @@ static inline int listen_sockets_add(LISTEN_SOCKETS *sockets, int fd, int family
sockets->fds_types[sockets->opened] = socktype;
sockets->fds_families[sockets->opened] = family;
sockets->fds_names[sockets->opened] = strdup_client_description(family, protocol, ip, port);
+ sockets->fds_acl_flags[sockets->opened] = acl_flags;
sockets->opened++;
return 0;
@@ -300,8 +301,20 @@ void listen_sockets_close(LISTEN_SOCKETS *sockets) {
sockets->failed = 0;
}
+WEB_CLIENT_ACL read_acl(char *st) {
+ if (!strcmp(st,"dashboard")) return WEB_CLIENT_ACL_DASHBOARD;
+ if (!strcmp(st,"registry")) return WEB_CLIENT_ACL_REGISTRY;
+ if (!strcmp(st,"badges")) return WEB_CLIENT_ACL_BADGE;
+ if (!strcmp(st,"management")) return WEB_CLIENT_ACL_MGMT;
+ if (!strcmp(st,"streaming")) return WEB_CLIENT_ACL_STREAMING;
+ if (!strcmp(st,"netdata.conf")) return WEB_CLIENT_ACL_NETDATACONF;
+ return WEB_CLIENT_ACL_NONE;
+}
+
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;
+
struct addrinfo hints;
struct addrinfo *result = NULL, *rp = NULL;
@@ -311,7 +324,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 = "";;
+ char *ip = buffer, *port = buffer2, *interface = "", *portconfig;;
int protocol = IPPROTO_TCP, socktype = SOCK_STREAM;
const char *protocol_str = "tcp";
@@ -332,14 +345,13 @@ static inline int bind_to_this(LISTEN_SOCKETS *sockets, const char *definition,
char *path = ip + 5;
socktype = SOCK_STREAM;
protocol_str = "unix";
-
int fd = create_listen_socket_unix(path, listen_backlog);
if (fd == -1) {
error("LISTENER: Cannot create unix socket '%s'", path);
sockets->failed++;
- }
- else {
- listen_sockets_add(sockets, fd, AF_UNIX, socktype, protocol_str, path, 0);
+ } 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;
+ listen_sockets_add(sockets, fd, AF_UNIX, socktype, protocol_str, path, 0, acl_flags);
added++;
}
return added;
@@ -355,19 +367,40 @@ static inline int bind_to_this(LISTEN_SOCKETS *sockets, const char *definition,
}
}
else {
- while(*e && *e != ':' && *e != '%') e++;
+ while(*e && *e != ':' && *e != '%' && *e != '=') e++;
}
if(*e == '%') {
*e = '\0';
e++;
interface = e;
- while(*e && *e != ':') e++;
+ while(*e && *e != ':' && *e != '=') e++;
}
if(*e == ':') {
port = e + 1;
*e = '\0';
+ e++;
+ while(*e && *e != '=') e++;
+ }
+
+ if(*e == '=') {
+ *e='\0';
+ e++;
+ portconfig = e;
+ while (*e != '\0') {
+ if (*e == '|') {
+ *e = '\0';
+ acl_flags |= read_acl(portconfig);
+ e++;
+ portconfig = e;
+ continue;
+ }
+ e++;
+ }
+ 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;
}
uint32_t scope_id = 0;
@@ -435,7 +468,7 @@ static inline int bind_to_this(LISTEN_SOCKETS *sockets, const char *definition,
sockets->failed++;
}
else {
- listen_sockets_add(sockets, fd, family, socktype, protocol_str, rip, rport);
+ listen_sockets_add(sockets, fd, family, socktype, protocol_str, rip, rport, acl_flags);
added++;
}
}
@@ -975,6 +1008,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
, uint32_t flags
, const char *client_ip
, const char *client_port
@@ -1013,6 +1047,8 @@ inline POLLINFO *poll_add_fd(POLLJOB *p
p->inf[i].slot = (size_t)i;
p->inf[i].flags = 0;
p->inf[i].socktype = -1;
+ p->inf[i].port_acl = -1;
+
p->inf[i].client_ip = NULL;
p->inf[i].client_port = NULL;
p->inf[i].del_callback = p->del_callback;
@@ -1042,6 +1078,7 @@ inline POLLINFO *poll_add_fd(POLLJOB *p
pi->fd = fd;
pi->p = p;
pi->socktype = socktype;
+ pi->port_acl = port_acl;
pi->flags = flags;
pi->next = NULL;
pi->client_ip = strdupz(client_ip);
@@ -1230,7 +1267,7 @@ static void poll_events_process(POLLJOB *p, POLLINFO *pi, struct pollfd *pf, sho
#ifdef NETDATA_INTERNAL_CHECKS
// this is common - it is used for web server file copies
if(unlikely(!(pf->events & (POLLIN|POLLOUT)))) {
- error("POLLFD: LISTENER: after reading, client slot %zu (fd %d) from '%s:%s' was left without expecting input or output. ", i, fd, pi->client_ip?pi->client_ip:"<undefined-ip>", pi->client_port?pi->client_port:"<undefined-port>");
+ error("POLLFD: LISTENER: after reading, client slot %zu (fd %d) from %s port %s was left without expecting input or output. ", i, fd, pi->client_ip?pi->client_ip:"<undefined-ip>", pi->client_port?pi->client_port:"<undefined-port>");
//poll_close_fd(pi);
//return;
}
@@ -1272,6 +1309,7 @@ static void poll_events_process(POLLJOB *p, POLLINFO *pi, struct pollfd *pf, sho
poll_add_fd(p
, nfd
, SOCK_STREAM
+ , pi->port_acl
, POLLINFO_FLAG_CLIENT_SOCKET
, client_ip
, client_port
@@ -1331,7 +1369,7 @@ static void poll_events_process(POLLJOB *p, POLLINFO *pi, struct pollfd *pf, sho
#ifdef NETDATA_INTERNAL_CHECKS
// this is common - it is used for streaming
if(unlikely(pi->flags & POLLINFO_FLAG_CLIENT_SOCKET && !(pf->events & (POLLIN|POLLOUT)))) {
- error("POLLFD: LISTENER: after sending, client slot %zu (fd %d) from '%s:%s' was left without expecting input or output. ", i, fd, pi->client_ip?pi->client_ip:"<undefined-ip>", pi->client_port?pi->client_port:"<undefined-port>");
+ error("POLLFD: LISTENER: after sending, client slot %zu (fd %d) from %s port %s was left without expecting input or output. ", i, fd, pi->client_ip?pi->client_ip:"<undefined-ip>", pi->client_port?pi->client_port:"<undefined-port>");
//poll_close_fd(pi);
//return;
}
@@ -1414,6 +1452,7 @@ void poll_events(LISTEN_SOCKETS *sockets
POLLINFO *pi = poll_add_fd(&p
, sockets->fds[i]
, sockets->fds_types[i]
+ , sockets->fds_acl_flags[i]
, POLLINFO_FLAG_SERVER_SOCKET
, (sockets->fds_names[i])?sockets->fds_names[i]:"UNKNOWN"
, ""
@@ -1457,7 +1496,7 @@ void poll_events(LISTEN_SOCKETS *sockets
}
usec_t dt_usec = next_timer_usec - now_usec;
- if(dt_usec > 1000 * USEC_PER_MS)
+ if(dt_usec < 1000 * USEC_PER_MS)
timeout_ms = 1000;
else
timeout_ms = (int)(dt_usec / USEC_PER_MS);
@@ -1503,7 +1542,7 @@ void poll_events(LISTEN_SOCKETS *sockets
if(likely(pi->flags & POLLINFO_FLAG_CLIENT_SOCKET)) {
if (unlikely(pi->send_count == 0 && p.complete_request_timeout > 0 && (now - pi->connected_t) >= p.complete_request_timeout)) {
- info("POLLFD: LISTENER: client slot %zu (fd %d) from '%s:%s' has not sent a complete request in %zu seconds - closing it. "
+ info("POLLFD: LISTENER: client slot %zu (fd %d) from %s port %s has not sent a complete request in %zu seconds - closing it. "
, i
, pi->fd
, pi->client_ip ? pi->client_ip : "<undefined-ip>"
@@ -1513,7 +1552,7 @@ void poll_events(LISTEN_SOCKETS *sockets
poll_close_fd(pi);
}
else if(unlikely(pi->recv_count && p.idle_timeout > 0 && now - ((pi->last_received_t > pi->last_sent_t) ? pi->last_received_t : pi->last_sent_t) >= p.idle_timeout )) {
- info("POLLFD: LISTENER: client slot %zu (fd %d) from '%s:%s' is idle for more than %zu seconds - closing it. "
+ info("POLLFD: LISTENER: client slot %zu (fd %d) from %s port %s is idle for more than %zu seconds - closing it. "
, i
, pi->fd
, pi->client_ip ? pi->client_ip : "<undefined-ip>"