diff options
-rwxr-xr-x | netdata-installer.sh | 5 | ||||
-rw-r--r-- | src/main.c | 4 | ||||
-rw-r--r-- | src/web_server.c | 142 | ||||
-rw-r--r-- | src/web_server.h | 4 |
4 files changed, 99 insertions, 56 deletions
diff --git a/netdata-installer.sh b/netdata-installer.sh index 2b316ff784..7a00a56cec 100755 --- a/netdata-installer.sh +++ b/netdata-installer.sh @@ -314,7 +314,10 @@ do count=$((count + 1)) - pid=$(cat /var/run/netdata/netdata.pid 2>/dev/null || cat /var/run/netdata.pid 2>/dev/null) + pid=$(cat /var/run/netdata.pid 2>/dev/null) + # backwards compatibility + [ -z "${pid}" ] && pid=$(cat /var/run/netdata/netdata.pid 2>/dev/null) + isnetdata $pid || pid= if [ ! -z "${pid}" ] then diff --git a/src/main.c b/src/main.c index 1ba8e461e4..2234b9cf2b 100644 --- a/src/main.c +++ b/src/main.c @@ -441,9 +441,9 @@ int main(int argc, char **argv) else if(!strcmp(ipv, "ipv6") || !strcmp(ipv, "IPV6") || !strcmp(ipv, "IPv6") || !strcmp(ipv, "6")) ip = 6; else fprintf(stderr, "Cannot understand ip version '%s'. Assumming 'any'.", ipv); - if(ip == 0 || ip == 6) listen_fd = create_listen_socket6(listen_port, listen_backlog); + if(ip == 0 || ip == 6) listen_fd = create_listen_socket6(config_get("global", "bind socket to IP", "*"), listen_port, listen_backlog); if(listen_fd < 0) { - listen_fd = create_listen_socket4(listen_port, listen_backlog); + listen_fd = create_listen_socket4(config_get("global", "bind socket to IP", "*"), listen_port, listen_backlog); if(listen_fd >= 0 && ip != 4) fprintf(stderr, "Managed to open an IPv4 socket on port %d.", listen_port); } diff --git a/src/web_server.c b/src/web_server.c index 031361402b..ab3e4357a6 100644 --- a/src/web_server.c +++ b/src/web_server.c @@ -49,81 +49,121 @@ static void log_allocations(void) } #endif -int create_listen_socket4(int port, int listen_backlog) +static int is_ip_anything(const char *ip) { - int sock; - int sockopt = 1; - struct sockaddr_in name; + if(!ip || !*ip + || !strcmp(ip, "any") + || !strcmp(ip, "all") + || !strcmp(ip, "*") + || !strcmp(ip, "::") + || !strcmp(ip, "0.0.0.0") + ) return 1; + + return 0; +} - debug(D_LISTENER, "IPv4 creating new listening socket on port %d", port); +int create_listen_socket4(const char *ip, int port, int listen_backlog) +{ + int sock; + int sockopt = 1; + struct sockaddr_in name; - sock = socket(AF_INET, SOCK_STREAM, 0); - if(sock < 0) { - error("IPv4 socket() failed."); - return -1; - } + debug(D_LISTENER, "IPv4 creating new listening socket on port %d", port); - /* avoid "address already in use" */ - setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*)&sockopt, sizeof(sockopt)); + sock = socket(AF_INET, SOCK_STREAM, 0); + if(sock < 0) { + error("IPv4 socket() failed."); + return -1; + } - memset(&name, 0, sizeof(struct sockaddr_in)); - name.sin_family = AF_INET; - name.sin_port = htons (port); - name.sin_addr.s_addr = htonl (INADDR_ANY); + /* avoid "address already in use" */ + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*)&sockopt, sizeof(sockopt)); - if(bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0) { - close(sock); - error("IPv4 bind() failed."); - return -1; - } + memset(&name, 0, sizeof(struct sockaddr_in)); + name.sin_family = AF_INET; + name.sin_port = htons (port); - if(listen(sock, listen_backlog) < 0) { + if(is_ip_anything(ip)) { + name.sin_addr.s_addr = htonl(INADDR_ANY); + info("Listening on any IPs (IPv4)."); + } + else { + int ret = inet_pton(AF_INET, ip, (void *)&name.sin_addr.s_addr); + if(ret != 1) { + error("Failed to convert IP '%s' to a valid IPv4 address.", ip); close(sock); - fatal("IPv4 listen() failed."); return -1; } + info("Listening on IP '%s' (IPv4).", ip); + } + + if(bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0) { + close(sock); + error("IPv4 bind() failed."); + return -1; + } + + if(listen(sock, listen_backlog) < 0) { + close(sock); + fatal("IPv4 listen() failed."); + return -1; + } - debug(D_LISTENER, "IPv4 listening port %d created", port); - return sock; + debug(D_LISTENER, "IPv4 listening port %d created", port); + return sock; } -int create_listen_socket6(int port, int listen_backlog) +int create_listen_socket6(const char *ip, int port, int listen_backlog) { - int sock = -1; - int sockopt = 1; - struct sockaddr_in6 name; + int sock = -1; + int sockopt = 1; + struct sockaddr_in6 name; - debug(D_LISTENER, "IPv6 creating new listening socket on port %d", port); + debug(D_LISTENER, "IPv6 creating new listening socket on port %d", port); - sock = socket(AF_INET6, SOCK_STREAM, 0); - if (sock < 0) { - error("IPv6 socket() failed."); - return -1; - } + sock = socket(AF_INET6, SOCK_STREAM, 0); + if (sock < 0) { + error("IPv6 socket() failed. Disabling IPv6."); + return -1; + } - /* avoid "address already in use" */ - setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*)&sockopt, sizeof(sockopt)); + /* avoid "address already in use" */ + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*)&sockopt, sizeof(sockopt)); - memset(&name, 0, sizeof(struct sockaddr_in6)); - name.sin6_family = AF_INET6; - name.sin6_port = htons ((uint16_t) port); - name.sin6_addr = in6addr_any; - name.sin6_scope_id = 0; + memset(&name, 0, sizeof(struct sockaddr_in6)); + name.sin6_family = AF_INET6; + name.sin6_port = htons ((uint16_t) port); - if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0) { + if(is_ip_anything(ip)) { + name.sin6_addr = in6addr_any; + info("Listening on all IPs (IPv6 and IPv4)"); + } + else { + int ret = inet_pton(AF_INET6, ip, (void *)&name.sin6_addr.s6_addr); + if(ret != 1) { + error("Failed to convert IP '%s' to a valid IPv6 address. Disabling IPv6.", ip); close(sock); - error("IPv6 bind() failed."); return -1; } + info("Listening on IP '%s' (IPv6)", ip); + } - if (listen(sock, listen_backlog) < 0) { - close(sock); - fatal("IPv6 listen() failed."); - return -1; - } + name.sin6_scope_id = 0; + + if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0) { + close(sock); + error("IPv6 bind() failed. Disabling IPv6."); + return -1; + } + + if (listen(sock, listen_backlog) < 0) { + close(sock); + error("IPv6 listen() failed. Disabling IPv6."); + return -1; + } - debug(D_LISTENER, "IPv6 listening port %d created", port); - return sock; + debug(D_LISTENER, "IPv6 listening port %d created", port); + return sock; } diff --git a/src/web_server.h b/src/web_server.h index 0d1e2da925..39f3bad918 100644 --- a/src/web_server.h +++ b/src/web_server.h @@ -13,8 +13,8 @@ extern int listen_backlog; extern int listen_fd; extern int listen_port; -extern int create_listen_socket4(int port, int listen_backlog); -extern int create_listen_socket6(int port, int listen_backlog); +extern int create_listen_socket4(const char *ip, int port, int listen_backlog); +extern int create_listen_socket6(const char *ip, int port, int listen_backlog); extern void *socket_listen_main(void *ptr); #endif /* NETDATA_WEB_SERVER_H */ |