Add max_response_timeouts option
authorNikolai Kondrashov <Nikolai.Kondrashov@redhat.com>
Wed, 4 Jun 2014 17:06:48 +0000 (20:06 +0300)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Fri, 13 Jun 2014 06:10:55 +0000 (07:10 +0100)
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
src/include/realms.h
src/main/process.c
src/main/realms.c

index 0180e74..beea063 100644 (file)
@@ -230,6 +230,7 @@ home_server localhost {
        #  this time, this server will initiate "zombie_period".
        #  The response window can be a number between 0.001 and 60.000
        #  Though values on the low end are discouraged.
+       #  See also "max_response_timeouts".
        #
        #  The response window is large because responses MAY be slow,
        #  especially when proxying across the Internet.
@@ -238,6 +239,12 @@ home_server localhost {
        response_window = 20
 
        #
+       # 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".
index ea62772..754b398 100644 (file)
@@ -69,6 +69,8 @@ typedef struct home_server {
        struct timeval  when;
 
        struct timeval  response_window;
+       uint32_t        response_timeouts;
+       uint32_t        max_response_timeouts;
        uint32_t        max_outstanding; /* don't overload it */
        uint32_t        currently_outstanding;
 
index 5757aaa..ca2b128 100644 (file)
@@ -2335,6 +2335,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
@@ -2951,6 +2952,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;
@@ -3197,6 +3199,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);
@@ -3421,7 +3424,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);
index 4e5383c..f99889a 100644 (file)
@@ -311,6 +311,7 @@ static CONF_PARSER home_server_config[] = {
        { "src_ipaddr", FR_CONF_POINTER(PW_TYPE_STRING, &hs_srcipaddr), NULL },
 
        { "response_window", FR_CONF_OFFSET(PW_TYPE_TIMEVAL, home_server_t, response_window), "30" },
+       { "max_response_timeouts", FR_CONF_OFFSET(PW_TYPE_INTEGER, home_server_t, max_response_timeouts), "0" },
        { "max_outstanding", FR_CONF_OFFSET(PW_TYPE_INTEGER, home_server_t, max_outstanding), "65536" },
 
        { "zombie_period", FR_CONF_OFFSET(PW_TYPE_INTEGER, home_server_t, zombie_period), "40" },
@@ -2306,6 +2307,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;
                        }
                }