@cryptotaxi247 / netdata-1 / commits / e313e0d5a

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);