Skip to content

Commit

Permalink
added support for binding to a configured IP address (IPv6 or IPv4)
Browse files Browse the repository at this point in the history
  • Loading branch information
ktsaou committed Apr 4, 2016
1 parent d3d8d3f commit a44f489
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 56 deletions.
5 changes: 4 additions & 1 deletion netdata-installer.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
142 changes: 91 additions & 51 deletions src/web_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}


Expand Down
4 changes: 2 additions & 2 deletions src/web_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

0 comments on commit a44f489

Please sign in to comment.