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 */