generic sockets listening functions supporting multiple sets of both TCP and UDP sockets (for later use)
Costa Tsaousis (ktsaou) committed
Apr 23, 2017 at 03:32 UTC
72c91ac89a6af39a2f866fee185cfe9b9c94329b
4 files changed
+251
-191
src/main.c
+1
-1
@@ -920,7 +920,7 @@ int main(int argc, char **argv) {
920
web_server_threading_selection();
921
922
if(web_server_mode != WEB_SERVER_MODE_NONE)
923
- create_listen_sockets();
923
+ create_api_listen_sockets();
924
}
925
926
// initialize the log files
src/socket.c
+117
-102
@@ -1,5 +1,121 @@
1
#include "common.h"
2
3
+// _connect_to()
4
+// protocol IPPROTO_TCP, IPPROTO_UDP
5
+// socktype SOCK_STREAM, SOCK_DGRAM
6
+// host the destination hostname or IP address (IPv4 or IPv6) to connect to
7
+// if it resolves to many IPs, all are tried (IPv4 and IPv6)
8
+// scope_id the if_index id of the interface to use for connecting (0 = any)
9
+// (used only under IPv6)
10
+// service the service name or port to connect to
11
+// timeout the timeout for establishing a connection
12
+
13
+static inline int _connect_to(int protocol, int socktype, const char *host, uint32_t scope_id, const char *service, struct timeval *timeout) {
14
+ struct addrinfo hints;
15
+ struct addrinfo *ai_head = NULL, *ai = NULL;
16
+
17
+ memset(&hints, 0, sizeof(hints));
18
+ hints.ai_family = PF_UNSPEC; /* Allow IPv4 or IPv6 */
19
+ hints.ai_socktype = socktype;
20
+ hints.ai_protocol = protocol;
21
+
22
+ int ai_err = getaddrinfo(host, service, &hints, &ai_head);
23
+ if (ai_err != 0) {
24
+ error("Cannot resolve host '%s', port '%s': %s", host, service, gai_strerror(ai_err));
25
+ return -1;
26
+ }
27
+
28
+ int fd = -1;
29
+ for (ai = ai_head; ai != NULL && fd == -1; ai = ai->ai_next) {
30
+
31
+ if (ai->ai_family == PF_INET6) {
32
+ struct sockaddr_in6 *pSadrIn6 = (struct sockaddr_in6 *) ai->ai_addr;
33
+ if(pSadrIn6->sin6_scope_id == 0) {
34
+ pSadrIn6->sin6_scope_id = scope_id;
35
+ }
36
+ }
37
+
38
+ char hostBfr[NI_MAXHOST + 1];
39
+ char servBfr[NI_MAXSERV + 1];
40
+
41
+ getnameinfo(ai->ai_addr,
42
+ ai->ai_addrlen,
43
+ hostBfr,
44
+ sizeof(hostBfr),
45
+ servBfr,
46
+ sizeof(servBfr),
47
+ NI_NUMERICHOST | NI_NUMERICSERV);
48
+
49
+ debug(D_CONNECT_TO, "Address info: host = '%s', service = '%s', ai_flags = 0x%02X, ai_family = %d (PF_INET = %d, PF_INET6 = %d), ai_socktype = %d (SOCK_STREAM = %d, SOCK_DGRAM = %d), ai_protocol = %d (IPPROTO_TCP = %d, IPPROTO_UDP = %d), ai_addrlen = %lu (sockaddr_in = %lu, sockaddr_in6 = %lu)",
50
+ hostBfr,
51
+ servBfr,
52
+ (unsigned int)ai->ai_flags,
53
+ ai->ai_family,
54
+ PF_INET,
55
+ PF_INET6,
56
+ ai->ai_socktype,
57
+ SOCK_STREAM,
58
+ SOCK_DGRAM,
59
+ ai->ai_protocol,
60
+ IPPROTO_TCP,
61
+ IPPROTO_UDP,
62
+ (unsigned long)ai->ai_addrlen,
63
+ (unsigned long)sizeof(struct sockaddr_in),
64
+ (unsigned long)sizeof(struct sockaddr_in6));
65
+
66
+ switch (ai->ai_addr->sa_family) {
67
+ case PF_INET: {
68
+ struct sockaddr_in *pSadrIn = (struct sockaddr_in *)ai->ai_addr;
69
+ debug(D_CONNECT_TO, "ai_addr = sin_family: %d (AF_INET = %d, AF_INET6 = %d), sin_addr: '%s', sin_port: '%s'",
70
+ pSadrIn->sin_family,
71
+ AF_INET,
72
+ AF_INET6,
73
+ hostBfr,
74
+ servBfr);
75
+ break;
76
+ }
77
+
78
+ case PF_INET6: {
79
+ struct sockaddr_in6 *pSadrIn6 = (struct sockaddr_in6 *) ai->ai_addr;
80
+ debug(D_CONNECT_TO,"ai_addr = sin6_family: %d (AF_INET = %d, AF_INET6 = %d), sin6_addr: '%s', sin6_port: '%s', sin6_flowinfo: %u, sin6_scope_id: %u",
81
+ pSadrIn6->sin6_family,
82
+ AF_INET,
83
+ AF_INET6,
84
+ hostBfr,
85
+ servBfr,
86
+ pSadrIn6->sin6_flowinfo,
87
+ pSadrIn6->sin6_scope_id);
88
+ break;
89
+ }
90
+
91
+ default: {
92
+ debug(D_CONNECT_TO, "Unknown protocol family %d.", ai->ai_family);
93
+ continue;
94
+ }
95
+ }
96
+
97
+ fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
98
+ if(fd != -1) {
99
+ if(timeout) {
100
+ if(setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char *) timeout, sizeof(struct timeval)) < 0)
101
+ error("Failed to set timeout on the socket to ip '%s' port '%s'", hostBfr, servBfr);
102
+ }
103
+
104
+ if(connect(fd, ai->ai_addr, ai->ai_addrlen) < 0) {
105
+ error("Failed to connect to '%s', port '%s'", hostBfr, servBfr);
106
+ close(fd);
107
+ fd = -1;
108
+ }
109
+
110
+ debug(D_CONNECT_TO, "Connected to '%s' on port '%s'.", hostBfr, servBfr);
111
+ }
112
+ }
113
+
114
+ freeaddrinfo(ai_head);
115
+
116
+ return fd;
117
+}
118
+
119
// connect_to()
120
//
121
// definition format:
@@ -12,9 +128,6 @@
128
// PORT = port number or service name
129
130
int connect_to(const char *definition, int default_port, struct timeval *timeout) {
15
- struct addrinfo hints;
16
- struct addrinfo *ai_head = NULL, *ai = NULL;
17
-
131
char buffer[strlen(definition) + 1];
132
strcpy(buffer, definition);
133
@@ -78,106 +191,8 @@ int connect_to(const char *definition, int default_port, struct timeval *timeout
191
if(!*service)
192
service = default_service;
193
81
- memset(&hints, 0, sizeof(hints));
82
- hints.ai_family = PF_UNSPEC; /* Allow IPv4 or IPv6 */
83
- hints.ai_socktype = socktype;
84
- hints.ai_protocol = protocol;
85
-
86
- int ai_err = getaddrinfo(host, service, &hints, &ai_head);
87
- if (ai_err != 0) {
88
- error("Cannot resolve host '%s', port '%s': %s", host, service, gai_strerror(ai_err));
89
- return -1;
90
- }
91
-
92
- int fd = -1;
93
- for (ai = ai_head; ai != NULL && fd == -1; ai = ai->ai_next) {
94
-
95
- if (ai->ai_family == PF_INET6) {
96
- struct sockaddr_in6 *pSadrIn6 = (struct sockaddr_in6 *) ai->ai_addr;
97
- if(pSadrIn6->sin6_scope_id == 0) {
98
- pSadrIn6->sin6_scope_id = scope_id;
99
- }
100
- }
101
-
102
- char hostBfr[NI_MAXHOST + 1];
103
- char servBfr[NI_MAXSERV + 1];
104
-
105
- getnameinfo(ai->ai_addr,
106
- ai->ai_addrlen,
107
- hostBfr,
108
- sizeof(hostBfr),
109
- servBfr,
110
- sizeof(servBfr),
111
- NI_NUMERICHOST | NI_NUMERICSERV);
112
-
113
- debug(D_CONNECT_TO, "Address info: host = '%s', service = '%s', ai_flags = 0x%02X, ai_family = %d (PF_INET = %d, PF_INET6 = %d), ai_socktype = %d (SOCK_STREAM = %d, SOCK_DGRAM = %d), ai_protocol = %d (IPPROTO_TCP = %d, IPPROTO_UDP = %d), ai_addrlen = %lu (sockaddr_in = %lu, sockaddr_in6 = %lu)",
114
- hostBfr,
115
- servBfr,
116
- (unsigned int)ai->ai_flags,
117
- ai->ai_family,
118
- PF_INET,
119
- PF_INET6,
120
- ai->ai_socktype,
121
- SOCK_STREAM,
122
- SOCK_DGRAM,
123
- ai->ai_protocol,
124
- IPPROTO_TCP,
125
- IPPROTO_UDP,
126
- (unsigned long)ai->ai_addrlen,
127
- (unsigned long)sizeof(struct sockaddr_in),
128
- (unsigned long)sizeof(struct sockaddr_in6));
129
-
130
- switch (ai->ai_addr->sa_family) {
131
- case PF_INET: {
132
- struct sockaddr_in *pSadrIn = (struct sockaddr_in *)ai->ai_addr;
133
- debug(D_CONNECT_TO, "ai_addr = sin_family: %d (AF_INET = %d, AF_INET6 = %d), sin_addr: '%s', sin_port: '%s'",
134
- pSadrIn->sin_family,
135
- AF_INET,
136
- AF_INET6,
137
- hostBfr,
138
- servBfr);
139
- break;
140
- }
141
-
142
- case PF_INET6: {
143
- struct sockaddr_in6 *pSadrIn6 = (struct sockaddr_in6 *) ai->ai_addr;
144
- debug(D_CONNECT_TO,"ai_addr = sin6_family: %d (AF_INET = %d, AF_INET6 = %d), sin6_addr: '%s', sin6_port: '%s', sin6_flowinfo: %u, sin6_scope_id: %u",
145
- pSadrIn6->sin6_family,
146
- AF_INET,
147
- AF_INET6,
148
- hostBfr,
149
- servBfr,
150
- pSadrIn6->sin6_flowinfo,
151
- pSadrIn6->sin6_scope_id);
152
- break;
153
- }
154
-
155
- default: {
156
- debug(D_CONNECT_TO, "Unknown protocol family %d.", ai->ai_family);
157
- continue;
158
- }
159
- }
194
161
- fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
162
- if(fd != -1) {
163
- if(timeout) {
164
- if(setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char *) timeout, sizeof(struct timeval)) < 0)
165
- error("Failed to set timeout on the socket to ip '%s' port '%s'", hostBfr, servBfr);
166
- }
167
-
168
- if(connect(fd, ai->ai_addr, ai->ai_addrlen) < 0) {
169
- error("Failed to connect to '%s', port '%s'", hostBfr, servBfr);
170
- close(fd);
171
- fd = -1;
172
- }
173
-
174
- debug(D_CONNECT_TO, "Connected to '%s' on port '%s'.", hostBfr, servBfr);
175
- }
176
- }
177
-
178
- freeaddrinfo(ai_head);
179
-
180
- return fd;
195
+ return _connect_to(protocol, socktype, host, scope_id, service, timeout);
196
}
197
198
int connect_to_one_of(const char *destination, int default_port, struct timeval *timeout, size_t *reconnects_counter, char *connected_to, size_t connected_to_size) {
src/web_server.c
+132
-86
@@ -1,15 +1,29 @@
1
#include "common.h"
2
3
-int listen_backlog = LISTEN_BACKLOG;
4
-size_t listen_fds_count = 0;
5
-int listen_fds[MAX_LISTEN_FDS] = { [0 ... 99] = -1 };
6
-char *listen_fds_names[MAX_LISTEN_FDS] = { [0 ... 99] = NULL };
7
-int listen_port = LISTEN_PORT;
3
+typedef struct listen_sockets {
4
+ const char *config_section;
5
+ size_t opened;
6
+ size_t failed;
7
+ int fds[MAX_LISTEN_FDS];
8
+ char *fds_names[MAX_LISTEN_FDS];
9
+ int default_port;
10
+ int backlog;
11
+ uint32_t flags;
12
+} LISTEN_SOCKETS;
13
+
14
+static LISTEN_SOCKETS api_sockets = {
15
+ .config_section = CONFIG_SECTION_WEB,
16
+ .opened = 0,
17
+ .failed = 0,
18
+ .fds = { [0 ... 99] = -1 },
19
+ .fds_names = { [0 ... 99] = NULL },
20
+ .default_port = LISTEN_PORT,
21
+ .backlog = LISTEN_BACKLOG,
22
+ .flags = 0
23
+};
24
25
WEB_SERVER_MODE web_server_mode = WEB_SERVER_MODE_MULTI_THREADED;
26
11
-static int shown_server_socket_error = 0;
12
-
27
#ifdef NETDATA_INTERNAL_CHECKS
28
static void log_allocations(void)
29
{
@@ -107,16 +121,15 @@ const char *web_server_mode_name(WEB_SERVER_MODE id) {
121
}
122
}
123
110
-int create_listen_socket4(const char *ip, int port, int listen_backlog) {
124
+int create_listen_socket4(int socktype, const char *ip, int port, int listen_backlog) {
125
int sock;
126
int sockopt = 1;
127
128
debug(D_LISTENER, "IPv4 creating new listening socket on ip '%s' port %d", ip, port);
129
116
- sock = socket(AF_INET, SOCK_STREAM, 0);
130
+ sock = socket(AF_INET, socktype, 0);
131
if(sock < 0) {
132
error("IPv4 socket() on ip '%s' port %d failed.", ip, port);
119
- shown_server_socket_error = 1;
133
return -1;
134
}
135
@@ -132,7 +145,6 @@ int create_listen_socket4(const char *ip, int port, int listen_backlog) {
145
int ret = inet_pton(AF_INET, ip, (void *)&name.sin_addr.s_addr);
146
if(ret != 1) {
147
error("Failed to convert IP '%s' to a valid IPv4 address.", ip);
135
- shown_server_socket_error = 1;
148
close(sock);
149
return -1;
150
}
@@ -140,14 +152,12 @@ int create_listen_socket4(const char *ip, int port, int listen_backlog) {
152
if(bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0) {
153
close(sock);
154
error("IPv4 bind() on ip '%s' port %d failed.", ip, port);
143
- shown_server_socket_error = 1;
155
return -1;
156
}
157
158
if(listen(sock, listen_backlog) < 0) {
159
close(sock);
160
error("IPv4 listen() on ip '%s' port %d failed.", ip, port);
150
- shown_server_socket_error = 1;
161
return -1;
162
}
163
@@ -155,17 +165,16 @@ int create_listen_socket4(const char *ip, int port, int listen_backlog) {
165
return sock;
166
}
167
158
-int create_listen_socket6(const char *ip, int port, int listen_backlog) {
168
+int create_listen_socket6(int socktype, uint32_t scope_id, const char *ip, int port, int listen_backlog) {
169
int sock = -1;
170
int sockopt = 1;
171
int ipv6only = 1;
172
173
debug(D_LISTENER, "IPv6 creating new listening socket on ip '%s' port %d", ip, port);
174
165
- sock = socket(AF_INET6, SOCK_STREAM, 0);
175
+ sock = socket(AF_INET6, socktype, 0);
176
if (sock < 0) {
177
error("IPv6 socket() on ip '%s' port %d failed.", ip, port);
168
- shown_server_socket_error = 1;
178
return -1;
179
}
180
@@ -181,28 +190,26 @@ int create_listen_socket6(const char *ip, int port, int listen_backlog) {
190
memset(&name, 0, sizeof(struct sockaddr_in6));
191
name.sin6_family = AF_INET6;
192
name.sin6_port = htons ((uint16_t) port);
193
+ name.sin6_scope_id = scope_id;
194
195
int ret = inet_pton(AF_INET6, ip, (void *)&name.sin6_addr.s6_addr);
196
if(ret != 1) {
197
error("Failed to convert IP '%s' to a valid IPv6 address.", ip);
188
- shown_server_socket_error = 1;
198
close(sock);
199
return -1;
200
}
201
193
- name.sin6_scope_id = 0;
202
+ name.sin6_scope_id = scope_id;
203
204
if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0) {
205
close(sock);
206
error("IPv6 bind() on ip '%s' port %d failed.", ip, port);
198
- shown_server_socket_error = 1;
207
return -1;
208
}
209
210
if (listen(sock, listen_backlog) < 0) {
211
close(sock);
212
error("IPv6 listen() on ip '%s' port %d failed.", ip, port);
205
- shown_server_socket_error = 1;
213
return -1;
214
}
215
@@ -210,46 +217,45 @@ int create_listen_socket6(const char *ip, int port, int listen_backlog) {
217
return sock;
218
}
219
213
-static inline int add_listen_socket(int fd, const char *ip, int port) {
214
- if(listen_fds_count >= MAX_LISTEN_FDS) {
215
- error("Too many listening sockets. Failed to add listening socket at ip '%s' port %d", ip, port);
216
- shown_server_socket_error = 1;
220
+static inline int add_listen_socket(LISTEN_SOCKETS *sockets, int fd, const char *protocol, const char *ip, int port) {
221
+ if(sockets->opened >= MAX_LISTEN_FDS) {
222
+ error("Too many listening sockets. Failed to add listening %s socket at ip '%s' port %d", protocol, ip, port);
223
close(fd);
224
return -1;
225
}
226
221
- listen_fds[listen_fds_count] = fd;
227
+ sockets->fds[sockets->opened] = fd;
228
229
char buffer[100 + 1];
224
- snprintfz(buffer, 100, "[%s]:%d", ip, port);
225
- listen_fds_names[listen_fds_count] = strdupz(buffer);
230
+ snprintfz(buffer, 100, "%s:[%s]:%d", protocol, ip, port);
231
+ sockets->fds_names[sockets->opened] = strdupz(buffer);
232
227
- listen_fds_count++;
233
+ sockets->opened++;
234
return 0;
235
}
236
231
-int is_listen_socket(int fd) {
237
+int is_listen_socket(LISTEN_SOCKETS *sockets, int fd) {
238
size_t i;
233
- for(i = 0; i < listen_fds_count ;i++)
234
- if(listen_fds[i] == fd) return 1;
239
+ for(i = 0; i < sockets->opened ;i++)
240
+ if(sockets->fds[i] == fd) return 1;
241
242
return 0;
243
}
244
239
-static inline void close_listen_sockets(void) {
245
+static inline void close_listen_sockets(LISTEN_SOCKETS *sockets) {
246
size_t i;
241
- for(i = 0; i < listen_fds_count ;i++) {
242
- close(listen_fds[i]);
243
- listen_fds[i] = -1;
247
+ for(i = 0; i < sockets->opened ;i++) {
248
+ close(sockets->fds[i]);
249
+ sockets->fds[i] = -1;
250
245
- freez(listen_fds_names[i]);
246
- listen_fds_names[i] = NULL;
251
+ freez(sockets->fds_names[i]);
252
+ sockets->fds_names[i] = NULL;
253
}
254
249
- listen_fds_count = 0;
255
+ sockets->opened = 0;
256
}
257
252
-static inline int bind_to_one(const char *definition, int default_port, int listen_backlog) {
258
+static inline int bind_to_one(LISTEN_SOCKETS *sockets, const char *definition, int default_port, int listen_backlog) {
259
int added = 0;
260
struct addrinfo hints;
261
struct addrinfo *result = NULL, *rp = NULL;
@@ -260,7 +266,23 @@ static inline int bind_to_one(const char *definition, int default_port, int list
266
char buffer2[10 + 1];
267
snprintfz(buffer2, 10, "%d", default_port);
268
263
- char *ip = buffer, *port = buffer2;
269
+ char *ip = buffer, *port = buffer2, *interface = "";;
270
+
271
+ int protocol = IPPROTO_TCP, socktype = SOCK_STREAM;
272
+ const char *protocol_str = "tcp";
273
+
274
+ if(strncmp(ip, "tcp:", 4) == 0) {
275
+ ip += 4;
276
+ protocol = IPPROTO_TCP;
277
+ socktype = SOCK_STREAM;
278
+ protocol_str = "tcp";
279
+ }
280
+ else if(strncmp(ip, "udp:", 4) == 0) {
281
+ ip += 4;
282
+ protocol = IPPROTO_UDP;
283
+ socktype = SOCK_DGRAM;
284
+ protocol_str = "udp";
285
+ }
286
287
char *e = ip;
288
if(*e == '[') {
@@ -272,6 +294,13 @@ static inline int bind_to_one(const char *definition, int default_port, int list
294
}
295
}
296
else {
297
+ while(*e && *e != ':' && *e != '%') e++;
298
+ }
299
+
300
+ if(*e == '%') {
301
+ *e = '\0';
302
+ e++;
303
+ interface = e;
304
while(*e && *e != ':') e++;
305
}
306
@@ -280,16 +309,24 @@ static inline int bind_to_one(const char *definition, int default_port, int list
309
*e = '\0';
310
}
311
312
+ uint32_t scope_id = 0;
313
+ if(*interface) {
314
+ scope_id = if_nametoindex(interface);
315
+ if(!scope_id)
316
+ error("Cannot find a network interface named '%s'. Continuing with limiting the network interface", interface);
317
+ }
318
+
319
if(!*ip || *ip == '*' || !strcmp(ip, "any") || !strcmp(ip, "all"))
320
ip = NULL;
321
+
322
if(!*port)
323
port = buffer2;
324
288
- memset(&hints, 0, sizeof(struct addrinfo));
289
- hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
290
- hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
291
- hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */
292
- hints.ai_protocol = 0; /* Any protocol */
325
+ memset(&hints, 0, sizeof(hints));
326
+ hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
327
+ hints.ai_socktype = socktype;
328
+ hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */
329
+ hints.ai_protocol = protocol;
330
hints.ai_canonname = NULL;
331
hints.ai_addr = NULL;
332
hints.ai_next = NULL;
@@ -311,7 +348,7 @@ static inline int bind_to_one(const char *definition, int default_port, int list
348
struct sockaddr_in *sin = (struct sockaddr_in *) rp->ai_addr;
349
inet_ntop(AF_INET, &sin->sin_addr, rip, INET_ADDRSTRLEN);
350
rport = ntohs(sin->sin_port);
314
- fd = create_listen_socket4(rip, rport, listen_backlog);
351
+ fd = create_listen_socket4(socktype, rip, rport, listen_backlog);
352
break;
353
}
354
@@ -319,15 +356,21 @@ static inline int bind_to_one(const char *definition, int default_port, int list
356
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) rp->ai_addr;
357
inet_ntop(AF_INET6, &sin6->sin6_addr, rip, INET6_ADDRSTRLEN);
358
rport = ntohs(sin6->sin6_port);
322
- fd = create_listen_socket6(rip, rport, listen_backlog);
359
+ fd = create_listen_socket6(socktype, scope_id, rip, rport, listen_backlog);
360
break;
361
}
362
+
363
+ default:
364
+ debug(D_LISTENER, "Unknown socket family %d", rp->ai_addr->sa_family);
365
+ break;
366
}
367
327
- if (fd == -1)
368
+ if (fd == -1) {
369
error("Cannot bind to ip '%s', port %d", rip, rport);
370
+ sockets->failed++;
371
+ }
372
else {
330
- add_listen_socket(fd, rip, rport);
373
+ add_listen_socket(sockets, fd, protocol_str, rip, rport);
374
added++;
375
}
376
}
@@ -337,19 +380,18 @@ static inline int bind_to_one(const char *definition, int default_port, int list
380
return added;
381
}
382
340
-int create_listen_sockets(void) {
341
- shown_server_socket_error = 0;
342
-
343
- listen_backlog = (int) config_get_number(CONFIG_SECTION_WEB, "listen backlog", LISTEN_BACKLOG);
383
+int create_listen_sockets(LISTEN_SOCKETS *sockets) {
384
+ sockets->backlog = (int) config_get_number(sockets->config_section, "listen backlog", LISTEN_BACKLOG);
385
345
- listen_port = (int) config_get_number(CONFIG_SECTION_WEB, "default port", LISTEN_PORT);
346
- if(listen_port < 1 || listen_port > 65535) {
347
- error("Invalid listen port %d given. Defaulting to %d.", listen_port, LISTEN_PORT);
348
- listen_port = (int) config_set_number(CONFIG_SECTION_WEB, "default port", LISTEN_PORT);
386
+ int old_port = sockets->default_port;
387
+ sockets->default_port = (int) config_get_number(sockets->config_section, "default port", sockets->default_port);
388
+ if(sockets->default_port < 1 || sockets->default_port > 65535) {
389
+ error("Invalid listen port %d given. Defaulting to %d.", sockets->default_port, old_port);
390
+ sockets->default_port = (int) config_set_number(sockets->config_section, "default port", old_port);
391
}
350
- debug(D_OPTIONS, "Default listen port set to %d.", listen_port);
392
+ debug(D_OPTIONS, "Default listen port set to %d.", sockets->default_port);
393
352
- char *s = config_get(CONFIG_SECTION_WEB, "bind to", "*");
394
+ char *s = config_get(sockets->config_section, "bind to", "*");
395
while(*s) {
396
char *e = s;
397
@@ -364,20 +406,24 @@ int create_listen_sockets(void) {
406
407
char buf[e - s + 1];
408
strncpyz(buf, s, e - s);
367
- bind_to_one(buf, listen_port, listen_backlog);
409
+ bind_to_one(sockets, buf, sockets->default_port, sockets->backlog);
410
411
s = e;
412
}
413
372
- if(!listen_fds_count)
414
+ if(!sockets->opened)
415
fatal("Cannot listen on any socket. Exiting...");
374
- else if(shown_server_socket_error) {
416
+ else if(sockets->failed) {
417
size_t i;
376
- for(i = 0; i < listen_fds_count ;i++)
377
- info("Listen socket %s opened.", listen_fds_names[i]);
418
+ for(i = 0; i < sockets->opened ;i++)
419
+ info("Listen socket %s opened successfully.", sockets->fds_names[i]);
420
}
421
380
- return (int)listen_fds_count;
422
+ return (int)sockets->opened;
423
+}
424
+
425
+int create_api_listen_sockets(void) {
426
+ return create_listen_sockets(&api_sockets);
427
}
428
429
// --------------------------------------------------------------------------------------
@@ -422,25 +468,25 @@ void *socket_listen_main_multi_threaded(void *ptr) {
468
if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0)
469
error("Cannot set pthread cancel state to ENABLE.");
470
425
- if(!listen_fds_count)
471
+ if(!api_sockets.opened)
472
fatal("LISTENER: No sockets to listen to.");
473
428
- struct pollfd *fds = callocz(sizeof(struct pollfd), listen_fds_count);
474
+ struct pollfd *fds = callocz(sizeof(struct pollfd), api_sockets.opened);
475
476
size_t i;
431
- for(i = 0; i < listen_fds_count ;i++) {
432
- fds[i].fd = listen_fds[i];
477
+ for(i = 0; i < api_sockets.opened ;i++) {
478
+ fds[i].fd = api_sockets.fds[i];
479
fds[i].events = POLLIN;
480
fds[i].revents = 0;
481
436
- info("Listening on '%s'", (listen_fds_names[i])?listen_fds_names[i]:"UNKNOWN");
482
+ info("Listening on '%s'", (api_sockets.fds_names[i])?api_sockets.fds_names[i]:"UNKNOWN");
483
}
484
485
int timeout = 10 * 1000;
486
487
for(;;) {
488
// debug(D_WEB_CLIENT, "LISTENER: Waiting...");
443
- retval = poll(fds, listen_fds_count, timeout);
489
+ retval = poll(fds, api_sockets.opened, timeout);
490
491
if(unlikely(retval == -1)) {
492
error("LISTENER: poll() failed.");
@@ -453,7 +499,7 @@ void *socket_listen_main_multi_threaded(void *ptr) {
499
continue;
500
}
501
456
- for(i = 0 ; i < listen_fds_count ; i++) {
502
+ for(i = 0 ; i < api_sockets.opened ; i++) {
503
short int revents = fds[i].revents;
504
505
// check for new incoming connections
@@ -486,7 +532,7 @@ void *socket_listen_main_multi_threaded(void *ptr) {
532
}
533
534
debug(D_WEB_CLIENT, "LISTENER: exit!");
489
- close_listen_sockets();
535
+ close_listen_sockets(&api_sockets);
536
537
freez(fds);
538
@@ -555,7 +601,7 @@ void *socket_listen_main_single_threaded(void *ptr) {
601
if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0)
602
error("Cannot set pthread cancel state to ENABLE.");
603
558
- if(!listen_fds_count)
604
+ if(!api_sockets.opened)
605
fatal("LISTENER: no listen sockets available.");
606
607
size_t i;
@@ -568,16 +614,16 @@ void *socket_listen_main_single_threaded(void *ptr) {
614
FD_ZERO (&efds);
615
int fdmax = 0;
616
571
- for(i = 0; i < listen_fds_count ; i++) {
572
- if (listen_fds[i] < 0 || listen_fds[i] >= FD_SETSIZE)
573
- fatal("LISTENER: Listen socket %d is not ready, or invalid.", listen_fds[i]);
617
+ for(i = 0; i < api_sockets.opened ; i++) {
618
+ if (api_sockets.fds[i] < 0 || api_sockets.fds[i] >= FD_SETSIZE)
619
+ fatal("LISTENER: Listen socket %d is not ready, or invalid.", api_sockets.fds[i]);
620
575
- info("Listening on '%s'", (listen_fds_names[i])?listen_fds_names[i]:"UNKNOWN");
621
+ info("Listening on '%s'", (api_sockets.fds_names[i])?api_sockets.fds_names[i]:"UNKNOWN");
622
577
- FD_SET(listen_fds[i], &ifds);
578
- FD_SET(listen_fds[i], &efds);
579
- if(fdmax < listen_fds[i])
580
- fdmax = listen_fds[i];
623
+ FD_SET(api_sockets.fds[i], &ifds);
624
+ FD_SET(api_sockets.fds[i], &efds);
625
+ if(fdmax < api_sockets.fds[i])
626
+ fdmax = api_sockets.fds[i];
627
}
628
629
for(;;) {
@@ -596,10 +642,10 @@ void *socket_listen_main_single_threaded(void *ptr) {
642
else if(likely(retval)) {
643
debug(D_WEB_CLIENT_ACCESS, "LISTENER: got something.");
644
599
- for(i = 0; i < listen_fds_count ; i++) {
600
- if (FD_ISSET(listen_fds[i], &rifds)) {
645
+ for(i = 0; i < api_sockets.opened ; i++) {
646
+ if (FD_ISSET(api_sockets.fds[i], &rifds)) {
647
debug(D_WEB_CLIENT_ACCESS, "LISTENER: new connection.");
602
- w = web_client_create(listen_fds[i]);
648
+ w = web_client_create(api_sockets.fds[i]);
649
if (single_threaded_link_client(w, &ifds, &ofds, &ifds, &fdmax) != 0) {
650
web_client_free(w);
651
}
@@ -658,7 +704,7 @@ void *socket_listen_main_single_threaded(void *ptr) {
704
}
705
706
debug(D_WEB_CLIENT, "LISTENER: exit!");
661
- close_listen_sockets();
707
+ close_listen_sockets(&api_sockets);
708
709
static_thread->enabled = 0;
710
pthread_exit(NULL);
src/web_server.h
+1
-2
@@ -27,8 +27,7 @@ extern const char *web_server_mode_name(WEB_SERVER_MODE id);
27
28
extern void *socket_listen_main_multi_threaded(void *ptr);
29
extern void *socket_listen_main_single_threaded(void *ptr);
30
-extern int create_listen_sockets(void);
31
-extern int is_listen_socket(int fd);
30
+extern int create_api_listen_sockets(void);
31
32
#ifndef HAVE_ACCEPT4
33
extern int accept4(int sock, struct sockaddr *addr, socklen_t *addrlen, int flags);