dovecot-2.1: master: Throttle rapid exit failures only if there ...

dovecot at dovecot.org dovecot at dovecot.org
Fri Jan 27 23:33:16 EET 2012


details:   http://hg.dovecot.org/dovecot-2.1/rev/85a9b5236b6c
changeset: 14016:85a9b5236b6c
user:      Timo Sirainen <tss at iki.fi>
date:      Fri Jan 27 23:33:00 2012 +0200
description:
master: Throttle rapid exit failures only if there have never been any exit successes.
This should still catch buggy services without allowing intentional DoSing.

diffstat:

 src/master/service-monitor.c |  18 +++++++++++++-----
 src/master/service.h         |   2 ++
 2 files changed, 15 insertions(+), 5 deletions(-)

diffs (48 lines):

diff -r c553725d57bb -r 85a9b5236b6c src/master/service-monitor.c
--- a/src/master/service-monitor.c	Fri Jan 27 23:26:42 2012 +0200
+++ b/src/master/service-monitor.c	Fri Jan 27 23:33:00 2012 +0200
@@ -535,12 +535,19 @@
 
 	service_process_log_status_error(process, status);
 	throttle = process->to_status != NULL;
-	if (service->exit_failure_last != ioloop_time) {
-		service->exit_failure_last = ioloop_time;
-		service->exit_failures_in_sec = 0;
+	if (!throttle && !service->have_successful_exits) {
+		/* this service has seen no successful exits yet.
+		   try to avoid failure storms by throttling the service if it
+		   only keeps failing rapidly. this is no longer done after
+		   one success to avoid intentional DoSing, in case attacker
+		   finds a way to quickly crash his own session. */
+		if (service->exit_failure_last != ioloop_time) {
+			service->exit_failure_last = ioloop_time;
+			service->exit_failures_in_sec = 0;
+		}
+		if (++service->exit_failures_in_sec > SERVICE_MAX_EXIT_FAILURES_IN_SEC)
+			throttle = TRUE;
 	}
-	if (++service->exit_failures_in_sec > SERVICE_MAX_EXIT_FAILURES_IN_SEC)
-		throttle = TRUE;
 	service_process_notify_add(service_anvil_global->kills, process);
 	return throttle;
 }
@@ -568,6 +575,7 @@
 			    !service->list->destroying)
 				service_monitor_listen_start(service);
 			/* one success resets all failures */
+			service->have_successful_exits = TRUE;
 			service->exit_failures_in_sec = 0;
 			service->throttle_secs =
 				SERVICE_STARTUP_FAILURE_THROTTLE_MIN_SECS;
diff -r c553725d57bb -r 85a9b5236b6c src/master/service.h
--- a/src/master/service.h	Fri Jan 27 23:26:42 2012 +0200
+++ b/src/master/service.h	Fri Jan 27 23:33:00 2012 +0200
@@ -111,6 +111,8 @@
 	unsigned int have_inet_listeners:1;
 	/* service_login_notify()'s last notification state */
 	unsigned int last_login_full_notify:1;
+	/* service has exited at least once with exit code 0 */
+	unsigned int have_successful_exits:1;
 };
 
 struct service_list {


More information about the dovecot-cvs mailing list