summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorCosta Tsaousis <costa@tsaousis.gr>2018-07-08 02:45:19 +0300
committerGitHub <noreply@github.com>2018-07-08 02:45:19 +0300
commit723651c4fdac9e38c7f4a2f4ceb8d4e2920e81b6 (patch)
treedd69c9dc065e5ce16ddfe42b2e84bac4382947fb /src
parent3fa750306772e3d5f0b0e43d4c1a764b5ec3f383 (diff)
parent07f25d0ae94c7e4fd1fd8c4463c62d31f6a0be42 (diff)
Merge branch 'master' into ms_team_notification_support
Diffstat (limited to 'src')
-rw-r--r--src/main.c1
-rw-r--r--src/rrdpush.c28
-rw-r--r--src/web_server.c1
-rw-r--r--src/web_server.h1
4 files changed, 31 insertions, 0 deletions
diff --git a/src/main.c b/src/main.c
index 277ffcdae2..9443095561 100644
--- a/src/main.c
+++ b/src/main.c
@@ -102,6 +102,7 @@ void web_server_threading_selection(void) {
void web_server_config_options(void) {
web_client_timeout = (int) config_get_number(CONFIG_SECTION_WEB, "disconnect idle clients after seconds", web_client_timeout);
web_client_first_request_timeout = (int) config_get_number(CONFIG_SECTION_WEB, "timeout for first request", web_client_first_request_timeout);
+ web_client_streaming_rate_t = config_get_number(CONFIG_SECTION_WEB, "accept a streaming request every seconds", web_client_streaming_rate_t);
respect_web_browser_do_not_track_policy = config_get_boolean(CONFIG_SECTION_WEB, "respect do not track policy", respect_web_browser_do_not_track_policy);
web_x_frame_options = config_get(CONFIG_SECTION_WEB, "x-frame-options response header", "");
diff --git a/src/rrdpush.c b/src/rrdpush.c
index 68def2247b..c28512ee05 100644
--- a/src/rrdpush.c
+++ b/src/rrdpush.c
@@ -1006,6 +1006,14 @@ int rrdpush_receiver_permission_denied(struct web_client *w) {
return 401;
}
+int rrdpush_receiver_too_busy_now(struct web_client *w) {
+ // we always respond with the same message and error code
+ // to prevent an attacker from gaining info about the error
+ buffer_flush(w->response.data);
+ buffer_sprintf(w->response.data, "The server is too busy now to accept this request. Try later.");
+ return 503;
+}
+
int rrdpush_receiver_thread_spawn(RRDHOST *host, struct web_client *w, char *url) {
(void)host;
@@ -1111,6 +1119,26 @@ int rrdpush_receiver_thread_spawn(RRDHOST *host, struct web_client *w, char *url
}
}
+ if(unlikely(web_client_streaming_rate_t > 0)) {
+ static netdata_mutex_t stream_rate_mutex = NETDATA_MUTEX_INITIALIZER;
+ static volatile time_t last_stream_accepted_t = 0;
+
+ netdata_mutex_lock(&stream_rate_mutex);
+ time_t now = now_realtime_sec();
+
+ if(unlikely(last_stream_accepted_t == 0))
+ last_stream_accepted_t = now;
+
+ if(now - last_stream_accepted_t < web_client_streaming_rate_t) {
+ netdata_mutex_unlock(&stream_rate_mutex);
+ error("STREAM [receive from [%s]:%s]: too busy to accept new streaming request. Will be allowed in %ld secs.", w->client_ip, w->client_port, (long)(web_client_streaming_rate_t - (now - last_stream_accepted_t)));
+ return rrdpush_receiver_too_busy_now(w);
+ }
+
+ last_stream_accepted_t = now;
+ netdata_mutex_unlock(&stream_rate_mutex);
+ }
+
struct rrdpush_thread *rpt = callocz(1, sizeof(struct rrdpush_thread));
rpt->fd = w->ifd;
rpt->key = strdupz(key);
diff --git a/src/web_server.c b/src/web_server.c
index 8c0aae46b5..ee8dddf7b9 100644
--- a/src/web_server.c
+++ b/src/web_server.c
@@ -409,6 +409,7 @@ static struct web_client *web_client_create_on_listenfd(int listener) {
int web_client_timeout = DEFAULT_DISCONNECT_IDLE_WEB_CLIENTS_AFTER_SECONDS;
int web_client_first_request_timeout = DEFAULT_TIMEOUT_TO_RECEIVE_FIRST_WEB_REQUEST;
+long web_client_streaming_rate_t = 0L;
static void multi_threaded_web_client_worker_main_cleanup(void *ptr) {
struct web_client *w = ptr;
diff --git a/src/web_server.h b/src/web_server.h
index 3542f30b26..3b7db2214a 100644
--- a/src/web_server.h
+++ b/src/web_server.h
@@ -43,5 +43,6 @@ extern int api_listen_sockets_setup(void);
#define DEFAULT_DISCONNECT_IDLE_WEB_CLIENTS_AFTER_SECONDS 60
extern int web_client_timeout;
extern int web_client_first_request_timeout;
+extern long web_client_streaming_rate_t;
#endif /* NETDATA_WEB_SERVER_H */