@cryptotaxi247 / netdata-1 / commits / a44f48981

added support for binding to a configured IP address (IPv6 or IPv4)

Costa Tsaousis (ktsaou) committed Apr 4, 2016 at 15:38 UTC a44f48981dba80bd4376226a7b30b3534660a855
4 files changed +99 -56
netdata-installer.sh
+4 -1
@@ -314,7 +314,10 @@ do
314
315 count=$((count + 1))
316
317 - pid=$(cat /var/run/netdata/netdata.pid 2>/dev/null || cat /var/run/netdata.pid 2>/dev/null)
317 + pid=$(cat /var/run/netdata.pid 2>/dev/null)
318 + # backwards compatibility
319 + [ -z "${pid}" ] && pid=$(cat /var/run/netdata/netdata.pid 2>/dev/null)
320 +
321 isnetdata $pid || pid=
322 if [ ! -z "${pid}" ]
323 then
src/main.c
+2 -2
@@ -441,9 +441,9 @@ int main(int argc, char **argv)
441 else if(!strcmp(ipv, "ipv6") || !strcmp(ipv, "IPV6") || !strcmp(ipv, "IPv6") || !strcmp(ipv, "6")) ip = 6;
442 else fprintf(stderr, "Cannot understand ip version '%s'. Assumming 'any'.", ipv);
443
444 - if(ip == 0 || ip == 6) listen_fd = create_listen_socket6(listen_port, listen_backlog);
444 + if(ip == 0 || ip == 6) listen_fd = create_listen_socket6(config_get("global", "bind socket to IP", "*"), listen_port, listen_backlog);
445 if(listen_fd < 0) {
446 - listen_fd = create_listen_socket4(listen_port, listen_backlog);
446 + listen_fd = create_listen_socket4(config_get("global", "bind socket to IP", "*"), listen_port, listen_backlog);
447 if(listen_fd >= 0 && ip != 4) fprintf(stderr, "Managed to open an IPv4 socket on port %d.", listen_port);
448 }
449
src/web_server.c
+91 -51
@@ -49,81 +49,121 @@ static void log_allocations(void)
49 }
50 #endif
51
52 -int create_listen_socket4(int port, int listen_backlog)
52 +static int is_ip_anything(const char *ip)
53 {
54 - int sock;
55 - int sockopt = 1;
56 - struct sockaddr_in name;
54 + if(!ip || !*ip
55 + || !strcmp(ip, "any")
56 + || !strcmp(ip, "all")
57 + || !strcmp(ip, "*")
58 + || !strcmp(ip, "::")
59 + || !strcmp(ip, "0.0.0.0")
60 + ) return 1;
61 +
62 + return 0;
63 +}
64
58 - debug(D_LISTENER, "IPv4 creating new listening socket on port %d", port);
65 +int create_listen_socket4(const char *ip, int port, int listen_backlog)
66 +{
67 + int sock;
68 + int sockopt = 1;
69 + struct sockaddr_in name;
70
60 - sock = socket(AF_INET, SOCK_STREAM, 0);
61 - if(sock < 0) {
62 - error("IPv4 socket() failed.");
63 - return -1;
64 - }
71 + debug(D_LISTENER, "IPv4 creating new listening socket on port %d", port);
72
66 - /* avoid "address already in use" */
67 - setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*)&sockopt, sizeof(sockopt));
73 + sock = socket(AF_INET, SOCK_STREAM, 0);
74 + if(sock < 0) {
75 + error("IPv4 socket() failed.");
76 + return -1;
77 + }
78
69 - memset(&name, 0, sizeof(struct sockaddr_in));
70 - name.sin_family = AF_INET;
71 - name.sin_port = htons (port);
72 - name.sin_addr.s_addr = htonl (INADDR_ANY);
79 + /* avoid "address already in use" */
80 + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*)&sockopt, sizeof(sockopt));
81
74 - if(bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0) {
75 - close(sock);
76 - error("IPv4 bind() failed.");
77 - return -1;
78 - }
82 + memset(&name, 0, sizeof(struct sockaddr_in));
83 + name.sin_family = AF_INET;
84 + name.sin_port = htons (port);
85
80 - if(listen(sock, listen_backlog) < 0) {
86 + if(is_ip_anything(ip)) {
87 + name.sin_addr.s_addr = htonl(INADDR_ANY);
88 + info("Listening on any IPs (IPv4).");
89 + }
90 + else {
91 + int ret = inet_pton(AF_INET, ip, (void *)&name.sin_addr.s_addr);
92 + if(ret != 1) {
93 + error("Failed to convert IP '%s' to a valid IPv4 address.", ip);
94 close(sock);
82 - fatal("IPv4 listen() failed.");
95 return -1;
96 }
97 + info("Listening on IP '%s' (IPv4).", ip);
98 + }
99 +
100 + if(bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0) {
101 + close(sock);
102 + error("IPv4 bind() failed.");
103 + return -1;
104 + }
105 +
106 + if(listen(sock, listen_backlog) < 0) {
107 + close(sock);
108 + fatal("IPv4 listen() failed.");
109 + return -1;
110 + }
111
86 - debug(D_LISTENER, "IPv4 listening port %d created", port);
87 - return sock;
112 + debug(D_LISTENER, "IPv4 listening port %d created", port);
113 + return sock;
114 }
115
90 -int create_listen_socket6(int port, int listen_backlog)
116 +int create_listen_socket6(const char *ip, int port, int listen_backlog)
117 {
92 - int sock = -1;
93 - int sockopt = 1;
94 - struct sockaddr_in6 name;
118 + int sock = -1;
119 + int sockopt = 1;
120 + struct sockaddr_in6 name;
121
96 - debug(D_LISTENER, "IPv6 creating new listening socket on port %d", port);
122 + debug(D_LISTENER, "IPv6 creating new listening socket on port %d", port);
123
98 - sock = socket(AF_INET6, SOCK_STREAM, 0);
99 - if (sock < 0) {
100 - error("IPv6 socket() failed.");
101 - return -1;
102 - }
124 + sock = socket(AF_INET6, SOCK_STREAM, 0);
125 + if (sock < 0) {
126 + error("IPv6 socket() failed. Disabling IPv6.");
127 + return -1;
128 + }
129
104 - /* avoid "address already in use" */
105 - setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*)&sockopt, sizeof(sockopt));
130 + /* avoid "address already in use" */
131 + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*)&sockopt, sizeof(sockopt));
132
107 - memset(&name, 0, sizeof(struct sockaddr_in6));
108 - name.sin6_family = AF_INET6;
109 - name.sin6_port = htons ((uint16_t) port);
110 - name.sin6_addr = in6addr_any;
111 - name.sin6_scope_id = 0;
133 + memset(&name, 0, sizeof(struct sockaddr_in6));
134 + name.sin6_family = AF_INET6;
135 + name.sin6_port = htons ((uint16_t) port);
136
113 - if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0) {
137 + if(is_ip_anything(ip)) {
138 + name.sin6_addr = in6addr_any;
139 + info("Listening on all IPs (IPv6 and IPv4)");
140 + }
141 + else {
142 + int ret = inet_pton(AF_INET6, ip, (void *)&name.sin6_addr.s6_addr);
143 + if(ret != 1) {
144 + error("Failed to convert IP '%s' to a valid IPv6 address. Disabling IPv6.", ip);
145 close(sock);
115 - error("IPv6 bind() failed.");
146 return -1;
147 }
148 + info("Listening on IP '%s' (IPv6)", ip);
149 + }
150
119 - if (listen(sock, listen_backlog) < 0) {
120 - close(sock);
121 - fatal("IPv6 listen() failed.");
122 - return -1;
123 - }
151 + name.sin6_scope_id = 0;
152 +
153 + if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0) {
154 + close(sock);
155 + error("IPv6 bind() failed. Disabling IPv6.");
156 + return -1;
157 + }
158 +
159 + if (listen(sock, listen_backlog) < 0) {
160 + close(sock);
161 + error("IPv6 listen() failed. Disabling IPv6.");
162 + return -1;
163 + }
164
125 - debug(D_LISTENER, "IPv6 listening port %d created", port);
126 - return sock;
165 + debug(D_LISTENER, "IPv6 listening port %d created", port);
166 + return sock;
167 }
168
169
src/web_server.h
+2 -2
@@ -13,8 +13,8 @@ extern int listen_backlog;
13 extern int listen_fd;
14 extern int listen_port;
15
16 -extern int create_listen_socket4(int port, int listen_backlog);
17 -extern int create_listen_socket6(int port, int listen_backlog);
16 +extern int create_listen_socket4(const char *ip, int port, int listen_backlog);
17 +extern int create_listen_socket6(const char *ip, int port, int listen_backlog);
18 extern void *socket_listen_main(void *ptr);
19
20 #endif /* NETDATA_WEB_SERVER_H */