From a79fe4c30215e7f25dba1b3a8a84c4dfdc0c9475 Mon Sep 17 00:00:00 2001 From: Jon Sexson Date: Thu, 15 May 2014 13:05:57 +0300 Subject: [PATCH 3/4] Add max_response_timeouts option Add "max_response_timeouts" - a home server option specifying number of times replies are allowed to miss "response_window" before the server enters the zombie period. This allows more tolerance before transiting to zombie period for lower response window configurations. --- raddb/proxy.conf | 7 +++++++ src/include/realms.h | 2 ++ src/main/process.c | 7 ++++++- src/main/realms.c | 5 +++++ 4 files changed, 20 insertions(+), 1 deletion(-) diff --git a/raddb/proxy.conf b/raddb/proxy.conf index c92d2ab..1dc541b 100644 --- a/raddb/proxy.conf +++ b/raddb/proxy.conf @@ -228,6 +228,7 @@ home_server localhost { # # If the home server does not respond to a request within # this time, this server will initiate "zombie_period". + # See also "max_response_timeouts". # # The time is specified with response_window and # response_window_usec for second and microsecond parts @@ -241,6 +242,12 @@ home_server localhost { response_window_usec = 0 # + # Ignore this many replies missing "response_window" + # before starting zombie period. + # + max_response_timeouts = 0 + + # # If you want the old behaviour of the server rejecting # proxied requests after "response_window" timeout, set # the following configuration item to "yes". diff --git a/src/include/realms.h b/src/include/realms.h index f6ddd08..b149b9f 100644 --- a/src/include/realms.h +++ b/src/include/realms.h @@ -63,6 +63,8 @@ typedef struct home_server { struct timeval when; struct timeval response_window; + int response_timeouts; + int max_response_timeouts; int max_outstanding; /* don't overload it */ int currently_outstanding; diff --git a/src/main/process.c b/src/main/process.c index 91818a9..f07d377 100644 --- a/src/main/process.c +++ b/src/main/process.c @@ -2282,6 +2282,7 @@ int request_proxy_reply(RADIUS_PACKET *packet) */ if (request->home_server->state == HOME_STATE_UNKNOWN) { request->home_server->state = HOME_STATE_ALIVE; + request->home_server->response_timeouts = 0; } #ifdef WITH_STATS @@ -2872,6 +2873,7 @@ STATE_MACHINE_DECL(request_ping) * pings. */ home->state = HOME_STATE_ALIVE; + home->response_timeouts = 0; exec_trigger(request, home->cs, "home_server.alive", false); home->currently_outstanding = 0; home->num_sent_pings = 0; @@ -3118,6 +3120,7 @@ void revive_home_server(void *ctx) #endif home->state = HOME_STATE_ALIVE; + home->response_timeouts = 0; home_trigger(home, "home_server.alive"); home->currently_outstanding = 0; gettimeofday(&home->revive_time, NULL); @@ -3336,7 +3339,9 @@ STATE_MACHINE_DECL(proxy_wait_for_reply) && (home->proto != IPPROTO_TCP) #endif ) { - mark_home_server_zombie(home, &now, &response_window); + home->response_timeouts++; + if (home->response_timeouts > home->max_response_timeouts) + mark_home_server_zombie(home, &now, &response_window); } FR_STATS_TYPE_INC(home->stats.total_timeouts); diff --git a/src/main/realms.c b/src/main/realms.c index 48d73d0..eef988e 100644 --- a/src/main/realms.c +++ b/src/main/realms.c @@ -345,6 +345,8 @@ static CONF_PARSER home_server_config[] = { 0, &response_window, "30" }, { "response_window_usec", PW_TYPE_INTEGER, 0, &response_window_usec, "0" }, + { "max_response_timeouts", PW_TYPE_INTEGER, + offsetof(home_server_t,max_response_timeouts), NULL, "0" }, { "max_outstanding", PW_TYPE_INTEGER, offsetof(home_server_t,max_outstanding), NULL, "65536" }, @@ -747,6 +749,8 @@ static int home_server_add(realm_config_t *rc, CONF_SECTION *cs) home->response_window.tv_sec = response_window; home->response_window.tv_usec = response_window_usec; + FR_INTEGER_BOUND_CHECK("max_response_timeouts", home->max_response_timeouts, >=, 0); + FR_INTEGER_BOUND_CHECK("zombie_period", home->zombie_period, >=, 1); FR_INTEGER_BOUND_CHECK("zombie_period", home->zombie_period, <=, 120); FR_INTEGER_BOUND_CHECK("zombie_period", home->zombie_period, >=, timerceil(&home->response_window)); @@ -2385,6 +2389,7 @@ home_server_t *home_server_ldb(char const *realmname, if ((home->state == HOME_STATE_IS_DEAD) && (home->ping_check == HOME_PING_CHECK_NONE)) { home->state = HOME_STATE_ALIVE; + home->response_timeouts = 0; if (!found) found = home; } } -- 1.9.2