fixed dead clients logging; added protection against invalid file descriptors in select()
Costa Tsaousis committed
May 29, 2016 at 13:51 UTC
e313e0d5a50476cfa5c68aad2fe3bc414d6bab6b
3 files changed
+37
-22
src/web_client.c
+23
-20
@@ -149,12 +149,16 @@ void web_client_reset(struct web_client *w)
149
debug(D_WEB_CLIENT, "%llu: Reseting client.", w->id);
150
151
if(w->stats_received_bytes || w->stats_sent_bytes) {
152
- global_statistics_lock();
152
+ if(web_server_mode == WEB_SERVER_MODE_MULTI_THREADED)
153
+ global_statistics_lock();
154
+
155
global_statistics.web_requests++;
156
global_statistics.web_usec += usecdiff(&tv, &w->tv_in);
157
global_statistics.bytes_received += w->stats_received_bytes;
158
global_statistics.bytes_sent += w->stats_sent_bytes;
157
- global_statistics_unlock();
159
+
160
+ if(web_server_mode == WEB_SERVER_MODE_MULTI_THREADED)
161
+ global_statistics_unlock();
162
}
163
w->stats_received_bytes = 0;
164
w->stats_sent_bytes = 0;
@@ -1882,10 +1886,10 @@ ssize_t web_client_send_deflate(struct web_client *w)
1886
return t;
1887
}
1888
1885
- if(unlikely(w->keepalive == 0)) {
1889
+ if(unlikely(!w->keepalive)) {
1890
debug(D_WEB_CLIENT, "%llu: Closing (keep-alive is not enabled). %ld bytes sent.", w->id, w->response.sent);
1887
- errno = 0;
1888
- return(-1);
1891
+ WEB_CLIENT_IS_DEAD(w);
1892
+ return t;
1893
}
1894
1895
// reset the client
@@ -1989,18 +1993,18 @@ ssize_t web_client_send(struct web_client *w) {
1993
// we have to wait, more data will come
1994
debug(D_WEB_CLIENT, "%llu: Waiting for more data to become available.", w->id);
1995
w->wait_send = 0;
1992
- return(0);
1996
+ return 0;
1997
}
1998
1995
- if(unlikely(w->keepalive == 0)) {
1999
+ if(unlikely(!w->keepalive)) {
2000
debug(D_WEB_CLIENT, "%llu: Closing (keep-alive is not enabled). %ld bytes sent.", w->id, w->response.sent);
1997
- errno = 0;
1998
- return(-1);
2001
+ WEB_CLIENT_IS_DEAD(w);
2002
+ return 0;
2003
}
2004
2005
web_client_reset(w);
2006
debug(D_WEB_CLIENT, "%llu: Done sending all data on socket. Waiting for next request on the same socket.", w->id);
2003
- return(0);
2007
+ return 0;
2008
}
2009
2010
bytes = send(w->ofd, &w->response.data->buffer[w->response.sent], w->response.data->len - w->response.sent, MSG_DONTWAIT);
@@ -2107,7 +2111,7 @@ void *web_client_main(void *ptr)
2111
2112
for(;;) {
2113
if(unlikely(w->dead)) {
2110
- error("%llu: client is dead.");
2114
+ error("%llu: client is dead.", w->id);
2115
break;
2116
}
2117
else if(unlikely(!w->wait_receive && !w->wait_send)) {
@@ -2119,6 +2123,11 @@ void *web_client_main(void *ptr)
2123
FD_ZERO (&ofds);
2124
FD_ZERO (&efds);
2125
2126
+ if(w->ifd < 0 || w->ifd >= FD_SETSIZE || w->ofd < 0 || w->ofd >= FD_SETSIZE) {
2127
+ error("%llu: invalid file descriptor, ifd = %d, ofd = %d (required 0 <= fd < FD_SETSIZE (%d)", w->id, w->ifd, w->ofd, FD_SETSIZE);
2128
+ break;
2129
+ }
2130
+
2131
FD_SET(w->ifd, &efds);
2132
2133
if(w->ifd != w->ofd)
@@ -2159,28 +2168,22 @@ void *web_client_main(void *ptr)
2168
}
2169
2170
if(w->wait_send && FD_ISSET(w->ofd, &ofds)) {
2162
- ssize_t bytes;
2163
- if((bytes = web_client_send(w)) < 0) {
2171
+ if(web_client_send(w) < 0) {
2172
debug(D_WEB_CLIENT, "%llu: Cannot send data to client. Closing client.", w->id);
2165
- errno = 0;
2173
break;
2174
}
2175
}
2176
2177
if(w->wait_receive && FD_ISSET(w->ifd, &ifds)) {
2171
- ssize_t bytes;
2172
- if((bytes = web_client_receive(w)) < 0) {
2178
+ if(web_client_receive(w) < 0) {
2179
debug(D_WEB_CLIENT, "%llu: Cannot receive data from client. Closing client.", w->id);
2174
- errno = 0;
2180
break;
2181
}
2182
2183
if(w->mode == WEB_CLIENT_MODE_NORMAL) {
2179
- debug(D_WEB_CLIENT, "%llu: Attempting to process received data (%ld bytes).", w->id, bytes);
2180
- // info("%llu: Attempting to process received data (%ld bytes).", w->id, bytes);
2184
+ debug(D_WEB_CLIENT, "%llu: Attempting to process received data.", w->id);
2185
web_client_process(w);
2186
}
2183
-
2187
}
2188
}
2189
src/web_server.c
+10
-2
@@ -27,9 +27,9 @@
27
#include "../config.h"
28
29
int listen_backlog = LISTEN_BACKLOG;
30
-
30
int listen_fd = -1;
31
int listen_port = LISTEN_PORT;
32
+int web_server_mode = WEB_SERVER_MODE_MULTI_THREADED;
33
34
#ifdef NETDATA_INTERNAL_CHECKS
35
static void log_allocations(void)
@@ -205,6 +205,7 @@ int create_listen_socket(void) {
205
void *socket_listen_main_multi_threaded(void *ptr) {
206
if(ptr) { ; }
207
208
+ web_server_mode = WEB_SERVER_MODE_MULTI_THREADED;
209
info("Multi-threaded WEB SERVER thread created with task id %d", gettid());
210
211
struct web_client *w;
@@ -308,6 +309,8 @@ void *socket_listen_main_multi_threaded(void *ptr) {
309
void *socket_listen_main_single_threaded(void *ptr) {
310
if(ptr) { ; }
311
312
+ web_server_mode = WEB_SERVER_MODE_SINGLE_THREADED;
313
+
314
info("Single threaded WEB SERVER thread created with task id %d", gettid());
315
316
struct web_client *w;
@@ -343,7 +346,7 @@ void *socket_listen_main_single_threaded(void *ptr) {
346
347
for(w = web_clients; w ; w = w->next) {
348
if(unlikely(w->dead)) {
346
- error("%llu: client is dead.");
349
+ error("%llu: client is dead.", w->id);
350
w->obsolete = 1;
351
}
352
else if(unlikely(!w->wait_receive && !w->wait_send)) {
@@ -351,6 +354,11 @@ void *socket_listen_main_single_threaded(void *ptr) {
354
w->obsolete = 1;
355
}
356
357
+ if(w->ifd < 0 || w->ifd >= FD_SETSIZE || w->ofd < 0 || w->ofd >= FD_SETSIZE) {
358
+ error("%llu: invalid file descriptor, ifd = %d, ofd = %d (required 0 <= fd < FD_SETSIZE (%d)", w->id, w->ifd, w->ofd, FD_SETSIZE);
359
+ w->obsolete = 1;
360
+ }
361
+
362
if(unlikely(w->obsolete)) {
363
has_obsolete++;
364
continue;
src/web_server.h
+4
@@ -13,6 +13,10 @@ extern int listen_backlog;
13
extern int listen_fd;
14
extern int listen_port;
15
16
+#define WEB_SERVER_MODE_MULTI_THREADED 0
17
+#define WEB_SERVER_MODE_SINGLE_THREADED 1
18
+extern int web_server_mode;
19
+
20
extern int create_listen_socket4(const char *ip, int port, int listen_backlog);
21
extern int create_listen_socket6(const char *ip, int port, int listen_backlog);
22
extern void *socket_listen_main_multi_threaded(void *ptr);